@luxonis/visualizer-protobuf 3.1.11 → 3.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{FoxgloveServer-B98MHUu6.js → FoxgloveServer-Da9kV1cr.js} +1 -1
- package/dist/{communicator-Bzkx3Qfr.js → communicator-Dh2aL-rj.js} +1 -1
- package/dist/{depth-DlC6A3Te.js → depth-DiD1V2Sg.js} +15 -28
- package/dist/{deserialization.worker-CO4m6y8V.js → deserialization.worker-DU2Hs4UP.js} +577 -341
- package/dist/{foxglove-protocol-yHdoBNaD.js → foxglove-protocol-BtLMVx24.js} +1 -1
- package/dist/{index-CB1fYMKI.js → index--95nXh6E.js} +5 -5
- package/dist/{index-Dqm1x8G2.js → index-B5oN0fQm.js} +1 -1
- package/dist/{index-BXzWxQD4.js → index-B9-rLgJ9.js} +7 -7
- package/dist/{index-DCsDqt-U.js → index-BMp_L7Aa.js} +5 -5
- package/dist/{index-Be6EYnox.js → index-B_3PleIH.js} +49 -35
- package/dist/{index-BYTk-1GW.js → index-BjiepKHF.js} +5 -5
- package/dist/{index-DgUF0rJi.js → index-C45UVGjk.js} +5 -5
- package/dist/{index-D_pNGJGQ.js → index-CCq5_y78.js} +5 -5
- package/dist/{index-D2sxEb00.js → index-CNjpp5xs.js} +5 -5
- package/dist/{index-B-g3aWAt.js → index-CcWunxJv.js} +5 -5
- package/dist/{index-BEUjTghZ.js → index-CidrwlEk.js} +5 -5
- package/dist/{index-CKE7xLWy.js → index-CqayH0_I.js} +5 -5
- package/dist/{index-CDp9Pzg1.js → index-CxKEiKY9.js} +5 -5
- package/dist/{index-BlROWu-J.js → index-D686pHc1.js} +6 -6
- package/dist/{index-DCsBkCC7.js → index-DWt4Nj5G.js} +5 -5
- package/dist/{index-DtnnnQqJ.js → index-DewnJOHY.js} +5 -5
- package/dist/{index-D0BOBLGo.js → index-DnhrXuH6.js} +5 -5
- package/dist/{index-OIOsl1pr.js → index-DopAEQk2.js} +5 -5
- package/dist/{index-D063HnO-.js → index-DzOBiI2h.js} +5 -5
- package/dist/{index-Dvd5sByT.js → index-JlGCfxtk.js} +5 -5
- package/dist/{index-DXmbPIsN.js → index-X1k93Nku.js} +5 -5
- package/dist/index.js +5 -5
- package/dist/lib/src/connection/foxglove-connection.d.ts.map +1 -1
- package/dist/lib/src/connection/foxglove-connection.js +7 -1
- package/dist/lib/src/connection/foxglove-connection.js.map +1 -1
- package/dist/lib/src/messaging/deserialization/pointcloud/pointcloudFromDepth.worker.js +2 -2
- package/dist/lib/src/messaging/deserialization/pointcloud/pointcloudFromDepth.worker.js.map +1 -1
- package/dist/lib/src/messaging/deserialization/pointcloud/poitcloudPoolManager.js.map +1 -1
- package/dist/lib/src/messaging/deserialization/pointcloud/utils.d.ts.map +1 -1
- package/dist/lib/src/messaging/deserialization/pointcloud/utils.js.map +1 -1
- package/dist/lib/src/messaging/deserialization/video/depth.d.ts.map +1 -1
- package/dist/lib/src/messaging/deserialization/video/depth.js +11 -1
- package/dist/lib/src/messaging/deserialization/video/depth.js.map +1 -1
- package/dist/lib/src/messaging/deserialization/video/h264.d.ts +11 -6
- package/dist/lib/src/messaging/deserialization/video/h264.d.ts.map +1 -1
- package/dist/lib/src/messaging/deserialization/video/h264.js +115 -166
- package/dist/lib/src/messaging/deserialization/video/h264.js.map +1 -1
- package/dist/lib/src/messaging/deserialization/video/h265.d.ts +2 -7
- package/dist/lib/src/messaging/deserialization/video/h265.d.ts.map +1 -1
- package/dist/lib/src/messaging/deserialization/video/h265.js +55 -126
- package/dist/lib/src/messaging/deserialization/video/h265.js.map +1 -1
- package/dist/lib/src/messaging/deserialization/video/mjpeg.d.ts.map +1 -1
- package/dist/lib/src/messaging/deserialization/video/mjpeg.js +7 -8
- package/dist/lib/src/messaging/deserialization/video/mjpeg.js.map +1 -1
- package/dist/lib/src/messaging/deserialization/video/rgbd-to-pointcloud.d.ts +17 -0
- package/dist/lib/src/messaging/deserialization/video/rgbd-to-pointcloud.d.ts.map +1 -0
- package/dist/lib/src/messaging/deserialization/video/rgbd-to-pointcloud.js +325 -0
- package/dist/lib/src/messaging/deserialization/video/rgbd-to-pointcloud.js.map +1 -0
- package/dist/lib/src/messaging/deserialization.worker.d.ts +4 -0
- package/dist/lib/src/messaging/deserialization.worker.d.ts.map +1 -1
- package/dist/lib/src/messaging/deserialization.worker.js +16 -3
- package/dist/lib/src/messaging/deserialization.worker.js.map +1 -1
- package/dist/lib/src/messaging/protobuf.d.ts +12 -1
- package/dist/lib/src/messaging/protobuf.d.ts.map +1 -1
- package/dist/lib/src/messaging/protobuf.js +8 -0
- package/dist/lib/src/messaging/protobuf.js.map +1 -1
- package/dist/lib/src/messaging/utils.d.ts.map +1 -1
- package/dist/lib/src/messaging/utils.js +2 -0
- package/dist/lib/src/messaging/utils.js.map +1 -1
- package/dist/lib/src/output.css +2 -21
- package/dist/lib/src/panels/PointCloudPanel.d.ts.map +1 -1
- package/dist/lib/src/panels/PointCloudPanel.js +5 -1
- package/dist/lib/src/panels/PointCloudPanel.js.map +1 -1
- package/dist/lib/src/utils/metrics-manager.d.ts +1 -0
- package/dist/lib/src/utils/metrics-manager.d.ts.map +1 -1
- package/dist/lib/src/utils/metrics-manager.js +4 -2
- package/dist/lib/src/utils/metrics-manager.js.map +1 -1
- package/dist/lib/src/utils/poitcloud-sync.d.ts +4 -3
- package/dist/lib/src/utils/poitcloud-sync.d.ts.map +1 -1
- package/dist/lib/src/utils/poitcloud-sync.js +3 -1
- package/dist/lib/src/utils/poitcloud-sync.js.map +1 -1
- package/dist/{pointcloudFromDepth.worker-JLptpLHr.js → pointcloudFromDepth.worker-60RA4Ief.js} +2 -2
- package/dist/{protobuf-Be0G3NFz.js → protobuf-OcbVtxg1.js} +406 -218
- package/dist/{worker-NFznpx6V.js → worker-Be-hru8f.js} +3 -3
- package/dist/{worker-0Q6os6Ck.js → worker-C2MHIq3t.js} +4 -4
- package/package.json +2 -2
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { b as _objectSpread2, P as PointsAnnotationType,
|
|
3
|
-
import { e as expose } from './comlink-jf8bdrAf.js';
|
|
4
|
-
import { t as typescript } from './index-
|
|
5
|
-
import { U as parseMessage, e as estimateObjectSize, V as fromMillis, W as DecoderRuntimeError, d as dist, X as
|
|
2
|
+
import { b as _objectSpread2, P as PointsAnnotationType, T as Type, h as Profile, p as protobufsBySchema } from './protobuf-OcbVtxg1.js';
|
|
3
|
+
import { w as wrap, e as expose } from './comlink-jf8bdrAf.js';
|
|
4
|
+
import { t as typescript } from './index-B5oN0fQm.js';
|
|
5
|
+
import { U as parseMessage, e as estimateObjectSize, V as fromMillis, W as DecoderRuntimeError, d as dist, X as deserializeDepthFrame, Y as UnsupportedTopicError, Z as NotInSecureContextError, _ as EncodedStreamNotSupportedError } from './depth-DiD1V2Sg.js';
|
|
6
6
|
import { L as Logger } from './logger-Bqy1nuLj.js';
|
|
7
7
|
import { i as isCapableOfEncodedStream } from './encoding-jXImCIb4.js';
|
|
8
|
+
import { u as uint8ArrayToUint16Array } from './utils-DmlHZWuo.js';
|
|
8
9
|
import 'react';
|
|
9
10
|
import 'zustand';
|
|
10
11
|
import 'react-mosaic-component';
|
|
@@ -797,17 +798,12 @@ function ensureWebCodecsSupported(target) {
|
|
|
797
798
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/
|
|
798
799
|
|
|
799
800
|
const logger$2 = Logger.getLogger();
|
|
800
|
-
function configureDecoder
|
|
801
|
+
function configureDecoder(decoder) {
|
|
801
802
|
decoder.configure({
|
|
802
803
|
codec: "avc1.42001E",
|
|
803
804
|
optimizeForLatency: true
|
|
804
805
|
});
|
|
805
806
|
}
|
|
806
|
-
function ensureDecoderConfigured$1(decoder) {
|
|
807
|
-
if (decoder.state === "unconfigured") {
|
|
808
|
-
configureDecoder$1(decoder);
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
807
|
function closeDecoder$1(decoder) {
|
|
812
808
|
if (!decoder) {
|
|
813
809
|
return;
|
|
@@ -823,110 +819,14 @@ function closeDecoder$1(decoder) {
|
|
|
823
819
|
}
|
|
824
820
|
function closeTopicDecoder$1(topic, topicDecoders) {
|
|
825
821
|
const decoderInfo = topicDecoders.get(topic);
|
|
826
|
-
topicDecoders.delete(topic);
|
|
827
822
|
closeDecoder$1(decoderInfo === null || decoderInfo === void 0 ? void 0 : decoderInfo.decoder);
|
|
828
823
|
decoderInfo === null || decoderInfo === void 0 || decoderInfo.timing.clear();
|
|
829
824
|
decoderInfo === null || decoderInfo === void 0 || decoderInfo.transformations.clear();
|
|
830
|
-
if (decoderInfo) {
|
|
831
|
-
decoderInfo.pendingFrame = undefined;
|
|
832
|
-
}
|
|
833
825
|
}
|
|
834
826
|
function isIgnorableInitialDecodeError(error) {
|
|
835
827
|
const message = error instanceof Error ? error.message : String(error);
|
|
836
828
|
return message.includes("A key frame is required after configure() or flush()");
|
|
837
829
|
}
|
|
838
|
-
function isUnconfiguredCodecError$1(error) {
|
|
839
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
840
|
-
return /cannot call ["']decode["'] on an unconfigured (?:codec|decoder)/i.test(message);
|
|
841
|
-
}
|
|
842
|
-
function resetTopicDecoder$1({
|
|
843
|
-
topic,
|
|
844
|
-
topicDecoders,
|
|
845
|
-
callback,
|
|
846
|
-
onError
|
|
847
|
-
}) {
|
|
848
|
-
const existingDecoderInfo = topicDecoders.get(topic);
|
|
849
|
-
closeDecoder$1(existingDecoderInfo === null || existingDecoderInfo === void 0 ? void 0 : existingDecoderInfo.decoder);
|
|
850
|
-
const decoder = createVideoDecoder$1({
|
|
851
|
-
topic,
|
|
852
|
-
callback,
|
|
853
|
-
topicDecoders,
|
|
854
|
-
onError
|
|
855
|
-
});
|
|
856
|
-
try {
|
|
857
|
-
configureDecoder$1(decoder);
|
|
858
|
-
} catch (error) {
|
|
859
|
-
closeDecoder$1(decoder);
|
|
860
|
-
closeTopicDecoder$1(topic, topicDecoders);
|
|
861
|
-
onError(new DecoderRuntimeError(topic, error instanceof Error ? error.message : "Failed to configure H.264 decoder."));
|
|
862
|
-
return undefined;
|
|
863
|
-
}
|
|
864
|
-
if (existingDecoderInfo) {
|
|
865
|
-
existingDecoderInfo.decoder = decoder;
|
|
866
|
-
existingDecoderInfo.timing.clear();
|
|
867
|
-
existingDecoderInfo.transformations.clear();
|
|
868
|
-
existingDecoderInfo.pendingFrame = undefined;
|
|
869
|
-
} else {
|
|
870
|
-
topicDecoders.set(topic, {
|
|
871
|
-
decoder,
|
|
872
|
-
timing: new Map(),
|
|
873
|
-
transformations: new Map(),
|
|
874
|
-
pendingFrame: undefined
|
|
875
|
-
});
|
|
876
|
-
}
|
|
877
|
-
return decoder;
|
|
878
|
-
}
|
|
879
|
-
function decodePendingFrame$1(topic, topicDecoders, callback, onError) {
|
|
880
|
-
const decoderInfo = topicDecoders.get(topic);
|
|
881
|
-
if (!decoderInfo) {
|
|
882
|
-
return;
|
|
883
|
-
}
|
|
884
|
-
const decoder = decoderInfo.decoder;
|
|
885
|
-
if (decoder.state === "closed" || decoder.decodeQueueSize > 0) {
|
|
886
|
-
return;
|
|
887
|
-
}
|
|
888
|
-
const pendingFrame = decoderInfo.pendingFrame;
|
|
889
|
-
if (!pendingFrame) {
|
|
890
|
-
return;
|
|
891
|
-
}
|
|
892
|
-
decoderInfo.pendingFrame = undefined;
|
|
893
|
-
decoderInfo.timing.set(pendingFrame.timestamp, pendingFrame.receiveTime);
|
|
894
|
-
decoderInfo.transformations.set(pendingFrame.timestamp, pendingFrame.transformation);
|
|
895
|
-
try {
|
|
896
|
-
var _topicDecoders$get;
|
|
897
|
-
ensureDecoderConfigured$1(decoder);
|
|
898
|
-
if (decoder.state !== "configured" || ((_topicDecoders$get = topicDecoders.get(topic)) === null || _topicDecoders$get === void 0 ? void 0 : _topicDecoders$get.decoder) !== decoder) {
|
|
899
|
-
closeTopicDecoder$1(topic, topicDecoders);
|
|
900
|
-
return;
|
|
901
|
-
}
|
|
902
|
-
const chunk = new EncodedVideoChunk({
|
|
903
|
-
type: "key",
|
|
904
|
-
data: pendingFrame.data,
|
|
905
|
-
timestamp: pendingFrame.timestamp
|
|
906
|
-
});
|
|
907
|
-
decoder.decode(chunk);
|
|
908
|
-
} catch (error) {
|
|
909
|
-
if (isUnconfiguredCodecError$1(error)) {
|
|
910
|
-
decoderInfo.pendingFrame = pendingFrame;
|
|
911
|
-
const replacementDecoder = resetTopicDecoder$1({
|
|
912
|
-
topic,
|
|
913
|
-
topicDecoders,
|
|
914
|
-
callback,
|
|
915
|
-
onError
|
|
916
|
-
});
|
|
917
|
-
if ((replacementDecoder === null || replacementDecoder === void 0 ? void 0 : replacementDecoder.state) === "configured") {
|
|
918
|
-
decodePendingFrame$1(topic, topicDecoders, callback, onError);
|
|
919
|
-
}
|
|
920
|
-
return;
|
|
921
|
-
}
|
|
922
|
-
if (isIgnorableInitialDecodeError(error)) {
|
|
923
|
-
closeTopicDecoder$1(topic, topicDecoders);
|
|
924
|
-
return;
|
|
925
|
-
}
|
|
926
|
-
closeTopicDecoder$1(topic, topicDecoders);
|
|
927
|
-
onError(new DecoderRuntimeError(topic, error instanceof Error ? error.message : "Failed to decode H.264 frame."));
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
830
|
function packedToI420(packed, width, height, stride, format, cropLeft = 0, cropTop = 0) {
|
|
931
831
|
if ((width & 1) !== 0 || (height & 1) !== 0) {
|
|
932
832
|
throw new Error("I420 requires even width and height.");
|
|
@@ -1032,67 +932,72 @@ function repackI420(source, width, height, yLayout, uLayout, vLayout, cropLeft =
|
|
|
1032
932
|
}
|
|
1033
933
|
return out;
|
|
1034
934
|
}
|
|
935
|
+
async function copyVideoFrameToI420(frame, logPrefix) {
|
|
936
|
+
var _visibleRect$width, _visibleRect$height, _visibleRect$x, _visibleRect$y;
|
|
937
|
+
const visibleRect = frame.visibleRect;
|
|
938
|
+
const frameWidth = (_visibleRect$width = visibleRect === null || visibleRect === void 0 ? void 0 : visibleRect.width) !== null && _visibleRect$width !== void 0 ? _visibleRect$width : frame.codedWidth;
|
|
939
|
+
const frameHeight = (_visibleRect$height = visibleRect === null || visibleRect === void 0 ? void 0 : visibleRect.height) !== null && _visibleRect$height !== void 0 ? _visibleRect$height : frame.codedHeight;
|
|
940
|
+
const cropLeft = (_visibleRect$x = visibleRect === null || visibleRect === void 0 ? void 0 : visibleRect.x) !== null && _visibleRect$x !== void 0 ? _visibleRect$x : 0;
|
|
941
|
+
const cropTop = (_visibleRect$y = visibleRect === null || visibleRect === void 0 ? void 0 : visibleRect.y) !== null && _visibleRect$y !== void 0 ? _visibleRect$y : 0;
|
|
942
|
+
let finalBuffer = new Uint8Array(frame.allocationSize());
|
|
943
|
+
logger$2.warn(`${logPrefix} decoder output format: ${frame.format}, coded=${frame.codedWidth}x${frame.codedHeight}, display=${frame.displayWidth}x${frame.displayHeight}, visible=${frameWidth}x${frameHeight}@${cropLeft},${cropTop}`);
|
|
944
|
+
switch (frame.format) {
|
|
945
|
+
case "I420":
|
|
946
|
+
{
|
|
947
|
+
const i420Buffer = new Uint8Array(frame.allocationSize());
|
|
948
|
+
const layouts = await frame.copyTo(i420Buffer);
|
|
949
|
+
const [yLayout, uLayout, vLayout] = layouts;
|
|
950
|
+
finalBuffer = yLayout != undefined && uLayout != undefined && vLayout != undefined ? repackI420(i420Buffer, frameWidth, frameHeight, yLayout, uLayout, vLayout, cropLeft, cropTop) : i420Buffer;
|
|
951
|
+
break;
|
|
952
|
+
}
|
|
953
|
+
case "NV12":
|
|
954
|
+
{
|
|
955
|
+
var _yLayout$stride, _uvLayout$stride, _yLayout$offset, _uvLayout$offset, _yLayout$stride2;
|
|
956
|
+
const nv12Buffer = new Uint8Array(frame.allocationSize());
|
|
957
|
+
const layouts = await frame.copyTo(nv12Buffer);
|
|
958
|
+
const [yLayout, uvLayout] = layouts;
|
|
959
|
+
finalBuffer = convertNv12ToI420(nv12Buffer, frameWidth, frameHeight, (_yLayout$stride = yLayout === null || yLayout === void 0 ? void 0 : yLayout.stride) !== null && _yLayout$stride !== void 0 ? _yLayout$stride : frame.codedWidth, (_uvLayout$stride = uvLayout === null || uvLayout === void 0 ? void 0 : uvLayout.stride) !== null && _uvLayout$stride !== void 0 ? _uvLayout$stride : frame.codedWidth, (_yLayout$offset = yLayout === null || yLayout === void 0 ? void 0 : yLayout.offset) !== null && _yLayout$offset !== void 0 ? _yLayout$offset : 0, (_uvLayout$offset = uvLayout === null || uvLayout === void 0 ? void 0 : uvLayout.offset) !== null && _uvLayout$offset !== void 0 ? _uvLayout$offset : ((_yLayout$stride2 = yLayout === null || yLayout === void 0 ? void 0 : yLayout.stride) !== null && _yLayout$stride2 !== void 0 ? _yLayout$stride2 : frame.codedWidth) * frame.codedHeight, cropLeft, cropTop);
|
|
960
|
+
break;
|
|
961
|
+
}
|
|
962
|
+
case "RGBX":
|
|
963
|
+
case "RGBA":
|
|
964
|
+
case "BGRX":
|
|
965
|
+
case "BGRA":
|
|
966
|
+
{
|
|
967
|
+
var _layout$stride;
|
|
968
|
+
const packedBuffer = new Uint8Array(frame.allocationSize());
|
|
969
|
+
const [layout] = await frame.copyTo(packedBuffer);
|
|
970
|
+
logger$2.warn(`${logPrefix} decoder received ${frame.format} frame.`);
|
|
971
|
+
finalBuffer = packedToI420(packedBuffer, frameWidth, frameHeight, (_layout$stride = layout === null || layout === void 0 ? void 0 : layout.stride) !== null && _layout$stride !== void 0 ? _layout$stride : frame.codedWidth * 4, frame.format, cropLeft, cropTop);
|
|
972
|
+
break;
|
|
973
|
+
}
|
|
974
|
+
default:
|
|
975
|
+
logger$2.warn(`${logPrefix} decoder received unexpected frame format:`, frame.format);
|
|
976
|
+
break;
|
|
977
|
+
}
|
|
978
|
+
return {
|
|
979
|
+
data: finalBuffer,
|
|
980
|
+
width: frameWidth,
|
|
981
|
+
height: frameHeight
|
|
982
|
+
};
|
|
983
|
+
}
|
|
1035
984
|
function createVideoDecoder$1({
|
|
1036
985
|
topic,
|
|
1037
|
-
|
|
1038
|
-
topicDecoders,
|
|
1039
|
-
onError
|
|
986
|
+
topicDecoders
|
|
1040
987
|
}) {
|
|
1041
988
|
let hasProducedFrame = false;
|
|
1042
|
-
|
|
1043
|
-
decoder = new VideoDecoder({
|
|
989
|
+
return new VideoDecoder({
|
|
1044
990
|
output: async frame => {
|
|
1045
|
-
var _topicDecoders$
|
|
1046
|
-
if (((_topicDecoders$get2 = topicDecoders.get(topic)) === null || _topicDecoders$get2 === void 0 ? void 0 : _topicDecoders$get2.decoder) !== decoder) {
|
|
1047
|
-
frame.close();
|
|
1048
|
-
return;
|
|
1049
|
-
}
|
|
991
|
+
var _topicDecoders$get$ti, _topicDecoders$get, _topicDecoders$get2, _topicDecoders$get3, _topicDecoders$get4;
|
|
1050
992
|
hasProducedFrame = true;
|
|
1051
|
-
const
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
case "I420":
|
|
1060
|
-
{
|
|
1061
|
-
const i420Buffer = new Uint8Array(frame.allocationSize());
|
|
1062
|
-
const layouts = await frame.copyTo(i420Buffer);
|
|
1063
|
-
const [yLayout, uLayout, vLayout] = layouts;
|
|
1064
|
-
finalBuffer = yLayout != undefined && uLayout != undefined && vLayout != undefined ? repackI420(i420Buffer, frameWidth, frameHeight, yLayout, uLayout, vLayout, cropLeft, cropTop) : i420Buffer;
|
|
1065
|
-
break;
|
|
1066
|
-
}
|
|
1067
|
-
case "NV12":
|
|
1068
|
-
{
|
|
1069
|
-
var _yLayout$stride, _uvLayout$stride, _yLayout$offset, _uvLayout$offset, _yLayout$stride2;
|
|
1070
|
-
const nv12Buffer = new Uint8Array(frame.allocationSize());
|
|
1071
|
-
const layouts = await frame.copyTo(nv12Buffer);
|
|
1072
|
-
const [yLayout, uvLayout] = layouts;
|
|
1073
|
-
finalBuffer = convertNv12ToI420(nv12Buffer, frameWidth, frameHeight, (_yLayout$stride = yLayout === null || yLayout === void 0 ? void 0 : yLayout.stride) !== null && _yLayout$stride !== void 0 ? _yLayout$stride : frame.codedWidth, (_uvLayout$stride = uvLayout === null || uvLayout === void 0 ? void 0 : uvLayout.stride) !== null && _uvLayout$stride !== void 0 ? _uvLayout$stride : frame.codedWidth, (_yLayout$offset = yLayout === null || yLayout === void 0 ? void 0 : yLayout.offset) !== null && _yLayout$offset !== void 0 ? _yLayout$offset : 0, (_uvLayout$offset = uvLayout === null || uvLayout === void 0 ? void 0 : uvLayout.offset) !== null && _uvLayout$offset !== void 0 ? _uvLayout$offset : ((_yLayout$stride2 = yLayout === null || yLayout === void 0 ? void 0 : yLayout.stride) !== null && _yLayout$stride2 !== void 0 ? _yLayout$stride2 : frame.codedWidth) * frame.codedHeight, cropLeft, cropTop);
|
|
1074
|
-
break;
|
|
1075
|
-
}
|
|
1076
|
-
case "RGBX":
|
|
1077
|
-
case "RGBA":
|
|
1078
|
-
case "BGRX":
|
|
1079
|
-
case "BGRA":
|
|
1080
|
-
{
|
|
1081
|
-
var _layout$stride;
|
|
1082
|
-
const packedBuffer = new Uint8Array(frame.allocationSize());
|
|
1083
|
-
const [layout] = await frame.copyTo(packedBuffer);
|
|
1084
|
-
logger$2.warn(`H264 decoder received ${frame.format} frame.`);
|
|
1085
|
-
finalBuffer = packedToI420(packedBuffer, frameWidth, frameHeight, (_layout$stride = layout === null || layout === void 0 ? void 0 : layout.stride) !== null && _layout$stride !== void 0 ? _layout$stride : frame.codedWidth * 4, frame.format, cropLeft, cropTop);
|
|
1086
|
-
break;
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
if (frame.format !== "I420" && frame.format !== "NV12" && frame.format !== "RGBX" && frame.format !== "RGBA" && frame.format !== "BGRX" && frame.format !== "BGRA") {
|
|
1090
|
-
logger$2.warn("H264 decoder received unexpected frame format:", frame.format);
|
|
1091
|
-
}
|
|
1092
|
-
const receiveTime = (_topicDecoders$get$ti = (_topicDecoders$get3 = topicDecoders.get(topic)) === null || _topicDecoders$get3 === void 0 ? void 0 : _topicDecoders$get3.timing.get(frame.timestamp)) !== null && _topicDecoders$get$ti !== void 0 ? _topicDecoders$get$ti : dist.fromMicros(frame.timestamp);
|
|
1093
|
-
(_topicDecoders$get4 = topicDecoders.get(topic)) === null || _topicDecoders$get4 === void 0 || _topicDecoders$get4.timing.delete(frame.timestamp);
|
|
1094
|
-
const transformation = (_topicDecoders$get5 = topicDecoders.get(topic)) === null || _topicDecoders$get5 === void 0 ? void 0 : _topicDecoders$get5.transformations.get(frame.timestamp);
|
|
1095
|
-
(_topicDecoders$get6 = topicDecoders.get(topic)) === null || _topicDecoders$get6 === void 0 || _topicDecoders$get6.transformations.delete(frame.timestamp);
|
|
993
|
+
const {
|
|
994
|
+
data: finalBuffer,
|
|
995
|
+
width: frameWidth,
|
|
996
|
+
height: frameHeight
|
|
997
|
+
} = await copyVideoFrameToI420(frame, "H264");
|
|
998
|
+
const receiveTime = (_topicDecoders$get$ti = (_topicDecoders$get = topicDecoders.get(topic)) === null || _topicDecoders$get === void 0 ? void 0 : _topicDecoders$get.timing.get(frame.timestamp)) !== null && _topicDecoders$get$ti !== void 0 ? _topicDecoders$get$ti : dist.fromMicros(frame.timestamp);
|
|
999
|
+
const transformation = (_topicDecoders$get2 = topicDecoders.get(topic)) === null || _topicDecoders$get2 === void 0 ? void 0 : _topicDecoders$get2.transformations.get(frame.timestamp);
|
|
1000
|
+
(_topicDecoders$get3 = topicDecoders.get(topic)) === null || _topicDecoders$get3 === void 0 || _topicDecoders$get3.transformations.delete(frame.timestamp);
|
|
1096
1001
|
const foxgloveMessage = {
|
|
1097
1002
|
timestamp: receiveTime,
|
|
1098
1003
|
frame_id: `h264-${topic}-frame`,
|
|
@@ -1102,7 +1007,7 @@ function createVideoDecoder$1({
|
|
|
1102
1007
|
encoding: "yuv420p",
|
|
1103
1008
|
step: frameWidth
|
|
1104
1009
|
};
|
|
1105
|
-
callback({
|
|
1010
|
+
(_topicDecoders$get4 = topicDecoders.get(topic)) === null || _topicDecoders$get4 === void 0 || _topicDecoders$get4.callback({
|
|
1106
1011
|
topic,
|
|
1107
1012
|
receiveTime,
|
|
1108
1013
|
message: foxgloveMessage,
|
|
@@ -1111,15 +1016,9 @@ function createVideoDecoder$1({
|
|
|
1111
1016
|
depthaiTransformation: transformation
|
|
1112
1017
|
});
|
|
1113
1018
|
frame.close();
|
|
1114
|
-
if (((_topicDecoders$get7 = topicDecoders.get(topic)) === null || _topicDecoders$get7 === void 0 ? void 0 : _topicDecoders$get7.decoder) === decoder) {
|
|
1115
|
-
decodePendingFrame$1(topic, topicDecoders, callback, onError);
|
|
1116
|
-
}
|
|
1117
1019
|
},
|
|
1118
1020
|
error: error => {
|
|
1119
|
-
var _topicDecoders$
|
|
1120
|
-
if (((_topicDecoders$get8 = topicDecoders.get(topic)) === null || _topicDecoders$get8 === void 0 ? void 0 : _topicDecoders$get8.decoder) !== decoder) {
|
|
1121
|
-
return;
|
|
1122
|
-
}
|
|
1021
|
+
var _topicDecoders$get5;
|
|
1123
1022
|
if (!hasProducedFrame && isIgnorableInitialDecodeError(error)) {
|
|
1124
1023
|
logger$2.warn(`Ignoring initial H264 decoder error for topic ${topic}: ${error.message}`);
|
|
1125
1024
|
closeTopicDecoder$1(topic, topicDecoders);
|
|
@@ -1127,10 +1026,9 @@ function createVideoDecoder$1({
|
|
|
1127
1026
|
}
|
|
1128
1027
|
logger$2.error(error);
|
|
1129
1028
|
closeTopicDecoder$1(topic, topicDecoders);
|
|
1130
|
-
onError(new DecoderRuntimeError(topic, error.message));
|
|
1029
|
+
(_topicDecoders$get5 = topicDecoders.get(topic)) === null || _topicDecoders$get5 === void 0 || _topicDecoders$get5.onError(new DecoderRuntimeError(topic, error.message));
|
|
1131
1030
|
}
|
|
1132
1031
|
});
|
|
1133
|
-
return decoder;
|
|
1134
1032
|
}
|
|
1135
1033
|
async function deserializeEncodedFrameH264({
|
|
1136
1034
|
topic,
|
|
@@ -1147,14 +1045,43 @@ async function deserializeEncodedFrameH264({
|
|
|
1147
1045
|
return;
|
|
1148
1046
|
}
|
|
1149
1047
|
const existingDecoderInfo = topicDecoders.get(topic);
|
|
1150
|
-
if (!existingDecoderInfo || existingDecoderInfo.decoder.state
|
|
1151
|
-
const decoder =
|
|
1048
|
+
if (!existingDecoderInfo || existingDecoderInfo.decoder.state === "closed") {
|
|
1049
|
+
const decoder = createVideoDecoder$1({
|
|
1152
1050
|
topic,
|
|
1153
|
-
|
|
1154
|
-
topicDecoders,
|
|
1155
|
-
onError
|
|
1051
|
+
topicDecoders
|
|
1156
1052
|
});
|
|
1157
|
-
|
|
1053
|
+
try {
|
|
1054
|
+
configureDecoder(decoder);
|
|
1055
|
+
} catch (error) {
|
|
1056
|
+
closeDecoder$1(decoder);
|
|
1057
|
+
onError(new DecoderRuntimeError(topic, error instanceof Error ? error.message : "Failed to configure H.264 decoder."));
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
if (existingDecoderInfo) {
|
|
1061
|
+
existingDecoderInfo.decoder = decoder;
|
|
1062
|
+
existingDecoderInfo.timing.clear();
|
|
1063
|
+
existingDecoderInfo.transformations.clear();
|
|
1064
|
+
existingDecoderInfo.callback = callback;
|
|
1065
|
+
existingDecoderInfo.onError = onError;
|
|
1066
|
+
} else {
|
|
1067
|
+
topicDecoders.set(topic, {
|
|
1068
|
+
decoder,
|
|
1069
|
+
timing: new Map(),
|
|
1070
|
+
transformations: new Map(),
|
|
1071
|
+
callback,
|
|
1072
|
+
onError
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
} else if (existingDecoderInfo.decoder.state === "unconfigured") {
|
|
1076
|
+
try {
|
|
1077
|
+
configureDecoder(existingDecoderInfo.decoder);
|
|
1078
|
+
existingDecoderInfo.timing.clear();
|
|
1079
|
+
existingDecoderInfo.transformations.clear();
|
|
1080
|
+
existingDecoderInfo.callback = callback;
|
|
1081
|
+
existingDecoderInfo.onError = onError;
|
|
1082
|
+
} catch (error) {
|
|
1083
|
+
closeTopicDecoder$1(topic, topicDecoders);
|
|
1084
|
+
onError(new DecoderRuntimeError(topic, error instanceof Error ? error.message : "Failed to reconfigure H.264 decoder."));
|
|
1158
1085
|
return;
|
|
1159
1086
|
}
|
|
1160
1087
|
}
|
|
@@ -1162,19 +1089,33 @@ async function deserializeEncodedFrameH264({
|
|
|
1162
1089
|
if (!decoderInfo) {
|
|
1163
1090
|
return;
|
|
1164
1091
|
}
|
|
1092
|
+
decoderInfo.callback = callback;
|
|
1093
|
+
decoderInfo.onError = onError;
|
|
1094
|
+
if (decoderInfo.decoder.decodeQueueSize > 60) {
|
|
1095
|
+
decoderInfo.decoder.reset();
|
|
1096
|
+
decoderInfo.timing.clear();
|
|
1097
|
+
decoderInfo.transformations.clear();
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1165
1100
|
const microTimestamp = receiveTime.sec * 1000000 + Math.floor(receiveTime.nsec / 1000);
|
|
1101
|
+
decoderInfo.timing.set(microTimestamp, receiveTime);
|
|
1102
|
+
decoderInfo.transformations.set(microTimestamp, message.transformation);
|
|
1166
1103
|
const frame = {
|
|
1104
|
+
type: 'key',
|
|
1167
1105
|
data: message.data,
|
|
1168
|
-
timestamp: microTimestamp
|
|
1169
|
-
receiveTime,
|
|
1170
|
-
transformation: message.transformation
|
|
1106
|
+
timestamp: microTimestamp
|
|
1171
1107
|
};
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1108
|
+
try {
|
|
1109
|
+
const chunk = new EncodedVideoChunk(frame);
|
|
1110
|
+
decoderInfo.decoder.decode(chunk);
|
|
1111
|
+
} catch (error) {
|
|
1112
|
+
if (isIgnorableInitialDecodeError(error)) {
|
|
1113
|
+
closeTopicDecoder$1(topic, topicDecoders);
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1116
|
+
closeTopicDecoder$1(topic, topicDecoders);
|
|
1117
|
+
onError(new DecoderRuntimeError(topic, error instanceof Error ? error.message : "Failed to decode H.264 frame."));
|
|
1175
1118
|
}
|
|
1176
|
-
decoderInfo.pendingFrame = frame;
|
|
1177
|
-
decodePendingFrame$1(topic, topicDecoders, callback, onError);
|
|
1178
1119
|
}
|
|
1179
1120
|
|
|
1180
1121
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
@@ -1182,17 +1123,6 @@ async function deserializeEncodedFrameH264({
|
|
|
1182
1123
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/
|
|
1183
1124
|
|
|
1184
1125
|
const logger$1 = Logger.getLogger();
|
|
1185
|
-
function configureDecoder(decoder) {
|
|
1186
|
-
decoder.configure({
|
|
1187
|
-
codec: "hev1.1.6.L93.B0",
|
|
1188
|
-
optimizeForLatency: true
|
|
1189
|
-
});
|
|
1190
|
-
}
|
|
1191
|
-
function ensureDecoderConfigured(decoder) {
|
|
1192
|
-
if (decoder.state === "unconfigured") {
|
|
1193
|
-
configureDecoder(decoder);
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
1126
|
function closeDecoder(decoder) {
|
|
1197
1127
|
if (!decoder) {
|
|
1198
1128
|
return;
|
|
@@ -1208,133 +1138,35 @@ function closeDecoder(decoder) {
|
|
|
1208
1138
|
}
|
|
1209
1139
|
function closeTopicDecoder(topic, topicDecoders) {
|
|
1210
1140
|
const decoderInfo = topicDecoders.get(topic);
|
|
1211
|
-
topicDecoders.delete(topic);
|
|
1212
1141
|
closeDecoder(decoderInfo === null || decoderInfo === void 0 ? void 0 : decoderInfo.decoder);
|
|
1213
1142
|
decoderInfo === null || decoderInfo === void 0 || decoderInfo.timing.clear();
|
|
1214
1143
|
decoderInfo === null || decoderInfo === void 0 || decoderInfo.transformations.clear();
|
|
1215
|
-
if (decoderInfo) {
|
|
1216
|
-
decoderInfo.pendingFrame = undefined;
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
function isUnconfiguredCodecError(error) {
|
|
1220
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1221
|
-
return /cannot call ["']decode["'] on an unconfigured (?:codec|decoder)/i.test(message);
|
|
1222
|
-
}
|
|
1223
|
-
function resetTopicDecoder({
|
|
1224
|
-
topic,
|
|
1225
|
-
topicDecoders,
|
|
1226
|
-
callback,
|
|
1227
|
-
onError
|
|
1228
|
-
}) {
|
|
1229
|
-
const existingDecoderInfo = topicDecoders.get(topic);
|
|
1230
|
-
closeDecoder(existingDecoderInfo === null || existingDecoderInfo === void 0 ? void 0 : existingDecoderInfo.decoder);
|
|
1231
|
-
const decoder = createVideoDecoder({
|
|
1232
|
-
topic,
|
|
1233
|
-
callback,
|
|
1234
|
-
topicDecoders,
|
|
1235
|
-
onError
|
|
1236
|
-
});
|
|
1237
|
-
try {
|
|
1238
|
-
configureDecoder(decoder);
|
|
1239
|
-
} catch (error) {
|
|
1240
|
-
closeDecoder(decoder);
|
|
1241
|
-
closeTopicDecoder(topic, topicDecoders);
|
|
1242
|
-
onError(new DecoderRuntimeError(topic, error instanceof Error ? error.message : "Failed to configure H.265 decoder."));
|
|
1243
|
-
return undefined;
|
|
1244
|
-
}
|
|
1245
|
-
if (existingDecoderInfo) {
|
|
1246
|
-
existingDecoderInfo.decoder = decoder;
|
|
1247
|
-
existingDecoderInfo.timing.clear();
|
|
1248
|
-
existingDecoderInfo.transformations.clear();
|
|
1249
|
-
existingDecoderInfo.pendingFrame = undefined;
|
|
1250
|
-
} else {
|
|
1251
|
-
topicDecoders.set(topic, {
|
|
1252
|
-
decoder,
|
|
1253
|
-
timing: new Map(),
|
|
1254
|
-
transformations: new Map(),
|
|
1255
|
-
pendingFrame: undefined
|
|
1256
|
-
});
|
|
1257
|
-
}
|
|
1258
|
-
return decoder;
|
|
1259
|
-
}
|
|
1260
|
-
function decodePendingFrame(topic, topicDecoders, callback, onError) {
|
|
1261
|
-
const decoderInfo = topicDecoders.get(topic);
|
|
1262
|
-
if (!decoderInfo) {
|
|
1263
|
-
return;
|
|
1264
|
-
}
|
|
1265
|
-
const decoder = decoderInfo.decoder;
|
|
1266
|
-
if (decoder.state === "closed" || decoder.decodeQueueSize > 0) {
|
|
1267
|
-
return;
|
|
1268
|
-
}
|
|
1269
|
-
const pendingFrame = decoderInfo.pendingFrame;
|
|
1270
|
-
if (!pendingFrame) {
|
|
1271
|
-
return;
|
|
1272
|
-
}
|
|
1273
|
-
decoderInfo.pendingFrame = undefined;
|
|
1274
|
-
decoderInfo.timing.set(pendingFrame.timestamp, pendingFrame.receiveTime);
|
|
1275
|
-
decoderInfo.transformations.set(pendingFrame.timestamp, pendingFrame.transformation);
|
|
1276
|
-
try {
|
|
1277
|
-
var _topicDecoders$get;
|
|
1278
|
-
ensureDecoderConfigured(decoder);
|
|
1279
|
-
if (decoder.state !== "configured" || ((_topicDecoders$get = topicDecoders.get(topic)) === null || _topicDecoders$get === void 0 ? void 0 : _topicDecoders$get.decoder) !== decoder) {
|
|
1280
|
-
closeTopicDecoder(topic, topicDecoders);
|
|
1281
|
-
return;
|
|
1282
|
-
}
|
|
1283
|
-
const chunk = new EncodedVideoChunk({
|
|
1284
|
-
type: "key",
|
|
1285
|
-
data: pendingFrame.data,
|
|
1286
|
-
timestamp: pendingFrame.timestamp
|
|
1287
|
-
});
|
|
1288
|
-
decoder.decode(chunk);
|
|
1289
|
-
} catch (error) {
|
|
1290
|
-
if (isUnconfiguredCodecError(error)) {
|
|
1291
|
-
decoderInfo.pendingFrame = pendingFrame;
|
|
1292
|
-
const replacementDecoder = resetTopicDecoder({
|
|
1293
|
-
topic,
|
|
1294
|
-
topicDecoders,
|
|
1295
|
-
callback,
|
|
1296
|
-
onError
|
|
1297
|
-
});
|
|
1298
|
-
if ((replacementDecoder === null || replacementDecoder === void 0 ? void 0 : replacementDecoder.state) === "configured") {
|
|
1299
|
-
decodePendingFrame(topic, topicDecoders, callback, onError);
|
|
1300
|
-
}
|
|
1301
|
-
return;
|
|
1302
|
-
}
|
|
1303
|
-
closeTopicDecoder(topic, topicDecoders);
|
|
1304
|
-
onError(new DecoderRuntimeError(topic, error instanceof Error ? error.message : "Failed to decode H.265 frame."));
|
|
1305
|
-
}
|
|
1306
1144
|
}
|
|
1307
1145
|
function createVideoDecoder({
|
|
1308
1146
|
topic,
|
|
1309
|
-
|
|
1310
|
-
topicDecoders,
|
|
1311
|
-
onError
|
|
1147
|
+
topicDecoders
|
|
1312
1148
|
}) {
|
|
1313
|
-
|
|
1314
|
-
decoder = new VideoDecoder({
|
|
1149
|
+
return new VideoDecoder({
|
|
1315
1150
|
output: async frame => {
|
|
1316
|
-
var _topicDecoders$
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
const
|
|
1324
|
-
(_topicDecoders$
|
|
1325
|
-
const transformation = (_topicDecoders$get5 = topicDecoders.get(topic)) === null || _topicDecoders$get5 === void 0 ? void 0 : _topicDecoders$get5.transformations.get(frame.timestamp);
|
|
1326
|
-
(_topicDecoders$get6 = topicDecoders.get(topic)) === null || _topicDecoders$get6 === void 0 || _topicDecoders$get6.transformations.delete(frame.timestamp);
|
|
1327
|
-
const [encoding, step] = parsePixelFormat(frame.format);
|
|
1151
|
+
var _topicDecoders$get$ti, _topicDecoders$get, _topicDecoders$get2, _topicDecoders$get3, _topicDecoders$get4;
|
|
1152
|
+
const {
|
|
1153
|
+
data: buffer,
|
|
1154
|
+
width,
|
|
1155
|
+
height
|
|
1156
|
+
} = await copyVideoFrameToI420(frame, "H265");
|
|
1157
|
+
const receiveTime = (_topicDecoders$get$ti = (_topicDecoders$get = topicDecoders.get(topic)) === null || _topicDecoders$get === void 0 ? void 0 : _topicDecoders$get.timing.get(frame.timestamp)) !== null && _topicDecoders$get$ti !== void 0 ? _topicDecoders$get$ti : dist.fromMicros(frame.timestamp);
|
|
1158
|
+
const transformation = (_topicDecoders$get2 = topicDecoders.get(topic)) === null || _topicDecoders$get2 === void 0 ? void 0 : _topicDecoders$get2.transformations.get(frame.timestamp);
|
|
1159
|
+
(_topicDecoders$get3 = topicDecoders.get(topic)) === null || _topicDecoders$get3 === void 0 || _topicDecoders$get3.transformations.delete(frame.timestamp);
|
|
1328
1160
|
const foxgloveMessage = {
|
|
1329
1161
|
timestamp: receiveTime,
|
|
1330
1162
|
frame_id: `h265-${topic}-frame`,
|
|
1331
|
-
width
|
|
1332
|
-
height
|
|
1163
|
+
width,
|
|
1164
|
+
height,
|
|
1333
1165
|
data: buffer,
|
|
1334
|
-
encoding,
|
|
1335
|
-
step:
|
|
1166
|
+
encoding: "yuv420p",
|
|
1167
|
+
step: width
|
|
1336
1168
|
};
|
|
1337
|
-
callback({
|
|
1169
|
+
(_topicDecoders$get4 = topicDecoders.get(topic)) === null || _topicDecoders$get4 === void 0 || _topicDecoders$get4.callback({
|
|
1338
1170
|
topic,
|
|
1339
1171
|
receiveTime,
|
|
1340
1172
|
message: foxgloveMessage,
|
|
@@ -1343,21 +1175,14 @@ function createVideoDecoder({
|
|
|
1343
1175
|
depthaiTransformation: transformation
|
|
1344
1176
|
});
|
|
1345
1177
|
frame.close();
|
|
1346
|
-
if (((_topicDecoders$get7 = topicDecoders.get(topic)) === null || _topicDecoders$get7 === void 0 ? void 0 : _topicDecoders$get7.decoder) === decoder) {
|
|
1347
|
-
decodePendingFrame(topic, topicDecoders, callback, onError);
|
|
1348
|
-
}
|
|
1349
1178
|
},
|
|
1350
1179
|
error: error => {
|
|
1351
|
-
var _topicDecoders$
|
|
1352
|
-
if (((_topicDecoders$get8 = topicDecoders.get(topic)) === null || _topicDecoders$get8 === void 0 ? void 0 : _topicDecoders$get8.decoder) !== decoder) {
|
|
1353
|
-
return;
|
|
1354
|
-
}
|
|
1180
|
+
var _topicDecoders$get5;
|
|
1355
1181
|
logger$1.error(error);
|
|
1356
1182
|
closeTopicDecoder(topic, topicDecoders);
|
|
1357
|
-
onError(new DecoderRuntimeError(topic, error.message));
|
|
1183
|
+
(_topicDecoders$get5 = topicDecoders.get(topic)) === null || _topicDecoders$get5 === void 0 || _topicDecoders$get5.onError(new DecoderRuntimeError(topic, error.message));
|
|
1358
1184
|
}
|
|
1359
1185
|
});
|
|
1360
|
-
return decoder;
|
|
1361
1186
|
}
|
|
1362
1187
|
async function deserializeEncodedFrameH265({
|
|
1363
1188
|
topic,
|
|
@@ -1374,34 +1199,62 @@ async function deserializeEncodedFrameH265({
|
|
|
1374
1199
|
return;
|
|
1375
1200
|
}
|
|
1376
1201
|
const existingDecoderInfo = topicDecoders.get(topic);
|
|
1377
|
-
if (!existingDecoderInfo || existingDecoderInfo.decoder.state
|
|
1378
|
-
const decoder =
|
|
1202
|
+
if (!existingDecoderInfo || existingDecoderInfo.decoder.state === "closed") {
|
|
1203
|
+
const decoder = createVideoDecoder({
|
|
1379
1204
|
topic,
|
|
1380
|
-
|
|
1381
|
-
topicDecoders,
|
|
1382
|
-
onError
|
|
1205
|
+
topicDecoders
|
|
1383
1206
|
});
|
|
1384
|
-
|
|
1207
|
+
try {
|
|
1208
|
+
decoder.configure({
|
|
1209
|
+
codec: "hev1.1.6.L93.B0",
|
|
1210
|
+
optimizeForLatency: true
|
|
1211
|
+
});
|
|
1212
|
+
} catch (error) {
|
|
1213
|
+
closeDecoder(decoder);
|
|
1214
|
+
onError(new DecoderRuntimeError(topic, error instanceof Error ? error.message : "Failed to configure H.265 decoder."));
|
|
1385
1215
|
return;
|
|
1386
1216
|
}
|
|
1217
|
+
if (existingDecoderInfo) {
|
|
1218
|
+
existingDecoderInfo.decoder = decoder;
|
|
1219
|
+
existingDecoderInfo.timing.clear();
|
|
1220
|
+
existingDecoderInfo.transformations.clear();
|
|
1221
|
+
existingDecoderInfo.callback = callback;
|
|
1222
|
+
existingDecoderInfo.onError = onError;
|
|
1223
|
+
} else {
|
|
1224
|
+
topicDecoders.set(topic, {
|
|
1225
|
+
decoder,
|
|
1226
|
+
timing: new Map(),
|
|
1227
|
+
transformations: new Map(),
|
|
1228
|
+
callback,
|
|
1229
|
+
onError
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1387
1232
|
}
|
|
1388
1233
|
const decoderInfo = topicDecoders.get(topic);
|
|
1389
1234
|
if (!decoderInfo) {
|
|
1390
1235
|
return;
|
|
1391
1236
|
}
|
|
1237
|
+
decoderInfo.callback = callback;
|
|
1238
|
+
decoderInfo.onError = onError;
|
|
1239
|
+
if (decoderInfo.decoder.decodeQueueSize > 60) {
|
|
1240
|
+
decoderInfo.decoder.reset();
|
|
1241
|
+
return;
|
|
1242
|
+
}
|
|
1392
1243
|
const microTimestamp = receiveTime.sec * 1000000 + Math.floor(receiveTime.nsec / 1000);
|
|
1244
|
+
decoderInfo.timing.set(microTimestamp, receiveTime);
|
|
1245
|
+
decoderInfo.transformations.set(microTimestamp, message.transformation);
|
|
1393
1246
|
const frame = {
|
|
1247
|
+
type: 'key',
|
|
1394
1248
|
data: message.data,
|
|
1395
|
-
timestamp: microTimestamp
|
|
1396
|
-
receiveTime,
|
|
1397
|
-
transformation: message.transformation
|
|
1249
|
+
timestamp: microTimestamp
|
|
1398
1250
|
};
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1251
|
+
try {
|
|
1252
|
+
const chunk = new EncodedVideoChunk(frame);
|
|
1253
|
+
decoderInfo.decoder.decode(chunk);
|
|
1254
|
+
} catch (error) {
|
|
1255
|
+
closeTopicDecoder(topic, topicDecoders);
|
|
1256
|
+
onError(new DecoderRuntimeError(topic, error instanceof Error ? error.message : "Failed to decode H.265 frame."));
|
|
1402
1257
|
}
|
|
1403
|
-
decoderInfo.pendingFrame = frame;
|
|
1404
|
-
decodePendingFrame(topic, topicDecoders, callback, onError);
|
|
1405
1258
|
}
|
|
1406
1259
|
|
|
1407
1260
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
@@ -1427,17 +1280,19 @@ async function deserializeMJPEGFrame({
|
|
|
1427
1280
|
const {
|
|
1428
1281
|
image: frame
|
|
1429
1282
|
} = await decoder.decode();
|
|
1430
|
-
const
|
|
1431
|
-
|
|
1432
|
-
|
|
1283
|
+
const {
|
|
1284
|
+
data: buffer,
|
|
1285
|
+
width,
|
|
1286
|
+
height
|
|
1287
|
+
} = await copyVideoFrameToI420(frame, "MJPEG");
|
|
1433
1288
|
const foxgloveMessage = {
|
|
1434
1289
|
timestamp: receiveTime,
|
|
1435
1290
|
frame_id: "camera",
|
|
1436
|
-
width
|
|
1437
|
-
height
|
|
1291
|
+
width,
|
|
1292
|
+
height,
|
|
1438
1293
|
data: buffer,
|
|
1439
|
-
encoding,
|
|
1440
|
-
step:
|
|
1294
|
+
encoding: "yuv420p",
|
|
1295
|
+
step: width
|
|
1441
1296
|
};
|
|
1442
1297
|
frame.close();
|
|
1443
1298
|
callback({
|
|
@@ -1450,6 +1305,372 @@ async function deserializeMJPEGFrame({
|
|
|
1450
1305
|
});
|
|
1451
1306
|
}
|
|
1452
1307
|
|
|
1308
|
+
const RGBD_POINTCLOUD_WORKER_COUNT = 6;
|
|
1309
|
+
let cachedRGBDHasGPU;
|
|
1310
|
+
let rgbdHasGPUPromise;
|
|
1311
|
+
let rgbdPointCloudWorkers;
|
|
1312
|
+
let rgbdPointCloudWorkerIndex = 0;
|
|
1313
|
+
function ensureEvenByteLength(data) {
|
|
1314
|
+
if (data.length % 2 === 0) {
|
|
1315
|
+
return data;
|
|
1316
|
+
}
|
|
1317
|
+
const padded = new Uint8Array(data.length + 1);
|
|
1318
|
+
padded.set(data);
|
|
1319
|
+
return padded;
|
|
1320
|
+
}
|
|
1321
|
+
function ensureRGBDGPUSupportDetection() {
|
|
1322
|
+
if (cachedRGBDHasGPU != undefined || rgbdHasGPUPromise) {
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
rgbdHasGPUPromise = (async () => {
|
|
1326
|
+
if (typeof navigator.gpu === "undefined") {
|
|
1327
|
+
cachedRGBDHasGPU = false;
|
|
1328
|
+
return false;
|
|
1329
|
+
}
|
|
1330
|
+
try {
|
|
1331
|
+
const adapter = await navigator.gpu.requestAdapter();
|
|
1332
|
+
cachedRGBDHasGPU = adapter != undefined;
|
|
1333
|
+
return cachedRGBDHasGPU;
|
|
1334
|
+
} catch (error) {
|
|
1335
|
+
cachedRGBDHasGPU = false;
|
|
1336
|
+
return false;
|
|
1337
|
+
} finally {
|
|
1338
|
+
rgbdHasGPUPromise = undefined;
|
|
1339
|
+
}
|
|
1340
|
+
})();
|
|
1341
|
+
}
|
|
1342
|
+
function getRGBDGPUSupport() {
|
|
1343
|
+
ensureRGBDGPUSupportDetection();
|
|
1344
|
+
return cachedRGBDHasGPU !== null && cachedRGBDHasGPU !== void 0 ? cachedRGBDHasGPU : false;
|
|
1345
|
+
}
|
|
1346
|
+
function getRGBDPointCloudWorkerSlot() {
|
|
1347
|
+
if (!rgbdPointCloudWorkers) {
|
|
1348
|
+
rgbdPointCloudWorkers = Array.from({
|
|
1349
|
+
length: RGBD_POINTCLOUD_WORKER_COUNT
|
|
1350
|
+
}, () => {
|
|
1351
|
+
const worker = new Worker(new URL("pointcloudFromDepth.worker-60RA4Ief.js", import.meta.url), {
|
|
1352
|
+
type: "module"
|
|
1353
|
+
});
|
|
1354
|
+
return {
|
|
1355
|
+
worker,
|
|
1356
|
+
remote: wrap(worker),
|
|
1357
|
+
activeJobs: 0
|
|
1358
|
+
};
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1361
|
+
const slots = rgbdPointCloudWorkers;
|
|
1362
|
+
const candidateSlots = slots.map((slot, index) => ({
|
|
1363
|
+
slot,
|
|
1364
|
+
index
|
|
1365
|
+
})).sort((left, right) => {
|
|
1366
|
+
if (left.slot.activeJobs !== right.slot.activeJobs) {
|
|
1367
|
+
return left.slot.activeJobs - right.slot.activeJobs;
|
|
1368
|
+
}
|
|
1369
|
+
const leftDistance = (left.index - rgbdPointCloudWorkerIndex + slots.length) % slots.length;
|
|
1370
|
+
const rightDistance = (right.index - rgbdPointCloudWorkerIndex + slots.length) % slots.length;
|
|
1371
|
+
return leftDistance - rightDistance;
|
|
1372
|
+
});
|
|
1373
|
+
const selected = candidateSlots[0];
|
|
1374
|
+
rgbdPointCloudWorkerIndex = (selected.index + 1) % slots.length;
|
|
1375
|
+
return {
|
|
1376
|
+
slot: selected.slot,
|
|
1377
|
+
index: selected.index
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
function repackYuv420pToI420(imageFrame, width, height) {
|
|
1381
|
+
var _imageFrame$fb;
|
|
1382
|
+
const specs = (_imageFrame$fb = imageFrame.fb) !== null && _imageFrame$fb !== void 0 ? _imageFrame$fb : imageFrame.sourceFb;
|
|
1383
|
+
const source = ensureEvenByteLength(imageFrame.data);
|
|
1384
|
+
const yStride = (specs === null || specs === void 0 ? void 0 : specs.stride) || width;
|
|
1385
|
+
const uvWidth = Math.floor(width / 2);
|
|
1386
|
+
const uvHeight = Math.floor(height / 2);
|
|
1387
|
+
const uvStride = yStride > width ? Math.floor(yStride / 2) : uvWidth;
|
|
1388
|
+
const yPlaneSize = width * height;
|
|
1389
|
+
const uvPlaneSize = uvWidth * uvHeight;
|
|
1390
|
+
const uOffset = (specs === null || specs === void 0 ? void 0 : specs.p1Offset) || yStride * height;
|
|
1391
|
+
const vOffset = (specs === null || specs === void 0 ? void 0 : specs.p2Offset) || uOffset + uvStride * uvHeight;
|
|
1392
|
+
const i420 = new Uint8Array(yPlaneSize + 2 * uvPlaneSize);
|
|
1393
|
+
for (let row = 0; row < height; row++) {
|
|
1394
|
+
const srcOffset = row * yStride;
|
|
1395
|
+
const dstOffset = row * width;
|
|
1396
|
+
i420.set(source.subarray(srcOffset, srcOffset + width), dstOffset);
|
|
1397
|
+
}
|
|
1398
|
+
for (let row = 0; row < uvHeight; row++) {
|
|
1399
|
+
const srcUOffset = uOffset + row * uvStride;
|
|
1400
|
+
const srcVOffset = vOffset + row * uvStride;
|
|
1401
|
+
const dstOffset = row * uvWidth;
|
|
1402
|
+
i420.set(source.subarray(srcUOffset, srcUOffset + uvWidth), yPlaneSize + dstOffset);
|
|
1403
|
+
i420.set(source.subarray(srcVOffset, srcVOffset + uvWidth), yPlaneSize + uvPlaneSize + dstOffset);
|
|
1404
|
+
}
|
|
1405
|
+
return i420;
|
|
1406
|
+
}
|
|
1407
|
+
function toMatrix3x3(matrix) {
|
|
1408
|
+
const rows = matrix === null || matrix === void 0 ? void 0 : matrix.arrays;
|
|
1409
|
+
if (!rows || rows.length < 3) {
|
|
1410
|
+
return undefined;
|
|
1411
|
+
}
|
|
1412
|
+
const normalizedRows = rows.slice(0, 3).map(row => row === null || row === void 0 ? void 0 : row.values.slice(0, 3).map(value => value !== null && value !== void 0 ? value : 0));
|
|
1413
|
+
if (normalizedRows.some(row => !row || row.length < 3)) {
|
|
1414
|
+
return undefined;
|
|
1415
|
+
}
|
|
1416
|
+
return normalizedRows;
|
|
1417
|
+
}
|
|
1418
|
+
function multiply3x3(left, right) {
|
|
1419
|
+
return [[left[0][0] * right[0][0] + left[0][1] * right[1][0] + left[0][2] * right[2][0], left[0][0] * right[0][1] + left[0][1] * right[1][1] + left[0][2] * right[2][1], left[0][0] * right[0][2] + left[0][1] * right[1][2] + left[0][2] * right[2][2]], [left[1][0] * right[0][0] + left[1][1] * right[1][0] + left[1][2] * right[2][0], left[1][0] * right[0][1] + left[1][1] * right[1][1] + left[1][2] * right[2][1], left[1][0] * right[0][2] + left[1][1] * right[1][2] + left[1][2] * right[2][2]], [left[2][0] * right[0][0] + left[2][1] * right[1][0] + left[2][2] * right[2][0], left[2][0] * right[0][1] + left[2][1] * right[1][1] + left[2][2] * right[2][1], left[2][0] * right[0][2] + left[2][1] * right[1][2] + left[2][2] * right[2][2]]];
|
|
1420
|
+
}
|
|
1421
|
+
function extractIntrinsicsFromTransformation(transformation) {
|
|
1422
|
+
const sourceIntrinsicMatrix = toMatrix3x3(transformation === null || transformation === void 0 ? void 0 : transformation.sourceIntrinsicMatrix);
|
|
1423
|
+
if (!sourceIntrinsicMatrix) {
|
|
1424
|
+
return undefined;
|
|
1425
|
+
}
|
|
1426
|
+
const transformationMatrix = toMatrix3x3(transformation === null || transformation === void 0 ? void 0 : transformation.transformationMatrix);
|
|
1427
|
+
const effectiveIntrinsicMatrix = transformationMatrix ? multiply3x3(transformationMatrix, sourceIntrinsicMatrix) : sourceIntrinsicMatrix;
|
|
1428
|
+
const fx = effectiveIntrinsicMatrix[0][0];
|
|
1429
|
+
const fy = effectiveIntrinsicMatrix[1][1];
|
|
1430
|
+
const cx = effectiveIntrinsicMatrix[0][2];
|
|
1431
|
+
const cy = effectiveIntrinsicMatrix[1][2];
|
|
1432
|
+
if (![fx, fy, cx, cy].every(value => Number.isFinite(value))) {
|
|
1433
|
+
return undefined;
|
|
1434
|
+
}
|
|
1435
|
+
return {
|
|
1436
|
+
left: {
|
|
1437
|
+
focalLenght: {
|
|
1438
|
+
x: fx,
|
|
1439
|
+
y: fy
|
|
1440
|
+
},
|
|
1441
|
+
principalPoint: {
|
|
1442
|
+
x: cx,
|
|
1443
|
+
y: cy
|
|
1444
|
+
}
|
|
1445
|
+
},
|
|
1446
|
+
right: {
|
|
1447
|
+
focalLenght: {
|
|
1448
|
+
x: fx,
|
|
1449
|
+
y: fy
|
|
1450
|
+
},
|
|
1451
|
+
principalPoint: {
|
|
1452
|
+
x: cx,
|
|
1453
|
+
y: cy
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
};
|
|
1457
|
+
}
|
|
1458
|
+
function resolveRGBDIntrinsics(message, fallbackIntrinsics) {
|
|
1459
|
+
var _ref, _ref2, _ref3, _extractIntrinsicsFro, _message$depthImgFram, _message$depthEncoded, _message$colorImgFram, _message$colorEncoded;
|
|
1460
|
+
return (_ref = (_ref2 = (_ref3 = (_extractIntrinsicsFro = extractIntrinsicsFromTransformation((_message$depthImgFram = message.depthImgFrame) === null || _message$depthImgFram === void 0 ? void 0 : _message$depthImgFram.transformation)) !== null && _extractIntrinsicsFro !== void 0 ? _extractIntrinsicsFro : extractIntrinsicsFromTransformation((_message$depthEncoded = message.depthEncodedFrame) === null || _message$depthEncoded === void 0 ? void 0 : _message$depthEncoded.transformation)) !== null && _ref3 !== void 0 ? _ref3 : extractIntrinsicsFromTransformation((_message$colorImgFram = message.colorImgFrame) === null || _message$colorImgFram === void 0 ? void 0 : _message$colorImgFram.transformation)) !== null && _ref2 !== void 0 ? _ref2 : extractIntrinsicsFromTransformation((_message$colorEncoded = message.colorEncodedFrame) === null || _message$colorEncoded === void 0 ? void 0 : _message$colorEncoded.transformation)) !== null && _ref !== void 0 ? _ref : fallbackIntrinsics;
|
|
1461
|
+
}
|
|
1462
|
+
async function extractEncodedColorFrame(encodedFrame, topicDecoders, topic) {
|
|
1463
|
+
const decodeFrame = async () => await new Promise((resolve, reject) => {
|
|
1464
|
+
const callback = event => {
|
|
1465
|
+
resolve(event.message);
|
|
1466
|
+
};
|
|
1467
|
+
const rejectDecode = error => {
|
|
1468
|
+
reject(error);
|
|
1469
|
+
};
|
|
1470
|
+
const args = {
|
|
1471
|
+
topic,
|
|
1472
|
+
message: encodedFrame,
|
|
1473
|
+
callback
|
|
1474
|
+
};
|
|
1475
|
+
if (encodedFrame.profile === Profile.AVC) {
|
|
1476
|
+
void deserializeEncodedFrameH264(_objectSpread2(_objectSpread2({}, args), {}, {
|
|
1477
|
+
topicDecoders,
|
|
1478
|
+
onError: rejectDecode
|
|
1479
|
+
})).catch(rejectDecode);
|
|
1480
|
+
} else if (encodedFrame.profile === Profile.JPEG) {
|
|
1481
|
+
void deserializeMJPEGFrame(args).catch(rejectDecode);
|
|
1482
|
+
} else if (encodedFrame.profile === Profile.HEVC) {
|
|
1483
|
+
void deserializeEncodedFrameH265(_objectSpread2(_objectSpread2({}, args), {}, {
|
|
1484
|
+
topicDecoders,
|
|
1485
|
+
onError: rejectDecode
|
|
1486
|
+
})).catch(rejectDecode);
|
|
1487
|
+
} else {
|
|
1488
|
+
var _Profile$encodedFrame;
|
|
1489
|
+
reject(new Error(`Unsupported RGBD color profile ${(_Profile$encodedFrame = Profile[encodedFrame.profile]) !== null && _Profile$encodedFrame !== void 0 ? _Profile$encodedFrame : encodedFrame.profile}`));
|
|
1490
|
+
}
|
|
1491
|
+
});
|
|
1492
|
+
const decoded = await decodeFrame();
|
|
1493
|
+
return {
|
|
1494
|
+
data: ensureEvenByteLength(decoded.data),
|
|
1495
|
+
width: decoded.width,
|
|
1496
|
+
height: decoded.height
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
function extractColorFrame(encodedFrame, imageFrame, topicDecoders, topic) {
|
|
1500
|
+
if (encodedFrame) {
|
|
1501
|
+
return extractEncodedColorFrame(encodedFrame, topicDecoders, topic);
|
|
1502
|
+
}
|
|
1503
|
+
if (imageFrame) {
|
|
1504
|
+
var _imageFrame$fb2;
|
|
1505
|
+
const {
|
|
1506
|
+
width,
|
|
1507
|
+
height,
|
|
1508
|
+
type
|
|
1509
|
+
} = parseMessage(imageFrame);
|
|
1510
|
+
const specs = (_imageFrame$fb2 = imageFrame.fb) !== null && _imageFrame$fb2 !== void 0 ? _imageFrame$fb2 : imageFrame.sourceFb;
|
|
1511
|
+
if (type === Type.NV12) {
|
|
1512
|
+
const stride = (specs === null || specs === void 0 ? void 0 : specs.stride) || width;
|
|
1513
|
+
const uvOffset = (specs === null || specs === void 0 ? void 0 : specs.p1Offset) || stride * height;
|
|
1514
|
+
return Promise.resolve({
|
|
1515
|
+
data: convertNv12ToI420(ensureEvenByteLength(imageFrame.data), width, height, stride, stride, 0, uvOffset),
|
|
1516
|
+
width,
|
|
1517
|
+
height
|
|
1518
|
+
});
|
|
1519
|
+
}
|
|
1520
|
+
if (type === Type.YUV420p) {
|
|
1521
|
+
return Promise.resolve({
|
|
1522
|
+
data: repackYuv420pToI420(imageFrame, width, height),
|
|
1523
|
+
width,
|
|
1524
|
+
height
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
return Promise.reject(new Error(`Unsupported RGBD color ImgFrame type ${Type[type]}`));
|
|
1528
|
+
}
|
|
1529
|
+
return Promise.resolve({
|
|
1530
|
+
data: new Uint8Array(),
|
|
1531
|
+
width: 0,
|
|
1532
|
+
height: 0
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
function extractDepthFrame(encodedFrame, imageFrame) {
|
|
1536
|
+
if (encodedFrame) {
|
|
1537
|
+
return ensureEvenByteLength(encodedFrame.data);
|
|
1538
|
+
}
|
|
1539
|
+
if (imageFrame) {
|
|
1540
|
+
return ensureEvenByteLength(imageFrame.data);
|
|
1541
|
+
}
|
|
1542
|
+
return new Uint8Array();
|
|
1543
|
+
}
|
|
1544
|
+
function parseDimensions(message) {
|
|
1545
|
+
const obj = {
|
|
1546
|
+
depthWidth: 0,
|
|
1547
|
+
depthHeight: 0
|
|
1548
|
+
};
|
|
1549
|
+
if (message.depthEncodedFrame) {
|
|
1550
|
+
var _message$depthEncoded2;
|
|
1551
|
+
const {
|
|
1552
|
+
width,
|
|
1553
|
+
height
|
|
1554
|
+
} = (_message$depthEncoded2 = message.depthEncodedFrame) !== null && _message$depthEncoded2 !== void 0 ? _message$depthEncoded2 : {
|
|
1555
|
+
width: 1920,
|
|
1556
|
+
height: 1200
|
|
1557
|
+
};
|
|
1558
|
+
obj.depthWidth = width;
|
|
1559
|
+
obj.depthHeight = height;
|
|
1560
|
+
} else if (message.depthImgFrame) {
|
|
1561
|
+
const {
|
|
1562
|
+
width,
|
|
1563
|
+
height
|
|
1564
|
+
} = parseMessage(message.depthImgFrame);
|
|
1565
|
+
obj.depthWidth = width;
|
|
1566
|
+
obj.depthHeight = height;
|
|
1567
|
+
}
|
|
1568
|
+
return obj;
|
|
1569
|
+
}
|
|
1570
|
+
async function deserializeRGBDFrameToPointCloud({
|
|
1571
|
+
topic,
|
|
1572
|
+
topicDecoders,
|
|
1573
|
+
cameraIntrinsics,
|
|
1574
|
+
maxStereoDepth,
|
|
1575
|
+
message,
|
|
1576
|
+
callback,
|
|
1577
|
+
onError
|
|
1578
|
+
}) {
|
|
1579
|
+
const {
|
|
1580
|
+
slot: workerSlot,
|
|
1581
|
+
index: workerIndex
|
|
1582
|
+
} = getRGBDPointCloudWorkerSlot();
|
|
1583
|
+
workerSlot.activeJobs += 1;
|
|
1584
|
+
const {
|
|
1585
|
+
receiveTime
|
|
1586
|
+
} = parseMessage(message);
|
|
1587
|
+
const {
|
|
1588
|
+
depthWidth,
|
|
1589
|
+
depthHeight
|
|
1590
|
+
} = parseDimensions(message);
|
|
1591
|
+
const rgbdIntrinsics = resolveRGBDIntrinsics(message, cameraIntrinsics);
|
|
1592
|
+
const hasGPU = getRGBDGPUSupport();
|
|
1593
|
+
if (message.depthImgFrame) {
|
|
1594
|
+
const depthFrameForPreview = _objectSpread2(_objectSpread2({}, message.depthImgFrame), {}, {
|
|
1595
|
+
data: message.depthImgFrame.data.slice()
|
|
1596
|
+
});
|
|
1597
|
+
void deserializeDepthFrame({
|
|
1598
|
+
topic,
|
|
1599
|
+
message: depthFrameForPreview,
|
|
1600
|
+
callback,
|
|
1601
|
+
maxStereoDepth: maxStereoDepth / 1000
|
|
1602
|
+
}).catch(onError);
|
|
1603
|
+
}
|
|
1604
|
+
const colorFrame = await extractColorFrame(message.colorEncodedFrame, message.colorImgFrame, topicDecoders, topic);
|
|
1605
|
+
const uint8DepthFrames = extractDepthFrame(message.depthEncodedFrame, message.depthImgFrame);
|
|
1606
|
+
const depthFrames = uint8ArrayToUint16Array(uint8DepthFrames);
|
|
1607
|
+
try {
|
|
1608
|
+
var _message$tsDevice;
|
|
1609
|
+
const pointCloud = await workerSlot.remote.depthToPointcloudGPU([depthFrames], depthWidth, depthHeight, rgbdIntrinsics.right.focalLenght.x, rgbdIntrinsics.right.focalLenght.y, rgbdIntrinsics.right.principalPoint.x, rgbdIntrinsics.right.principalPoint.y, [colorFrame.data], colorFrame.width, colorFrame.height, maxStereoDepth, {
|
|
1610
|
+
hasGPU
|
|
1611
|
+
});
|
|
1612
|
+
const foxgloveMessage = {
|
|
1613
|
+
timestamp: (_message$tsDevice = message.tsDevice) !== null && _message$tsDevice !== void 0 ? _message$tsDevice : receiveTime,
|
|
1614
|
+
frame_id: `pointcloud-${topic}-frame`,
|
|
1615
|
+
point_stride: 16,
|
|
1616
|
+
pose: {
|
|
1617
|
+
position: {
|
|
1618
|
+
x: 0,
|
|
1619
|
+
y: 0,
|
|
1620
|
+
z: 0
|
|
1621
|
+
},
|
|
1622
|
+
orientation: {
|
|
1623
|
+
x: 0,
|
|
1624
|
+
y: 0,
|
|
1625
|
+
z: 1,
|
|
1626
|
+
w: 0
|
|
1627
|
+
}
|
|
1628
|
+
},
|
|
1629
|
+
width: depthWidth,
|
|
1630
|
+
height: depthHeight,
|
|
1631
|
+
fields: [{
|
|
1632
|
+
name: "x",
|
|
1633
|
+
offset: 0,
|
|
1634
|
+
type: typescript.NumericType.FLOAT32
|
|
1635
|
+
}, {
|
|
1636
|
+
name: "y",
|
|
1637
|
+
offset: 4,
|
|
1638
|
+
type: typescript.NumericType.FLOAT32
|
|
1639
|
+
}, {
|
|
1640
|
+
name: "z",
|
|
1641
|
+
offset: 8,
|
|
1642
|
+
type: typescript.NumericType.FLOAT32
|
|
1643
|
+
}, {
|
|
1644
|
+
name: "red",
|
|
1645
|
+
offset: 12,
|
|
1646
|
+
type: typescript.NumericType.UINT8
|
|
1647
|
+
}, {
|
|
1648
|
+
name: "green",
|
|
1649
|
+
offset: 13,
|
|
1650
|
+
type: typescript.NumericType.UINT8
|
|
1651
|
+
}, {
|
|
1652
|
+
name: "blue",
|
|
1653
|
+
offset: 14,
|
|
1654
|
+
type: typescript.NumericType.UINT8
|
|
1655
|
+
}, {
|
|
1656
|
+
name: "alpha",
|
|
1657
|
+
offset: 15,
|
|
1658
|
+
type: typescript.NumericType.UINT8
|
|
1659
|
+
}],
|
|
1660
|
+
data: pointCloud[0]
|
|
1661
|
+
};
|
|
1662
|
+
callback({
|
|
1663
|
+
topic,
|
|
1664
|
+
receiveTime,
|
|
1665
|
+
message: foxgloveMessage,
|
|
1666
|
+
sizeInBytes: estimateObjectSize(foxgloveMessage),
|
|
1667
|
+
schemaName: "foxglove.PointCloud.Colored"
|
|
1668
|
+
});
|
|
1669
|
+
} finally {
|
|
1670
|
+
workerSlot.activeJobs = Math.max(0, workerSlot.activeJobs - 1);
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1453
1674
|
const logger = Logger.getLogger();
|
|
1454
1675
|
function errorInstanceToErrorCode(error) {
|
|
1455
1676
|
if (error instanceof UnsupportedTopicError) {
|
|
@@ -1481,6 +1702,7 @@ function handleMessageToDecode({
|
|
|
1481
1702
|
schema,
|
|
1482
1703
|
buffer,
|
|
1483
1704
|
topic,
|
|
1705
|
+
neuralCameraIntrinsics,
|
|
1484
1706
|
stereoDepthMaxValue
|
|
1485
1707
|
}, configStore, errorCallback) {
|
|
1486
1708
|
const handleDecodingError = error => {
|
|
@@ -1514,6 +1736,7 @@ function handleMessageToDecode({
|
|
|
1514
1736
|
topic,
|
|
1515
1737
|
topicSizes,
|
|
1516
1738
|
topicDecoders,
|
|
1739
|
+
neuralCameraIntrinsics,
|
|
1517
1740
|
message,
|
|
1518
1741
|
callback,
|
|
1519
1742
|
type: protobufSchema.type,
|
|
@@ -1525,7 +1748,6 @@ function handleMessageToDecode({
|
|
|
1525
1748
|
}
|
|
1526
1749
|
}
|
|
1527
1750
|
async function deserializeDepthAiMessage(args) {
|
|
1528
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
1529
1751
|
const {
|
|
1530
1752
|
topicDecoders,
|
|
1531
1753
|
topicSizes,
|
|
@@ -1533,6 +1755,7 @@ async function deserializeDepthAiMessage(args) {
|
|
|
1533
1755
|
message,
|
|
1534
1756
|
callback,
|
|
1535
1757
|
topic,
|
|
1758
|
+
neuralCameraIntrinsics,
|
|
1536
1759
|
maxSteroDepth,
|
|
1537
1760
|
onError
|
|
1538
1761
|
} = args;
|
|
@@ -1678,6 +1901,19 @@ async function deserializeDepthAiMessage(args) {
|
|
|
1678
1901
|
});
|
|
1679
1902
|
break;
|
|
1680
1903
|
}
|
|
1904
|
+
case 'rgbd':
|
|
1905
|
+
{
|
|
1906
|
+
void deserializeRGBDFrameToPointCloud({
|
|
1907
|
+
topic,
|
|
1908
|
+
topicDecoders,
|
|
1909
|
+
cameraIntrinsics: neuralCameraIntrinsics,
|
|
1910
|
+
maxStereoDepth: maxSteroDepth,
|
|
1911
|
+
message,
|
|
1912
|
+
callback,
|
|
1913
|
+
onError
|
|
1914
|
+
});
|
|
1915
|
+
break;
|
|
1916
|
+
}
|
|
1681
1917
|
default:
|
|
1682
1918
|
{
|
|
1683
1919
|
logger.warn(`Message decoding failed: unsupported type "${type}"`);
|