Makes sure discarded frames do not cause EAGAIN to be returned during flushing, which is forbidden.
Showing the changes to libavcodec (1 of 1 file). Show all
Unified · Split
| @@ -613,17 +613,22 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) · 612 unmodified lines | ||
| 613 | 613 | av_assert0(!frame->buf[0]); |
| 614 | 614 | |
| 615 | 615 | if (codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME) { |
| 616 | + while (1) { | |
| 616 | 617 | frame->pict_type = dc->initial_pict_type; |
| 617 | 618 | frame->flags |= dc->intra_only_flag; |
| 618 | 619 | ret = codec->cb.receive_frame(avctx, frame); |
| 619 | 620 | emms_c(); |
| 620 | 621 | if (!ret) { |
| 621 | − if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) | |
| 622 | − ret = (frame->flags & AV_FRAME_FLAG_DISCARD) ? AVERROR(EAGAIN) : 0; | |
| 623 | − else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { | |
| 622 | + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { | |
| 624 | 623 | int64_t discarded_samples = 0; |
| 625 | 624 | ret = discard_samples(avctx, frame, &discarded_samples); |
| 626 | 625 | } |
| 626 | + if (ret == AVERROR(EAGAIN) || (frame->flags & AV_FRAME_FLAG_DISCARD)) { | |
| 627 | + av_frame_unref(frame); | |
| 628 | + continue; | |
| 629 | + } | |
| 630 | + } | |
| 631 | + break; | |
| 627 | 632 | } |
| 628 | 633 | } else |
| 629 | 634 | ret = decode_simple_receive_frame(avctx, frame); |