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.
This commit is contained in:
parent
c1528cdca9
commit
6e05d7047a
1 changed files with 14 additions and 6 deletions
|
@ -110,8 +110,19 @@ sc_decoder_push(struct sc_decoder *decoder, const AVPacket *packet) {
|
||||||
decoder->name, ret);
|
decoder->name, ret);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
ret = avcodec_receive_frame(decoder->codec_ctx, decoder->frame);
|
ret = avcodec_receive_frame(decoder->codec_ctx, decoder->frame);
|
||||||
if (!ret) {
|
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
|
// a frame was received
|
||||||
bool ok = push_frame_to_sinks(decoder, decoder->frame);
|
bool ok = push_frame_to_sinks(decoder, decoder->frame);
|
||||||
// A frame lost should not make the whole pipeline fail. The error, if
|
// A frame lost should not make the whole pipeline fail. The error, if
|
||||||
|
@ -119,11 +130,8 @@ sc_decoder_push(struct sc_decoder *decoder, const AVPacket *packet) {
|
||||||
(void) ok;
|
(void) ok;
|
||||||
|
|
||||||
av_frame_unref(decoder->frame);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue