diff options
author | Anton Khirnov <anton@khirnov.net> | 2016-05-27 13:23:19 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2016-06-21 19:53:38 +0200 |
commit | a0524d9b1e1bb0012207584f067096df7792df6c (patch) | |
tree | bdfb1267c302c700a8a4c5830631320a22d381fa /libavcodec/qsvdec.c | |
parent | 59e7361cc791e5103be1712dc59a2055f118d0da (diff) | |
download | ffmpeg-streaming-a0524d9b1e1bb0012207584f067096df7792df6c.zip ffmpeg-streaming-a0524d9b1e1bb0012207584f067096df7792df6c.tar.gz |
qsvdec: support getting the session from an AVHWFramesContext
Diffstat (limited to 'libavcodec/qsvdec.c')
-rw-r--r-- | libavcodec/qsvdec.c | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index e3e5bba..ac7a1e6 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -27,6 +27,8 @@ #include <mfx/mfxvideo.h> #include "libavutil/common.h" +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_qsv.h" #include "libavutil/mem.h" #include "libavutil/log.h" #include "libavutil/pixfmt.h" @@ -49,19 +51,42 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format) } } -static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session) +static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session, + AVBufferRef *hw_frames_ref) { - if (!session) { + int ret; + + if (session) { + q->session = session; + } else if (hw_frames_ref) { + if (q->internal_session) { + MFXClose(q->internal_session); + q->internal_session = NULL; + } + av_buffer_unref(&q->frames_ctx.hw_frames_ctx); + + q->frames_ctx.hw_frames_ctx = av_buffer_ref(hw_frames_ref); + if (!q->frames_ctx.hw_frames_ctx) + return AVERROR(ENOMEM); + + ret = ff_qsv_init_session_hwcontext(avctx, &q->internal_session, + &q->frames_ctx, q->load_plugins, + q->iopattern == MFX_IOPATTERN_OUT_OPAQUE_MEMORY); + if (ret < 0) { + av_buffer_unref(&q->frames_ctx.hw_frames_ctx); + return ret; + } + + q->session = q->internal_session; + } else { if (!q->internal_session) { - int ret = ff_qsv_init_internal_session(avctx, &q->internal_session, - q->load_plugins); + ret = ff_qsv_init_internal_session(avctx, &q->internal_session, + q->load_plugins); if (ret < 0) return ret; } q->session = q->internal_session; - } else { - q->session = session; } /* make sure the decoder is uninitialized */ @@ -73,6 +98,7 @@ static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession ses static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q) { mfxSession session = NULL; + int iopattern = 0; mfxVideoParam param = { { 0 } }; int ret; @@ -86,12 +112,28 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q) if (avctx->hwaccel_context) { AVQSVContext *user_ctx = avctx->hwaccel_context; session = user_ctx->session; - q->iopattern = user_ctx->iopattern; + iopattern = user_ctx->iopattern; q->ext_buffers = user_ctx->ext_buffers; q->nb_ext_buffers = user_ctx->nb_ext_buffers; } - ret = qsv_init_session(avctx, q, session); + if (avctx->hw_frames_ctx) { + AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx; + + if (!iopattern) { + if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME) + iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY; + else if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET) + iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY; + } + } + + if (!iopattern) + iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY; + q->iopattern = iopattern; + + ret = qsv_init_session(avctx, q, session, avctx->hw_frames_ctx); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error initializing an MFX session\n"); return ret; @@ -360,6 +402,10 @@ int ff_qsv_decode_close(QSVContext *q) if (q->internal_session) MFXClose(q->internal_session); + av_buffer_unref(&q->frames_ctx.hw_frames_ctx); + av_freep(&q->frames_ctx.mids); + q->frames_ctx.nb_mids = 0; + return 0; } |