From 4300bfd5180b7d287d93b04d8e600f34886e0c53 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 24 Mar 2016 17:53:30 +0100 Subject: ad_lavc, vd_lavc: support new Libav decoding API For now only found in Libav. --- audio/decode/ad_lavc.c | 14 ++++++++++++++ video/decode/vd_lavc.c | 21 ++++++++++++++++++--- wscript | 6 ++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index 0c61c03986..c5e6b09cd4 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -192,6 +192,19 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, int got_frame = 0; av_frame_unref(priv->avframe); + +#if HAVE_AVCODEC_NEW_CODEC_API + 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(EAGAIN) || ret == AVERROR_EOF) + ret = 0; + } +#else int ret = avcodec_decode_audio4(avctx, priv->avframe, &got_frame, &pkt); if (mpkt) { // At least "shorten" decodes sub-frames, instead of the whole packet. @@ -208,6 +221,7 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, return 0; } } +#endif if (ret < 0) { MP_ERR(da, "Error decoding audio.\n"); return -1; diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 56633c0227..9559e0800f 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -646,6 +646,7 @@ static void decode(struct dec_video *vd, struct demux_packet *packet, vd_ffmpeg_ctx *ctx = vd->priv; AVCodecContext *avctx = ctx->avctx; struct vd_lavc_params *opts = ctx->opts->vd_lavc_params; + bool consumed = false; AVPacket pkt; if (!avctx) @@ -667,7 +668,23 @@ static void decode(struct dec_video *vd, struct demux_packet *packet, reset_avctx(vd); hwdec_lock(ctx); +#if HAVE_AVCODEC_NEW_CODEC_API + ret = avcodec_send_packet(avctx, packet ? &pkt : NULL); + if (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + if (ret >= 0) + consumed = true; + ret = avcodec_receive_frame(avctx, ctx->pic); + if (ret >= 0) + got_picture = 1; + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + ret = 0; + } else { + consumed = true; + } +#else ret = avcodec_decode_video2(avctx, ctx->pic, &got_picture, &pkt); + consumed = true; +#endif hwdec_unlock(ctx); // Reset decoder if it was fully flushed. Caller might send more flush @@ -692,10 +709,8 @@ static void decode(struct dec_video *vd, struct demux_packet *packet, return; } - if (packet) { - // always fully consumed + if (packet && consumed) packet->len = 0; - } // Skipped frame, or delayed output due to multithreaded decoding. if (!got_picture) { diff --git a/wscript b/wscript index 13d739e221..7d09a7ddbf 100644 --- a/wscript +++ b/wscript @@ -484,6 +484,12 @@ FFmpeg/Libav libraries. You need at least {0}. Aborting.".format(libav_versions_ 'func': check_statement('libavcodec/avcodec.h', 'avcodec_profile_name(0,0)', use='libav'), + }, { + 'name': 'avcodec-new-codec-api', + 'desc': 'new libavcodec decode/encode API', + 'func': check_statement('libavcodec/avcodec.h', + 'avcodec_send_packet(0,0)', + use='libav'), }, ] -- cgit v1.2.3