Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit c7549ad6 authored by Simon Chan's avatar Simon Chan
Browse files

feat(webcodecs): change to a faster render method

parent 48557f62
Loading
Loading
Loading
Loading
+39 −19
Original line number Original line Diff line number Diff line
@@ -68,7 +68,7 @@ export class WebCodecsDecoder implements ScrcpyVideoDecoder {
        return this.#sizeChanged.event;
        return this.#sizeChanged.event;
    }
    }


    #context: CanvasRenderingContext2D;
    #context: ImageBitmapRenderingContext;
    #decoder: VideoDecoder;
    #decoder: VideoDecoder;
    #config: Uint8Array | undefined;
    #config: Uint8Array | undefined;


@@ -80,15 +80,19 @@ export class WebCodecsDecoder implements ScrcpyVideoDecoder {


        this.#renderer = document.createElement("canvas");
        this.#renderer = document.createElement("canvas");


        this.#context = this.#renderer.getContext("2d")!;
        this.#context = this.#renderer.getContext("bitmaprenderer", {
            alpha: false,
        })!;
        this.#decoder = new VideoDecoder({
        this.#decoder = new VideoDecoder({
            output: (frame) => {
            output: (frame) => {
                createImageBitmap(frame)
                    .then((bitmap) => {
                        if (this.#currentFrameRendered) {
                        if (this.#currentFrameRendered) {
                    this.#frameSkipped += 1;
                } else {
                    this.#currentFrameRendered = true;
                            this.#frameRendered += 1;
                            this.#frameRendered += 1;
                        } else {
                            this.#frameSkipped += 1;
                        }
                        }
                        this.#currentFrameRendered = false;


                        // PERF: H.264 renderer may draw multiple frames in one vertical sync interval to minimize latency.
                        // PERF: H.264 renderer may draw multiple frames in one vertical sync interval to minimize latency.
                        // When multiple frames are drawn in one vertical sync interval,
                        // When multiple frames are drawn in one vertical sync interval,
@@ -96,11 +100,23 @@ export class WebCodecsDecoder implements ScrcpyVideoDecoder {
                        // But this ensures users can always see the most up-to-date screen.
                        // But this ensures users can always see the most up-to-date screen.
                        // This is also the behavior of official Scrcpy client.
                        // This is also the behavior of official Scrcpy client.
                        // https://github.com/Genymobile/scrcpy/issues/3679
                        // https://github.com/Genymobile/scrcpy/issues/3679
                this.#context.drawImage(frame, 0, 0);
                        this.#context.transferFromImageBitmap(bitmap);
                        frame.close();
                        frame.close();
                    })
                    .catch((e) => {
                        console.warn(
                            "[@yume-chan/scrcpy-decoder-webcodecs]",
                            "createImageBitmap error",
                            e,
                        );
                    });
            },
            },
            error(e) {
            error(e) {
                void e;
                console.warn(
                    "[@yume-chan/scrcpy-decoder-webcodecs]",
                    "VideoDecoder error",
                    e,
                );
            },
            },
        });
        });


@@ -121,7 +137,7 @@ export class WebCodecsDecoder implements ScrcpyVideoDecoder {
    }
    }


    #onFramePresented = () => {
    #onFramePresented = () => {
        this.#currentFrameRendered = false;
        this.#currentFrameRendered = true;
        this.#animationFrameId = requestAnimationFrame(this.#onFramePresented);
        this.#animationFrameId = requestAnimationFrame(this.#onFramePresented);
    };
    };


@@ -168,6 +184,10 @@ export class WebCodecsDecoder implements ScrcpyVideoDecoder {


                this.#renderer.width = croppedWidth;
                this.#renderer.width = croppedWidth;
                this.#renderer.height = croppedHeight;
                this.#renderer.height = croppedHeight;
                this.#sizeChanged.fire({
                    width: croppedWidth,
                    height: croppedHeight,
                });


                const codec = [
                const codec = [
                    "hev1",
                    "hev1",