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 | av_assert0(!frame->buf[0]); | 613 | av_assert0(!frame->buf[0]); |
| 614 | 614 | ||
| 615 | if (codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME) { | 615 | if (codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME) { |
| 616 | while (1) { | ||
| 616 | frame->pict_type = dc->initial_pict_type; | 617 | frame->pict_type = dc->initial_pict_type; |
| 617 | frame->flags |= dc->intra_only_flag; | 618 | frame->flags |= dc->intra_only_flag; |
| 618 | ret = codec->cb.receive_frame(avctx, frame); | 619 | ret = codec->cb.receive_frame(avctx, frame); |
| 619 | emms_c(); | 620 | emms_c(); |
| 620 | if (!ret) { | 621 | if (!ret) { |
| 621 | if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) | 622 | if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { |
| 622 | ret = (frame->flags & AV_FRAME_FLAG_DISCARD) ? AVERROR(EAGAIN) : 0; | ||
| 623 | else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { | ||
| 624 | int64_t discarded_samples = 0; | 623 | int64_t discarded_samples = 0; |
| 625 | ret = discard_samples(avctx, frame, &discarded_samples); | 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 | } else | 633 | } else |
| 629 | ret = decode_simple_receive_frame(avctx, frame); | 634 | ret = decode_simple_receive_frame(avctx, frame); |