mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
9d0af06811
commit
7ea22fe889
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue