attempt to re-stitch together JPEGs at the recovery markers upon dataloss

This commit is contained in:
DavidVentura
2024-02-01 17:56:27 +01:00
parent 2f2b6d302a
commit 25ae4fa72e
4 changed files with 47 additions and 6 deletions
+40 -3
View File
@@ -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
// than just missing some frames
if (!session.options.attempt_to_fix_packet_loss) {
return; 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
View File
@@ -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";
+1
View File
@@ -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;
}; };
+2
View File
@@ -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,
}; };