lavc/qsvenc: Fix bitrate_limit to allow AVC encode in limited bitrate
authorLinjie Fu <linjie.fu@intel.com>
Tue, 15 Oct 2019 07:56:23 +0000 (15:56 +0800)
committerZhong Li <zhongli_dev@126.com>
Sun, 3 Nov 2019 08:22:47 +0000 (16:22 +0800)
MFXVideoENCODE_Query calls CheckVideoParamQueryLike in MSDK and
will determine whether to set param.mfx.TargetKbps to the allowed
minTargetKbps according to the bitrate_limit in extco2 buffer.

Thus q->param.ExtParam must be set before MFXVideoENCODE_Query in case
minTargetKbps is written to TargetKbps by default.

1080P AVC encoding with option "-bitrate_limit 0 -b:v 100k":
Before patch:
            902 kbps
After patch:
            156 kbps
Signed-off-by: Linjie Fu <linjie.fu@intel.com>
libavcodec/qsvenc.c

index ba85d64..dcff778 100644 (file)
@@ -1052,25 +1052,6 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
     if (ret < 0)
         return ret;
 
-    ret = MFXVideoENCODE_Query(q->session, &q->param, &q->param);
-    if (ret == MFX_WRN_PARTIAL_ACCELERATION) {
-        av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
-    } else if (ret < 0) {
-        return ff_qsv_print_error(avctx, ret,
-                                  "Error querying encoder params");
-    }
-
-    ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
-    if (ret < 0)
-        return ff_qsv_print_error(avctx, ret,
-                                  "Error querying (IOSurf) the encoding parameters");
-
-    if (opaque_alloc) {
-        ret = qsv_init_opaque_alloc(avctx, q);
-        if (ret < 0)
-            return ret;
-    }
-
     if (avctx->hwaccel_context) {
         AVQSVContext *qsv = avctx->hwaccel_context;
         int i, j;
@@ -1100,6 +1081,25 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
         q->param.NumExtParam = q->nb_extparam_internal;
     }
 
+    ret = MFXVideoENCODE_Query(q->session, &q->param, &q->param);
+    if (ret == MFX_WRN_PARTIAL_ACCELERATION) {
+        av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
+    } else if (ret < 0) {
+        return ff_qsv_print_error(avctx, ret,
+                                  "Error querying encoder params");
+    }
+
+    ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
+    if (ret < 0)
+        return ff_qsv_print_error(avctx, ret,
+                                  "Error querying (IOSurf) the encoding parameters");
+
+    if (opaque_alloc) {
+        ret = qsv_init_opaque_alloc(avctx, q);
+        if (ret < 0)
+            return ret;
+    }
+
     ret = MFXVideoENCODE_Init(q->session, &q->param);
     if (ret < 0)
         return ff_qsv_print_error(avctx, ret,