web: Workaround Direct H.264 flickering on Firefox

This commit is contained in:
Maxim Devaev 2025-05-13 19:56:48 +03:00
parent c551b9ff57
commit af51d79502

View File

@ -38,8 +38,9 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
var __ping_timer = null;
var __missed_heartbeats = 0;
var __decoder = null;
var __codec = "";
var __decoder = null;
var __frame = null;
var __canvas = $("stream-canvas");
var __ctx = __canvas.getContext("2d");
@ -208,7 +209,7 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
__closeDecoder();
__codec = codec;
__decoder = new VideoDecoder({ // eslint-disable-line no-undef
"output": __drawFrame,
"output": __renderFrame,
"error": (err) => __logInfo(err.message),
});
if (started) {
@ -241,24 +242,41 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
if (__decoder !== null) {
try {
__decoder.close();
} catch {
// Pass
} finally {
__decoder = null;
__codec = "";
__decoder = null;
if (__frame !== null) {
try {
__closeFrame(__frame);
} finally {
__frame = null;
}
}
}
}
};
var __drawFrame = function(frame) {
var __renderFrame = function(frame) {
if (__frame === null) {
__frame = frame;
window.requestAnimationFrame(__drawPendingFrame, __canvas);
} else {
__closeFrame(frame);
}
};
var __drawPendingFrame = function() {
if (__frame === null) {
return;
}
try {
let width = frame.displayWidth;
let height = frame.displayHeight;
let width = __frame.displayWidth;
let height = __frame.displayHeight;
switch (__orient) {
case 90:
case 270:
width = frame.displayHeight;
height = frame.displayWidth;
width = __frame.displayHeight;
height = __frame.displayWidth;
}
if (__canvas.width !== width || __canvas.height !== height) {
@ -267,7 +285,7 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
}
if (__orient === 0) {
__ctx.drawImage(frame, 0, 0);
__ctx.drawImage(__frame, 0, 0);
} else {
__ctx.save();
try {
@ -276,14 +294,28 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
case 180: __ctx.translate(width, height); __ctx.rotate(-Math.PI); break;
case 270: __ctx.translate(width, 0); __ctx.rotate(Math.PI / 2); break;
}
__ctx.drawImage(frame, 0, 0);
__ctx.drawImage(__frame, 0, 0);
} finally {
__ctx.restore();
}
}
__fps_accum += 1;
} finally {
__closeFrame(__frame);
__frame = null;
}
};
var __closeFrame = function(frame) {
if (!tools.browser.is_firefox) {
// FIXME: On Firefox, image is flickering when we're closing the frame for some reason.
// So we're just not performing the close() and it seems there is no problems here
// because Firefox is implementing some auto-closing logic. With auto-close,
// no flickering observed.
// - https://github.com/mozilla/gecko-dev/blob/82333a9/dom/media/webcodecs/VideoFrame.cpp
// Note at 2025.05.13:
// - The problem is not observed on nightly Firefox 140.
// - It's also not observed with hardware accelleration on 138.
frame.close();
}
};