refactor: clean up size change handling

This commit is contained in:
Simon Chan 2024-05-10 08:28:49 +08:00
parent c8090fbbfd
commit 2dd9307859
No known key found for this signature in database
GPG key ID: A8B69F750B9BCEDD

View file

@ -111,24 +111,13 @@ export class WebCodecsVideoDecoder implements ScrcpyVideoDecoder {
} }
this.#currentFrameRendered = false; this.#currentFrameRendered = false;
if (
frame.displayWidth !== this.#canvas.width ||
frame.displayHeight !== this.#canvas.height
) {
this.#canvas.width = frame.displayWidth;
this.#canvas.height = frame.displayHeight;
this.#sizeChanged.fire({
width: frame.displayWidth,
height: frame.displayHeight,
});
}
// 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,
// only the last one is visible to users. // only the last one is visible to users.
// 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.#updateSize(frame.displayWidth, frame.displayHeight);
this.#renderer.draw(frame); this.#renderer.draw(frame);
}, },
error(e) { error(e) {
@ -164,7 +153,7 @@ export class WebCodecsVideoDecoder implements ScrcpyVideoDecoder {
this.#configureAv1(packet.data); this.#configureAv1(packet.data);
this.#decoder.decode( this.#decoder.decode(
new EncodedVideoChunk({ new EncodedVideoChunk({
// Treat `undefined` as `key`, otherwise won't decode. // Treat `undefined` as `key`, otherwise it won't decode.
type: packet.keyframe === false ? "delta" : "key", type: packet.keyframe === false ? "delta" : "key",
timestamp: 0, timestamp: 0,
data: packet.data, data: packet.data,
@ -187,6 +176,17 @@ export class WebCodecsVideoDecoder implements ScrcpyVideoDecoder {
this.#onFramePresented(); this.#onFramePresented();
} }
#updateSize(width: number, height: number) {
if (width !== this.#canvas.width || height !== this.#canvas.height) {
this.#canvas.width = width;
this.#canvas.height = height;
this.#sizeChanged.fire({
width: width,
height: height,
});
}
}
#onFramePresented = () => { #onFramePresented = () => {
this.#currentFrameRendered = true; this.#currentFrameRendered = true;
this.#animationFrameId = requestAnimationFrame(this.#onFramePresented); this.#animationFrameId = requestAnimationFrame(this.#onFramePresented);
@ -201,12 +201,7 @@ export class WebCodecsVideoDecoder implements ScrcpyVideoDecoder {
croppedHeight, croppedHeight,
} = h264ParseConfiguration(data); } = h264ParseConfiguration(data);
this.#canvas.width = croppedWidth; this.#updateSize(croppedWidth, croppedHeight);
this.#canvas.height = croppedHeight;
this.#sizeChanged.fire({
width: croppedWidth,
height: croppedHeight,
});
// https://www.rfc-editor.org/rfc/rfc6381#section-3.3 // https://www.rfc-editor.org/rfc/rfc6381#section-3.3
// ISO Base Media File Format Name Space // ISO Base Media File Format Name Space
@ -233,12 +228,7 @@ export class WebCodecsVideoDecoder implements ScrcpyVideoDecoder {
croppedHeight, croppedHeight,
} = h265ParseConfiguration(data); } = h265ParseConfiguration(data);
this.#canvas.width = croppedWidth; this.#updateSize(croppedWidth, croppedHeight);
this.#canvas.height = croppedHeight;
this.#sizeChanged.fire({
width: croppedWidth,
height: croppedHeight,
});
const codec = [ const codec = [
"hev1", "hev1",
@ -298,9 +288,7 @@ export class WebCodecsVideoDecoder implements ScrcpyVideoDecoder {
const width = max_frame_width_minus_1 + 1; const width = max_frame_width_minus_1 + 1;
const height = max_frame_height_minus_1 + 1; const height = max_frame_height_minus_1 + 1;
this.#canvas.width = width; this.#updateSize(width, height);
this.#canvas.height = height;
this.#sizeChanged.fire({ width, height });
const codec = [ const codec = [
"av01", "av01",