[FFmpeg-devel] [PATCH] ffmpeg_qsv.c: Init an hwframes_context for decoder instead of encoder

Huang, Zhengxu zhengxu.maxwell at gmail.com
Fri Jan 20 11:41:01 EET 2017


-------------- next part --------------
From 2149f87637ab941be14828f7ae2c224908784c7d Mon Sep 17 00:00:00 2001
From: Zhengxu <zhengxu.maxwell at gmail.com>
Date: Wed, 4 Jan 2017 16:43:43 +0800
Subject: [PATCH] ffmpeg_qsv.c: Init an hwframes_context for decoder instead of
 encoder.

We consider that encoder is the last stage in the pipeline. Thinking
about filters, they get hwframes_context from their inputs. Likewise,
encoder should get hwframes_context from its input instead creating a
new faker one. Encoder can get acuurate parameters by doing so.

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>
---
 ffmpeg_qsv.c | 95 +++++++++++++++++++++++++++---------------------------------
 1 file changed, 43 insertions(+), 52 deletions(-)

diff --git a/ffmpeg_qsv.c b/ffmpeg_qsv.c
index 86824b6..8cedb7e 100644
--- a/ffmpeg_qsv.c
+++ b/ffmpeg_qsv.c
@@ -81,25 +81,26 @@ int qsv_init(AVCodecContext *s)
             return ret;
     }
 
-    av_buffer_unref(&ist->hw_frames_ctx);
-    ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
-    if (!ist->hw_frames_ctx)
-        return AVERROR(ENOMEM);
-
-    frames_ctx   = (AVHWFramesContext*)ist->hw_frames_ctx->data;
-    frames_hwctx = frames_ctx->hwctx;
-
-    frames_ctx->width             = FFALIGN(s->coded_width,  32);
-    frames_ctx->height            = FFALIGN(s->coded_height, 32);
-    frames_ctx->format            = AV_PIX_FMT_QSV;
-    frames_ctx->sw_format         = s->sw_pix_fmt;
-    frames_ctx->initial_pool_size = 64;
-    frames_hwctx->frame_type      = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
-
-    ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
-    if (ret < 0) {
-        av_log(NULL, AV_LOG_ERROR, "Error initializing a QSV frame pool\n");
-        return ret;
+    if(!ist->hw_frames_ctx) {
+        ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
+        if (!ist->hw_frames_ctx)
+            return AVERROR(ENOMEM);
+
+        frames_ctx   = (AVHWFramesContext*)ist->hw_frames_ctx->data;
+        frames_hwctx = frames_ctx->hwctx;
+
+        frames_ctx->width             = FFALIGN(s->coded_width,  32);
+        frames_ctx->height            = FFALIGN(s->coded_height, 32);
+        frames_ctx->format            = AV_PIX_FMT_QSV;
+        frames_ctx->sw_format         = s->sw_pix_fmt;
+        frames_ctx->initial_pool_size = 64;
+        frames_hwctx->frame_type      = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
+
+        ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Error initializing a QSV frame pool\n");
+            return ret;
+        }
     }
 
     ist->hwaccel_get_buffer = qsv_get_buffer;
@@ -114,9 +115,8 @@ int qsv_transcode_init(OutputStream *ost)
     const enum AVPixelFormat *pix_fmt;
 
     int err, i;
-    AVBufferRef *encode_frames_ref = NULL;
-    AVHWFramesContext *encode_frames;
-    AVQSVFramesContext *qsv_frames;
+    AVHWFramesContext *frames_ctx;
+    AVQSVFramesContext *frames_hwctx;
 
     /* check if the encoder supports QSV */
     if (!ost->enc->pix_fmts)
@@ -150,42 +150,33 @@ int qsv_transcode_init(OutputStream *ost)
     if (!hw_device_ctx) {
         err = qsv_device_init(ist);
         if (err < 0)
-            goto fail;
-    }
-
-    // This creates a dummy hw_frames_ctx for the encoder to be
-    // suitably initialised.  It only contains one real frame, so
-    // hopefully doesn't waste too much memory.
-
-    encode_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx);
-    if (!encode_frames_ref) {
-        err = AVERROR(ENOMEM);
-        goto fail;
+            return err;
     }
-    encode_frames = (AVHWFramesContext*)encode_frames_ref->data;
-    qsv_frames = encode_frames->hwctx;
 
-    encode_frames->width     = FFALIGN(ist->resample_width,  32);
-    encode_frames->height    = FFALIGN(ist->resample_height, 32);
-    encode_frames->format    = AV_PIX_FMT_QSV;
-    encode_frames->sw_format = AV_PIX_FMT_NV12;
-    encode_frames->initial_pool_size = 1;
+    ist->dec_ctx->pix_fmt = AV_PIX_FMT_QSV;
+    ist->resample_pix_fmt = AV_PIX_FMT_QSV;
+    ist->hw_frames_ctx    = av_hwframe_ctx_alloc(hw_device_ctx);
+    if (!ist->hw_frames_ctx)
+        return AVERROR(ENOMEM);
 
-    qsv_frames->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
+    frames_ctx   = (AVHWFramesContext*)ist->hw_frames_ctx->data;
+    frames_hwctx = frames_ctx->hwctx;
 
-    err = av_hwframe_ctx_init(encode_frames_ref);
-    if (err < 0)
-        goto fail;
+    frames_ctx->width             = FFALIGN(ist->resample_width,  32);
+    frames_ctx->height            = FFALIGN(ist->resample_height, 32);
+    frames_ctx->format            = AV_PIX_FMT_QSV;
+    frames_ctx->sw_format         = AV_PIX_FMT_NV12;
+    frames_ctx->initial_pool_size = 64;
+    frames_hwctx->frame_type      = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
 
-    ist->dec_ctx->pix_fmt       = AV_PIX_FMT_QSV;
-    ist->resample_pix_fmt       = AV_PIX_FMT_QSV;
+    err = av_hwframe_ctx_init(ist->hw_frames_ctx);
+    if (err < 0) {
+        av_buffer_unref(&ist->hw_frames_ctx);
+        av_log(NULL, AV_LOG_ERROR, "Error initializing a QSV frame pool\n");
+        return err;
+    }
 
-    ost->enc_ctx->pix_fmt       = AV_PIX_FMT_QSV;
-    ost->enc_ctx->hw_frames_ctx = encode_frames_ref;
+    ost->enc_ctx->pix_fmt = AV_PIX_FMT_QSV;
 
     return 0;
-
-fail:
-    av_buffer_unref(&encode_frames_ref);
-    return err;
 }
-- 
1.8.3.1



More information about the ffmpeg-devel mailing list