[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