[FFmpeg-devel] [PATCH 2/2 V2] libavcodec/qsvenc: Fix the encode part hwaccle issue when using system memory
Huang, Zhengxu
zhengxu.maxwell at gmail.com
Tue Jan 17 08:57:34 EET 2017
在 2017/1/9 10:10, Huang, Zhengxu 写道:
>
-------------- next part --------------
From 8466186d4622f760194edd62f7779a0ab8a230d2 Mon Sep 17 00:00:00 2001
From: Zhengxu <zhengxu.maxwell at gmail.com>
Date: Mon, 19 Dec 2016 03:39:39 -0500
Subject: [PATCH 2/2] libavcodec/qsvenc: Fix the encode part hwaccle issue when
using system memory
Description: when using system memory the encode actually uses the
PARTIAL_ACCELERATION which means the SW encoder of MSDK. And the performance
will quite poor compared with the HW MSDK.
eg: ./ffmpeg -c:v h264 -i in -c:v h264_qsv output.h264
Fix: Use the HWContext to get the vaDisplay and configure the encode to HW
mode. The performance will be improved significantly
Signed-off-by: ChaoX A Liu <chaox.a.liu at gmail.com>
Signed-off-by: Huang, Zhengxu <zhengxu.maxwell at gmail.com>
Signed-off-by: Andrew, Zhang <huazh407 at gmail.com>
---
libavcodec/qsvenc.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++--
libavcodec/qsvenc.h | 4 +++-
2 files changed, 66 insertions(+), 3 deletions(-)
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index ac443c1..f61aad7 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -651,6 +651,66 @@ static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q)
return 0;
}
+static int qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
+ QSVEncContext *q, const char *load_plugins)
+{
+ mfxIMPL impl = MFX_IMPL_AUTO_ANY;
+ const char *desc;
+ int ret;
+ AVHWDeviceContext *device_hw;
+ AVQSVDeviceContext *hwctx;
+ AVBufferRef *hw_device_ctx;
+ AVDictionary *dict = NULL;
+
+ if (q->dev_name) {
+ ret = av_dict_set(&dict, "child_device", q->dev_name, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV, NULL, dict, 0);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Failed to create a QSV device\n");
+ av_dict_free(&dict);
+ return ret;
+ }
+ av_dict_free(&dict);
+
+ device_hw = (AVHWDeviceContext*)hw_device_ctx->data;
+ hwctx = device_hw->hwctx;
+
+ *session = hwctx->session;
+
+ q->device_ctx.hw_device_ctx = hw_device_ctx;
+
+ ret = ff_qsv_load_plugins(*session, load_plugins, avctx);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error loading plugins\n");
+ return ret;
+ }
+ MFXQueryIMPL(*session, &impl);
+
+ switch (MFX_IMPL_BASETYPE(impl)) {
+ case MFX_IMPL_SOFTWARE:
+ desc = "software";
+ break;
+ case MFX_IMPL_HARDWARE:
+ case MFX_IMPL_HARDWARE2:
+ case MFX_IMPL_HARDWARE3:
+ case MFX_IMPL_HARDWARE4:
+ desc = "hardware accelerated";
+ break;
+ default:
+ desc = "unknown";
+ }
+
+ av_log(avctx, AV_LOG_VERBOSE,
+ "Initialized an internal MFX session using %s implementation\n",
+ desc);
+
+ return 0;
+}
+
static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q)
{
int ret;
@@ -673,12 +733,12 @@ static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q)
q->session = q->internal_session;
} else {
- ret = ff_qsv_init_internal_session(avctx, &q->internal_session,
+ ret = qsv_init_internal_session(avctx, &q->session, q,
q->load_plugins);
if (ret < 0)
return ret;
- q->session = q->internal_session;
+ // q->session = q->internal_session;
}
return 0;
@@ -1088,6 +1148,7 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
q->internal_session = NULL;
av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
+ av_buffer_unref(&q->device_ctx.hw_device_ctx);
av_freep(&q->frames_ctx.mids);
q->frames_ctx.nb_mids = 0;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 361d933..42d3ed5 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -71,6 +71,7 @@
{ "adaptive_b", "Adaptive B-frame placement", OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
{ "b_strategy", "Strategy to choose between I/P/B-frames", OFFSET(qsv.b_strategy), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
{ "cavlc", "Enable CAVLC", OFFSET(qsv.cavlc), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, \
+{ "qsv_dev", "Set QSV hardware device (DirectX adapter index, DRM path or X11 display name)", OFFSET(qsv.dev_name), AV_OPT_TYPE_STRING, { .str = "" }, 0, 128, VE }, \
typedef int SetEncodeCtrlCB (AVCodecContext *avctx,
const AVFrame *frame, mfxEncodeCtrl* enc_ctrl);
@@ -105,7 +106,7 @@ typedef struct QSVEncContext {
AVFifoBuffer *async_fifo;
QSVFramesContext frames_ctx;
-
+ QSVDeviceContext device_ctx;
// options set by the caller
int async_depth;
int idr_interval;
@@ -141,6 +142,7 @@ typedef struct QSVEncContext {
int a53_cc;
char *load_plugins;
+ char *dev_name;
SetEncodeCtrlCB *set_encode_ctrl_cb;
} QSVEncContext;
--
1.8.3.1
More information about the ffmpeg-devel
mailing list