summaryrefslogtreecommitdiffstats
path: root/libavcodec/decode.c
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2017-11-11 18:58:12 -0300
committerJames Almer <jamrial@gmail.com>2017-11-11 20:33:26 -0300
commit48e4eda11d537c6ed52d1000aaa6ce5cbb641e25 (patch)
treea47751225502234d83afae7bee047f213ff6cf58 /libavcodec/decode.c
parentb125822d1d07e305c0012ef67b8be0cb9261ee9f (diff)
parentb46a77f19ddc4b2b5fa3187835ceb602a5244e24 (diff)
downloadffmpeg-streaming-48e4eda11d537c6ed52d1000aaa6ce5cbb641e25.zip
ffmpeg-streaming-48e4eda11d537c6ed52d1000aaa6ce5cbb641e25.tar.gz
Merge commit 'b46a77f19ddc4b2b5fa3187835ceb602a5244e24'
* commit 'b46a77f19ddc4b2b5fa3187835ceb602a5244e24': lavc: external hardware frame pool initialization Includes the fix from e724bdfffbd3c27aac53d1f32f20f105f37caef0 Merged-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec/decode.c')
-rw-r--r--libavcodec/decode.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 7601d16..a7f1e23 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1106,6 +1106,86 @@ static AVHWAccel *find_hwaccel(AVCodecContext *avctx,
return NULL;
}
+int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
+ enum AVHWDeviceType dev_type)
+{
+ AVHWDeviceContext *device_ctx;
+ AVHWFramesContext *frames_ctx;
+ int ret;
+
+ if (!avctx->hwaccel)
+ return AVERROR(ENOSYS);
+
+ if (avctx->hw_frames_ctx)
+ return 0;
+ if (!avctx->hw_device_ctx) {
+ av_log(avctx, AV_LOG_ERROR, "A hardware frames or device context is "
+ "required for hardware accelerated decoding.\n");
+ return AVERROR(EINVAL);
+ }
+
+ device_ctx = (AVHWDeviceContext *)avctx->hw_device_ctx->data;
+ if (device_ctx->type != dev_type) {
+ av_log(avctx, AV_LOG_ERROR, "Device type %s expected for hardware "
+ "decoding, but got %s.\n", av_hwdevice_get_type_name(dev_type),
+ av_hwdevice_get_type_name(device_ctx->type));
+ return AVERROR(EINVAL);
+ }
+
+ ret = avcodec_get_hw_frames_parameters(avctx,
+ avctx->hw_device_ctx,
+ avctx->hwaccel->pix_fmt,
+ &avctx->hw_frames_ctx);
+ if (ret < 0)
+ return ret;
+
+ frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
+
+
+ if (frames_ctx->initial_pool_size) {
+ // We guarantee 4 base work surfaces. The function above guarantees 1
+ // (the absolute minimum), so add the missing count.
+ frames_ctx->initial_pool_size += 3;
+
+ // Add an additional surface per thread is frame threading is enabled.
+ if (avctx->active_thread_type & FF_THREAD_FRAME)
+ frames_ctx->initial_pool_size += avctx->thread_count;
+ }
+
+ ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
+ if (ret < 0) {
+ av_buffer_unref(&avctx->hw_frames_ctx);
+ return ret;
+ }
+
+ return 0;
+}
+
+int avcodec_get_hw_frames_parameters(AVCodecContext *avctx,
+ AVBufferRef *device_ref,
+ enum AVPixelFormat hw_pix_fmt,
+ AVBufferRef **out_frames_ref)
+{
+ AVBufferRef *frames_ref = NULL;
+ AVHWAccel *hwa = find_hwaccel(avctx, hw_pix_fmt);
+ int ret;
+
+ if (!hwa || !hwa->frame_params)
+ return AVERROR(ENOENT);
+
+ frames_ref = av_hwframe_ctx_alloc(device_ref);
+ if (!frames_ref)
+ return AVERROR(ENOMEM);
+
+ ret = hwa->frame_params(avctx, frames_ref);
+ if (ret >= 0) {
+ *out_frames_ref = frames_ref;
+ } else {
+ av_buffer_unref(&frames_ref);
+ }
+ return ret;
+}
+
static int setup_hwaccel(AVCodecContext *avctx,
const enum AVPixelFormat fmt,
const char *name)
OpenPOWER on IntegriCloud