diff options
author | wm4 <wm4@nowhere> | 2016-06-22 21:37:36 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-06-22 21:37:36 +0200 |
commit | 7ea22fe889fececeb653daa5f957ae600d7bb616 (patch) | |
tree | f67c9c1ec8d1fdaf7782e45be111ddc4149fff53 /audio | |
parent | 9d0af0681191823608d9bbc290f5f30fc60e228e (diff) | |
download | mpv-7ea22fe889fececeb653daa5f957ae600d7bb616.tar.bz2 mpv-7ea22fe889fececeb653daa5f957ae600d7bb616.tar.xz |
ad_lavc: resume from mid-stream EOF conditions with new decode API
Workaround for an awful corner-case. The new decode API "locks" the
decoder into the EOF state once a drain packet has been sent. The
problem starts with a file containing a 0-sized packet, which is
interpreted as drain packet.
This should probably be changed in libavcodec (not treating 0-sized
packets as drain packets with the new API) or in libavformat (discard
0-sized packets as invalid), but efforts to do so have been fruitless.
Note that vd_lavc.c already does something similar, but originally for
other reasons.
Fixes #3106.
Diffstat (limited to 'audio')
-rw-r--r-- | audio/decode/ad_lavc.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index 8a6bb4061b..f48993f81f 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -45,6 +45,7 @@ struct priv { uint32_t skip_samples, trim_samples; bool preroll_done; double next_pts; + bool needs_reset; AVRational codec_timebase; }; @@ -173,6 +174,7 @@ static int control(struct dec_audio *da, int cmd, void *arg) ctx->trim_samples = 0; ctx->preroll_done = false; ctx->next_pts = MP_NOPTS_VALUE; + ctx->needs_reset = false; return CONTROL_TRUE; } return CONTROL_UNKNOWN; @@ -192,6 +194,9 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, int got_frame = 0; av_frame_unref(priv->avframe); + if (priv->needs_reset) + control(da, ADCTRL_RESET, NULL); + #if HAVE_AVCODEC_NEW_CODEC_API int ret = avcodec_send_packet(avctx, &pkt); if (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { @@ -200,6 +205,8 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, ret = avcodec_receive_frame(avctx, priv->avframe); if (ret >= 0) got_frame = 1; + if (ret == AVERROR_EOF) + priv->needs_reset = true; if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) ret = 0; } |