From: Anton Khirnov Date: Mon, 9 May 2016 19:40:08 +0000 (+0200) Subject: lavc: allow using AVCodecContext.hw_frames_ctx for decoding X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=e85f6f7f8d037c0af0f294000718d9ba22753baa;p=ffmpeg lavc: allow using AVCodecContext.hw_frames_ctx for decoding For now it will only be used by the default get_buffer2 callback for allocating hw frames. --- diff --git a/doc/APIchanges b/doc/APIchanges index de0213f80e2..e251490944d 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavc 57.23.0 - avcodec.h + AVCodecContext.hw_frames_ctx now may be used by decoders. + 2016-xx-xx - xxxxxxx - lavc 57.20.0 - avcodec.h Add FF_PROFILE_H264_MULTIVIEW_HIGH and FF_PROFILE_H264_STEREO_HIGH. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index c4bf708e3b4..ace761dd569 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3078,15 +3078,25 @@ typedef struct AVCodecContext { int nb_coded_side_data; /** - * Encoding only. + * A reference to the AVHWFramesContext describing the input (for encoding) + * or output (decoding) frames. The reference is set by the caller and + * afterwards owned (and freed) by libavcodec. * - * For hardware encoders configured to use a hwaccel pixel format, this - * field should be set by the caller to a reference to the AVHWFramesContext - * describing input frames. AVHWFramesContext.format must be equal to - * AVCodecContext.pix_fmt. + * - decoding: This field should be set by the caller from the get_format() + * callback. The previous reference (if any) will always be + * unreffed by libavcodec before the get_format() call. * - * This field should be set before avcodec_open2() is called and is - * afterwards owned and managed by libavcodec. + * If the default get_buffer2() is used with a hwaccel pixel + * format, then this AVHWFramesContext will be used for + * allocating the frame buffers. + * + * - encoding: For hardware encoders configured to use a hwaccel pixel + * format, this field should be set by the caller to a reference + * to the AVHWFramesContext describing input frames. + * AVHWFramesContext.format must be equal to + * AVCodecContext.pix_fmt. + * + * This field should be set before avcodec_open2() is called. */ AVBufferRef *hw_frames_ctx; } AVCodecContext; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index a0352b80a0d..8f8efecbeaa 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -513,6 +513,9 @@ int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags { int ret; + if (avctx->hw_frames_ctx) + return av_hwframe_get_buffer(avctx->hw_frames_ctx, frame, 0); + if ((ret = update_frame_pool(avctx, frame)) < 0) return ret; @@ -793,6 +796,8 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) av_freep(&avctx->internal->hwaccel_priv_data); avctx->hwaccel = NULL; + av_buffer_unref(&avctx->hw_frames_ctx); + ret = avctx->get_format(avctx, choices); desc = av_pix_fmt_desc_get(ret); @@ -804,6 +809,16 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) break; + if (avctx->hw_frames_ctx) { + AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + if (hw_frames_ctx->format != ret) { + av_log(avctx, AV_LOG_ERROR, "Format returned from get_buffer() " + "does not match the format of provided AVHWFramesContext\n"); + ret = AV_PIX_FMT_NONE; + break; + } + } + if (!setup_hwaccel(avctx, ret, desc->name)) break; diff --git a/libavcodec/version.h b/libavcodec/version.h index 78f4214d289..9b495e9a44b 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 22 -#define LIBAVCODEC_VERSION_MICRO 2 +#define LIBAVCODEC_VERSION_MINOR 23 +#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \