[libav-devel] [RFC/PATCH 05/11] qsvenc: postpone initializing the encoder if possible

Anton Khirnov anton at khirnov.net
Wed Aug 12 15:07:16 CEST 2015


If the caller has not requested the global header, then we can wait with
initializing the encoder until the first packet is submitted. This will
allow us to export information like the size of the encoding frame pool
to the caller.
---
Callers who do want global headers (which in current API means extradata set
after codec open) are out of luck though. Not very nice.
---
 libavcodec/qsvenc.c | 43 ++++++++++++++++++++++++++++++++-----------
 libavcodec/qsvenc.h |  1 +
 2 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index d6a731f..6228b6c 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -190,6 +190,27 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
     return 0;
 }
 
+static int init_encoder(AVCodecContext *avctx, QSVEncContext *q)
+{
+    int ret;
+
+    ret = MFXVideoENCODE_Init(q->session, &q->param);
+    if (ret < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
+        return ff_qsv_error(ret);
+    }
+
+    ret = qsv_retrieve_enc_params(avctx, q);
+    if (ret < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
+        return ret;
+    }
+
+    q->encoder_initialized = 1;
+
+    return 0;
+}
+
 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
 {
     int ret;
@@ -228,20 +249,14 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
         return ff_qsv_error(ret);
     }
 
-    ret = MFXVideoENCODE_Init(q->session, &q->param);
-    if (ret < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
-        return ff_qsv_error(ret);
-    }
+    q->avctx = avctx;
 
-    ret = qsv_retrieve_enc_params(avctx, q);
-    if (ret < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
-        return ret;
+    if (!(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
+        ret = init_encoder(avctx, q);
+        if (ret < 0)
+            return ret;
     }
 
-    q->avctx = avctx;
-
     return 0;
 }
 
@@ -379,6 +394,12 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
     mfxSyncPoint sync      = NULL;
     int ret;
 
+    if (!q->encoder_initialized) {
+        ret = init_encoder(avctx, q);
+        if (ret < 0)
+            return ret;
+    }
+
     if (frame) {
         ret = submit_frame(q, frame, &surf);
         if (ret < 0) {
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 7bbeec3..f202863 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -44,6 +44,7 @@ typedef struct QSVEncContext {
 
     int packet_size;
     int width_align;
+    int encoder_initialized;
 
     mfxVideoParam param;
     mfxFrameAllocRequest req;
-- 
2.0.0



More information about the libav-devel mailing list