feat(scrcpy-decoder): record skipped frame count

This commit is contained in:
Simon Chan 2023-01-10 16:00:16 +08:00
parent 0df4c85ab1
commit b73737742c
No known key found for this signature in database
GPG key ID: A8B69F750B9BCEDD
6 changed files with 30 additions and 5 deletions

View file

@ -5,6 +5,7 @@
"allowlist", "allowlist",
"arraybuffer", "arraybuffer",
"autorun", "autorun",
"Bframes",
"brotli", "brotli",
"Callout", "Callout",
"Cascadia", "Cascadia",

View file

@ -184,6 +184,7 @@ export interface H264Decoder extends Disposable {
readonly renderer: HTMLElement; readonly renderer: HTMLElement;
readonly frameRendered: number; readonly frameRendered: number;
readonly frameSkipped: number;
readonly writable: WritableStream<ScrcpyVideoStreamPacket>; readonly writable: WritableStream<ScrcpyVideoStreamPacket>;
} }

View file

@ -67,7 +67,7 @@ export class ScrcpyPageState {
decoder: H264Decoder | undefined = undefined; decoder: H264Decoder | undefined = undefined;
configuration: ScrcpyVideoStreamConfigurationPacket | undefined = undefined; configuration: ScrcpyVideoStreamConfigurationPacket | undefined = undefined;
fpsCounterIntervalId: any = undefined; fpsCounterIntervalId: any = undefined;
fps = 0; fps = "0";
connecting = false; connecting = false;
serverTotalSize = 0; serverTotalSize = 0;
@ -199,11 +199,22 @@ export class ScrcpyPageState {
runInAction(() => { runInAction(() => {
this.decoder = decoder; this.decoder = decoder;
let lastFrameCount = 0; let lastFrameRendered = 0;
let lastFrameSkipped = 0;
this.fpsCounterIntervalId = setInterval( this.fpsCounterIntervalId = setInterval(
action(() => { action(() => {
this.fps = decoder.frameRendered - lastFrameCount; const deltaRendered =
lastFrameCount = decoder.frameRendered; decoder.frameRendered - lastFrameRendered;
const deltaSkipped =
decoder.frameSkipped - lastFrameSkipped;
// prettier-ignore
this.fps = `${
deltaRendered
}${
deltaSkipped ? `+${deltaSkipped} skipped` : ""
}`;
lastFrameRendered = decoder.frameRendered;
lastFrameSkipped = decoder.frameSkipped;
}), }),
1000 1000
); );
@ -328,7 +339,7 @@ export class ScrcpyPageState {
RECORD_STATE.recording = false; RECORD_STATE.recording = false;
} }
this.fps = 0; this.fps = "0";
clearTimeout(this.fpsCounterIntervalId); clearTimeout(this.fpsCounterIntervalId);
this.client = undefined; this.client = undefined;

View file

@ -43,6 +43,11 @@ export class TinyH264Decoder {
return this._frameRendered; return this._frameRendered;
} }
private _frameSkipped = 0;
public get frameSkipped() {
return this._frameSkipped;
}
private _writable: WritableStream<ScrcpyVideoStreamPacket>; private _writable: WritableStream<ScrcpyVideoStreamPacket>;
public get writable() { public get writable() {
return this._writable; return this._writable;

View file

@ -29,6 +29,11 @@ export class WebCodecsDecoder {
return this._frameRendered; return this._frameRendered;
} }
private _frameSkipped = 0;
public get frameSkipped() {
return this._frameSkipped;
}
private context: CanvasRenderingContext2D; private context: CanvasRenderingContext2D;
private decoder: VideoDecoder; private decoder: VideoDecoder;
@ -43,6 +48,7 @@ export class WebCodecsDecoder {
this.decoder = new VideoDecoder({ this.decoder = new VideoDecoder({
output: (frame) => { output: (frame) => {
if (this.lastFrame) { if (this.lastFrame) {
this._frameSkipped += 1;
this.lastFrame.close(); this.lastFrame.close();
} }
this.lastFrame = frame; this.lastFrame = frame;

View file

@ -13,6 +13,7 @@ export interface CodecOptionsInit {
level: AndroidCodecLevel; level: AndroidCodecLevel;
iFrameInterval: number; iFrameInterval: number;
maxBframes: number;
repeatPreviousFrameAfter: number; repeatPreviousFrameAfter: number;
maxPtsGapToEncoder: number; maxPtsGapToEncoder: number;
} }