diff options
Diffstat (limited to 'audio/decode/ad_lavc.c')
-rw-r--r-- | audio/decode/ad_lavc.c | 87 |
1 files changed, 42 insertions, 45 deletions
diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index c4d3a2ae7b..7f3abfd612 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -45,7 +45,6 @@ struct priv { uint32_t skip_samples, trim_samples; bool preroll_done; double next_pts; - bool needs_reset; AVRational codec_timebase; }; @@ -116,26 +115,18 @@ static int init(struct dec_audio *da, const char *decoder) av_opt_set_double(lavc_context, "drc_scale", opts->ac3drc, AV_OPT_SEARCH_CHILDREN); -#if HAVE_AVFRAME_SKIP_SAMPLES +#if LIBAVCODEC_VERSION_MICRO >= 100 // Let decoder add AV_FRAME_DATA_SKIP_SAMPLES. av_opt_set(lavc_context, "flags2", "+skip_manual", AV_OPT_SEARCH_CHILDREN); #endif mp_set_avopts(da->log, lavc_context, opts->avopts); - lavc_context->codec_tag = c->codec_tag; - lavc_context->sample_rate = c->samplerate; - lavc_context->bit_rate = c->bitrate; - lavc_context->block_align = c->block_align; - lavc_context->bits_per_coded_sample = c->bits_per_coded_sample; - lavc_context->channels = c->channels.num; - if (!mp_chmap_is_unknown(&c->channels)) - lavc_context->channel_layout = mp_chmap_to_lavc(&c->channels); - - // demux_mkv - mp_lavc_set_extradata(lavc_context, c->extradata, c->extradata_size); - - mp_set_lav_codec_headers(lavc_context, c); + if (mp_set_avctx_codec_headers(lavc_context, c) < 0) { + MP_ERR(da, "Could not set decoder parameters.\n"); + uninit(da); + return 0; + } mp_set_avcodec_threads(da->log, lavc_context, opts->threads); @@ -177,14 +168,12 @@ 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; } -static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, - struct mp_audio **out) +static bool send_packet(struct dec_audio *da, struct demux_packet *mpkt) { struct priv *priv = da->priv; AVCodecContext *avctx = priv->avctx; @@ -195,41 +184,48 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, if (mpkt && priv->next_pts == MP_NOPTS_VALUE) priv->next_pts = mpkt->pts; - int in_len = mpkt ? mpkt->len : 0; - AVPacket pkt; mp_set_av_packet(&pkt, mpkt, &priv->codec_timebase); - int got_frame = 0; - av_frame_unref(priv->avframe); + int ret = avcodec_send_packet(avctx, mpkt ? &pkt : NULL); - if (priv->needs_reset) - control(da, ADCTRL_RESET, NULL); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return false; - int ret = avcodec_send_packet(avctx, &pkt); - if (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { - if (ret >= 0 && mpkt) - mpkt->len = 0; - 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; - } - if (ret < 0) { + if (ret < 0) + MP_ERR(da, "Error decoding audio.\n"); + return true; +} + +static bool receive_frame(struct dec_audio *da, struct mp_audio **out) +{ + struct priv *priv = da->priv; + AVCodecContext *avctx = priv->avctx; + + int ret = avcodec_receive_frame(avctx, priv->avframe); + + if (ret == AVERROR_EOF) { + // If flushing was initialized earlier and has ended now, make it start + // over in case we get new packets at some point in the future. + control(da, ADCTRL_RESET, NULL); + return false; + } else if (ret < 0 && ret != AVERROR(EAGAIN)) { MP_ERR(da, "Error decoding audio.\n"); - return -1; } - if (!got_frame) - return 0; + +#if LIBAVCODEC_VERSION_MICRO >= 100 + if (priv->avframe->flags & AV_FRAME_FLAG_DISCARD) + av_frame_unref(priv->avframe); +#endif + + if (!priv->avframe->buf[0]) + return true; double out_pts = mp_pts_from_av(priv->avframe->pts, &priv->codec_timebase); struct mp_audio *mpframe = mp_audio_from_avframe(priv->avframe); if (!mpframe) - return -1; + return true; struct mp_chmap lavc_chmap = mpframe->channels; if (lavc_chmap.num != avctx->channels) @@ -247,7 +243,7 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, if (mpframe->pts != MP_NOPTS_VALUE) priv->next_pts = mpframe->pts + mpframe->samples / (double)mpframe->rate; -#if HAVE_AVFRAME_SKIP_SAMPLES +#if LIBAVCODEC_VERSION_MICRO >= 100 AVFrameSideData *sd = av_frame_get_side_data(priv->avframe, AV_FRAME_DATA_SKIP_SAMPLES); if (sd && sd->size >= 10) { @@ -279,8 +275,8 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, av_frame_unref(priv->avframe); - MP_DBG(da, "Decoded %d -> %d samples\n", in_len, mpframe->samples); - return 0; + MP_DBG(da, "Decoded %d samples\n", mpframe->samples); + return true; } static void add_decoders(struct mp_decoder_list *list) @@ -294,5 +290,6 @@ const struct ad_functions ad_lavc = { .init = init, .uninit = uninit, .control = control, - .decode_packet = decode_packet, + .send_packet = send_packet, + .receive_frame = receive_frame, }; |