From 7ae7543de287dbdf0dca24321dc014849bb775f6 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Tue, 28 Feb 2023 21:20:28 +0100 Subject: [PATCH] Call avcodec_receive_frame() in a loop Since in scrcpy a video packet passed to avcodec_send_packet() is always a complete video frame, it is sufficient to call avcodec_receive_frame() exactly once. In practice, it also works for audio packets: the decoder produces exactly 1 frame for 1 input packet. In theory, it is an implementation detail though, so avcodec_receive_frame() should be called in a loop. --- app/src/decoder.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/app/src/decoder.c b/app/src/decoder.c index 33acc0da..a4e70418 100644 --- a/app/src/decoder.c +++ b/app/src/decoder.c @@ -121,8 +121,19 @@ sc_decoder_push(struct sc_decoder *decoder, const AVPacket *packet) { decoder->name, ret); return false; } - ret = avcodec_receive_frame(decoder->codec_ctx, decoder->frame); - if (!ret) { + + for (;;) { + ret = avcodec_receive_frame(decoder->codec_ctx, decoder->frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + break; + } + + if (ret) { + LOGE("Decoder '%s', could not receive video frame: %d", + decoder->name, ret); + return false; + } + // a frame was received bool ok = push_frame_to_sinks(decoder, decoder->frame); // A frame lost should not make the whole pipeline fail. The error, if @@ -130,11 +141,8 @@ sc_decoder_push(struct sc_decoder *decoder, const AVPacket *packet) { (void) ok; av_frame_unref(decoder->frame); - } else if (ret != AVERROR(EAGAIN)) { - LOGE("Decoder '%s', could not receive video frame: %d", - decoder->name, ret); - return false; } + return true; }