From e415089a1bf431dad44b92f0ec140077ef336692 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Mon, 16 Oct 2023 16:04:25 +0200 Subject: [PATCH] Bug showcase: decode video frames in reverse order --- src/video-element.ts | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/video-element.ts b/src/video-element.ts index c02dcd2..f2d5f54 100644 --- a/src/video-element.ts +++ b/src/video-element.ts @@ -53,6 +53,9 @@ const decodeQueueHwm = 30; const DEBUG = false; +// Bug showcases +const BUG_DECODE_VIDEO_IN_REVERSE = false; + export class BabyVideoElement extends HTMLElement { readonly #canvas: HTMLCanvasElement; readonly #canvasContext: CanvasRenderingContext2D; @@ -89,6 +92,7 @@ export class BabyVideoElement extends HTMLElement { #nextDecodedVideoFramePromise: Deferred | undefined = undefined; #lastRenderedFrame: number | undefined = undefined; #nextRenderFrame: number = 0; + #needKeyFrame: boolean = true; readonly #audioDecoder: AudioDecoder; #lastAudioDecoderConfig: AudioDecoderConfig | undefined = undefined; @@ -711,17 +715,31 @@ export class BabyVideoElement extends HTMLElement { ) { this.#videoDecoder.configure(codecConfig); this.#lastVideoDecoderConfig = codecConfig; + this.#needKeyFrame = true; + } + if (BUG_DECODE_VIDEO_IN_REVERSE) { + frames.reverse(); + } + if (this.#needKeyFrame) { + // Remove non-keyframes + const firstKeyFrame = frames.findIndex((x) => x.type === "key"); + if (firstKeyFrame > 0) { + frames.splice(0, firstKeyFrame); + } } for (const frame of frames) { + if (this.#needKeyFrame && frame.type === "key") { + this.#needKeyFrame = false; + } this.#videoDecoder.decode(frame); this.#decodingVideoFrames.push(frame); } // The "furthest decoded frame" depends on the rendering order, // since we must decode the frames in their original order. - if (direction == Direction.FORWARD) { - this.#furthestDecodingVideoFrame = frames[frames.length - 1]; - } else { + if (direction === Direction.BACKWARD && !BUG_DECODE_VIDEO_IN_REVERSE) { this.#furthestDecodingVideoFrame = frames[0]; + } else { + this.#furthestDecodingVideoFrame = frames[frames.length - 1]; } } @@ -847,6 +865,7 @@ export class BabyVideoElement extends HTMLElement { this.#lastRenderedFrame = undefined; this.#decodingVideoFrames.length = 0; this.#decodedVideoFrames.length = 0; + this.#needKeyFrame = true; this.#videoDecoder.reset(); }