@@ -38,8 +38,9 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
38
38
var __ping_timer = null ;
39
39
var __missed_heartbeats = 0 ;
40
40
41
- var __decoder = null ;
42
41
var __codec = "" ;
42
+ var __decoder = null ;
43
+ var __frame = null ;
43
44
var __canvas = $ ( "stream-canvas" ) ;
44
45
var __ctx = __canvas . getContext ( "2d" ) ;
45
46
@@ -208,7 +209,7 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
208
209
__closeDecoder ( ) ;
209
210
__codec = codec ;
210
211
__decoder = new VideoDecoder ( { // eslint-disable-line no-undef
211
- "output" : __drawFrame ,
212
+ "output" : __renderFrame ,
212
213
"error" : ( err ) => __logInfo ( err . message ) ,
213
214
} ) ;
214
215
if ( started ) {
@@ -241,24 +242,41 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
241
242
if ( __decoder !== null ) {
242
243
try {
243
244
__decoder . close ( ) ;
244
- } catch {
245
- // Pass
246
245
} finally {
247
- __decoder = null ;
248
246
__codec = "" ;
247
+ __decoder = null ;
248
+ if ( __frame !== null ) {
249
+ try {
250
+ __closeFrame ( __frame ) ;
251
+ } finally {
252
+ __frame = null ;
253
+ }
254
+ }
249
255
}
250
256
}
251
257
} ;
252
258
253
- var __drawFrame = function ( frame ) {
259
+ var __renderFrame = function ( frame ) {
260
+ if ( __frame === null ) {
261
+ __frame = frame ;
262
+ window . requestAnimationFrame ( __drawPendingFrame , __canvas ) ;
263
+ } else {
264
+ __closeFrame ( frame ) ;
265
+ }
266
+ } ;
267
+
268
+ var __drawPendingFrame = function ( ) {
269
+ if ( __frame === null ) {
270
+ return ;
271
+ }
254
272
try {
255
- let width = frame . displayWidth ;
256
- let height = frame . displayHeight ;
273
+ let width = __frame . displayWidth ;
274
+ let height = __frame . displayHeight ;
257
275
switch ( __orient ) {
258
276
case 90 :
259
277
case 270 :
260
- width = frame . displayHeight ;
261
- height = frame . displayWidth ;
278
+ width = __frame . displayHeight ;
279
+ height = __frame . displayWidth ;
262
280
}
263
281
264
282
if ( __canvas . width !== width || __canvas . height !== height ) {
@@ -267,7 +285,7 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
267
285
}
268
286
269
287
if ( __orient === 0 ) {
270
- __ctx . drawImage ( frame , 0 , 0 ) ;
288
+ __ctx . drawImage ( __frame , 0 , 0 ) ;
271
289
} else {
272
290
__ctx . save ( ) ;
273
291
try {
@@ -276,14 +294,28 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
276
294
case 180 : __ctx . translate ( width , height ) ; __ctx . rotate ( - Math . PI ) ; break ;
277
295
case 270 : __ctx . translate ( width , 0 ) ; __ctx . rotate ( Math . PI / 2 ) ; break ;
278
296
}
279
- __ctx . drawImage ( frame , 0 , 0 ) ;
297
+ __ctx . drawImage ( __frame , 0 , 0 ) ;
280
298
} finally {
281
299
__ctx . restore ( ) ;
282
300
}
283
301
}
284
-
285
302
__fps_accum += 1 ;
286
303
} finally {
304
+ __closeFrame ( __frame ) ;
305
+ __frame = null ;
306
+ }
307
+ } ;
308
+
309
+ var __closeFrame = function ( frame ) {
310
+ if ( ! tools . browser . is_firefox ) {
311
+ // FIXME: On Firefox, image is flickering when we're closing the frame for some reason.
312
+ // So we're just not performing the close() and it seems there is no problems here
313
+ // because Firefox is implementing some auto-closing logic. With auto-close,
314
+ // no flickering observed.
315
+ // - https://github.com/mozilla/gecko-dev/blob/82333a9/dom/media/webcodecs/VideoFrame.cpp
316
+ // Note at 2025.05.13:
317
+ // - The problem is not observed on nightly Firefox 140.
318
+ // - It's also not observed with hardware accelleration on 138.
287
319
frame . close ( ) ;
288
320
}
289
321
} ;
0 commit comments