mirror of
https://github.com/yume-chan/ya-webadb.git
synced 2025-10-03 17:59:50 +02:00
feat(decoder): disable VSync
This commit is contained in:
parent
7d1f271cdb
commit
849cb0c7fc
1 changed files with 20 additions and 20 deletions
|
@ -37,9 +37,8 @@ export class WebCodecsDecoder {
|
||||||
private context: CanvasRenderingContext2D;
|
private context: CanvasRenderingContext2D;
|
||||||
private decoder: VideoDecoder;
|
private decoder: VideoDecoder;
|
||||||
|
|
||||||
// Limit FPS to system refresh rate
|
private currentFrameRendered = false;
|
||||||
private lastFrame: VideoFrame | undefined;
|
private animationFrameId = 0;
|
||||||
private animationFrame = 0;
|
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
this._renderer = document.createElement("canvas");
|
this._renderer = document.createElement("canvas");
|
||||||
|
@ -47,16 +46,21 @@ export class WebCodecsDecoder {
|
||||||
this.context = this._renderer.getContext("2d")!;
|
this.context = this._renderer.getContext("2d")!;
|
||||||
this.decoder = new VideoDecoder({
|
this.decoder = new VideoDecoder({
|
||||||
output: (frame) => {
|
output: (frame) => {
|
||||||
if (this.lastFrame) {
|
if (this.currentFrameRendered) {
|
||||||
this._frameSkipped += 1;
|
this._frameSkipped += 1;
|
||||||
this.lastFrame.close();
|
} else {
|
||||||
|
this.currentFrameRendered = true;
|
||||||
|
this._frameRendered += 1;
|
||||||
}
|
}
|
||||||
this.lastFrame = frame;
|
|
||||||
|
|
||||||
if (!this.animationFrame) {
|
// PERF: H.264 renderer may draw multiple frames in one vertical sync interval to minimize latency.
|
||||||
// Start render loop on first frame
|
// When multiple frames are drawn in one vertical sync interval,
|
||||||
this.render();
|
// only the last one is visible to users.
|
||||||
}
|
// But this ensures users can always see the most up-to-date screen.
|
||||||
|
// This is also the behavior of official Scrcpy client.
|
||||||
|
// https://github.com/Genymobile/scrcpy/issues/3679
|
||||||
|
this.context.drawImage(frame, 0, 0);
|
||||||
|
frame.close();
|
||||||
},
|
},
|
||||||
error(e) {
|
error(e) {
|
||||||
void e;
|
void e;
|
||||||
|
@ -83,17 +87,13 @@ export class WebCodecsDecoder {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.onFramePresented();
|
||||||
}
|
}
|
||||||
|
|
||||||
private render = () => {
|
private onFramePresented = () => {
|
||||||
if (this.lastFrame) {
|
this.currentFrameRendered = false;
|
||||||
this._frameRendered += 1;
|
this.animationFrameId = requestAnimationFrame(this.onFramePresented);
|
||||||
this.context.drawImage(this.lastFrame, 0, 0);
|
|
||||||
this.lastFrame.close();
|
|
||||||
this.lastFrame = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.animationFrame = requestAnimationFrame(this.render);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private configure(config: H264Configuration) {
|
private configure(config: H264Configuration) {
|
||||||
|
@ -114,7 +114,7 @@ export class WebCodecsDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose() {
|
public dispose() {
|
||||||
cancelAnimationFrame(this.animationFrame);
|
cancelAnimationFrame(this.animationFrameId);
|
||||||
this.decoder.close();
|
this.decoder.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue