attempt to re-stitch together JPEGs at the recovery markers upon dataloss
This commit is contained in:
+41
-4
@@ -152,6 +152,7 @@ const deal_with_data = (session: Session, dv: DataView) => {
|
|||||||
session.eventEmitter.emit("frame");
|
session.eventEmitter.emit("frame");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.frame_was_fixed = false;
|
||||||
session.frame_is_bad = false;
|
session.frame_is_bad = false;
|
||||||
session.curImage = [Buffer.from(data.buffer)];
|
session.curImage = [Buffer.from(data.buffer)];
|
||||||
session.rcvSeqId = pkt_id;
|
session.rcvSeqId = pkt_id;
|
||||||
@@ -164,12 +165,34 @@ const deal_with_data = (session: Session, dv: DataView) => {
|
|||||||
let b = Buffer.from(data.buffer);
|
let b = Buffer.from(data.buffer);
|
||||||
|
|
||||||
if (pkt_id > session.rcvSeqId + 1) {
|
if (pkt_id > session.rcvSeqId + 1) {
|
||||||
// missed some packets -- filling with zeroes still produces a broken
|
|
||||||
// image
|
|
||||||
session.frame_is_bad = true;
|
session.frame_is_bad = true;
|
||||||
console.log(`Missed some packets on ${session.devName} -- skipping a frame`);
|
// this should always be enabled but currently it seems to cause more visual distortion
|
||||||
return;
|
// than just missing some frames
|
||||||
|
if (!session.options.attempt_to_fix_packet_loss) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session.curImage.length == 1) return; // header does not have markers
|
||||||
|
|
||||||
|
let lastFrameSlice = session.curImage[session.curImage.length - 1];
|
||||||
|
const lastResetMarker = findAllResetMarkers(lastFrameSlice).pop();
|
||||||
|
if (lastResetMarker == undefined) {
|
||||||
|
// not storing rcvSeqId as this frame did not put us back in track
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstResetMarker = findAllResetMarkers(b).shift();
|
||||||
|
if (firstResetMarker == undefined) {
|
||||||
|
// not storing rcvSeqId as this frame did not put us back in track
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
session.curImage[session.curImage.length - 1] = Buffer.from(lastFrameSlice.subarray(0, lastResetMarker));
|
||||||
|
b = Buffer.from(b.subarray(firstResetMarker));
|
||||||
|
session.frame_is_bad = false;
|
||||||
|
session.frame_was_fixed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
session.rcvSeqId = pkt_id;
|
session.rcvSeqId = pkt_id;
|
||||||
if (session.curImage != null) {
|
if (session.curImage != null) {
|
||||||
session.curImage.push(b);
|
session.curImage.push(b);
|
||||||
@@ -178,6 +201,20 @@ const deal_with_data = (session: Session, dv: DataView) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const findAllResetMarkers = (b: Buffer): number[] => {
|
||||||
|
// a reset marker is a byte 0xff followed by a byte 0xd0-0xd7
|
||||||
|
let ret = [];
|
||||||
|
for (let i = 0; i < b.length - 1; i++) {
|
||||||
|
if (b[i] == 0xff) {
|
||||||
|
const nb = b[i + 1];
|
||||||
|
if (nb >= 0xd0 && nb <= 0xd7) {
|
||||||
|
ret.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
const makeDrwAck = (dv: DataView): DataView => {
|
const makeDrwAck = (dv: DataView): DataView => {
|
||||||
const pkt_id = dv.add(6).readU16();
|
const pkt_id = dv.add(6).readU16();
|
||||||
const m_stream = dv.add(5).readU8(); // data = 1, control = 0
|
const m_stream = dv.add(5).readU8(); // data = 1, control = 0
|
||||||
|
|||||||
+3
-2
@@ -10,8 +10,9 @@ import { ServerResponse } from "http";
|
|||||||
const opts = {
|
const opts = {
|
||||||
debug: false,
|
debug: false,
|
||||||
ansi: false,
|
ansi: false,
|
||||||
discovery_ip: "192.168.40.255", //, "192.168.1.255"
|
// discovery_ip: "192.168.40.255", //, "192.168.1.255"
|
||||||
// discovery_ip: "192.168.40.101",
|
discovery_ip: "192.168.40.101",
|
||||||
|
attempt_to_fix_packet_loss: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let BOUNDARY = "a very good boundary line";
|
let BOUNDARY = "a very good boundary line";
|
||||||
|
|||||||
@@ -2,4 +2,5 @@ export type opt = {
|
|||||||
debug: boolean;
|
debug: boolean;
|
||||||
ansi: boolean;
|
ansi: boolean;
|
||||||
discovery_ip: string;
|
discovery_ip: string;
|
||||||
|
attempt_to_fix_packet_loss: boolean;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export type Session = {
|
|||||||
curImage: Buffer[];
|
curImage: Buffer[];
|
||||||
rcvSeqId: number;
|
rcvSeqId: number;
|
||||||
frame_is_bad: boolean;
|
frame_is_bad: boolean;
|
||||||
|
frame_was_fixed: boolean;
|
||||||
options: opt;
|
options: opt;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -101,6 +102,7 @@ export const makeSession = (
|
|||||||
curImage: [],
|
curImage: [],
|
||||||
rcvSeqId: 0,
|
rcvSeqId: 0,
|
||||||
frame_is_bad: false,
|
frame_is_bad: false,
|
||||||
|
frame_was_fixed: false,
|
||||||
options: options,
|
options: options,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user