[FFmpeg-devel,v2,14/36] vaapi_encode: Clean up the encode quality configuration

Submitted by Mark Thompson on June 7, 2018, 11:43 p.m.

Details

Message ID 20180607234331.32139-15-sw@jkqxz.net
State New
Headers show

Commit Message

Mark Thompson June 7, 2018, 11:43 p.m.
---
 libavcodec/vaapi_encode.c      | 84 +++++++++++++++++++++++++-----------------
 libavcodec/vaapi_encode_h264.c |  7 ++--
 2 files changed, 54 insertions(+), 37 deletions(-)

Comments

Haihao Xiang June 12, 2018, 7:39 a.m.
On Fri, 2018-06-08 at 00:43 +0100, Mark Thompson wrote:
> ---

>  libavcodec/vaapi_encode.c      | 84 +++++++++++++++++++++++++--------------

> ---

>  libavcodec/vaapi_encode_h264.c |  7 ++--

>  2 files changed, 54 insertions(+), 37 deletions(-)

> 

> diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c

> index 6104470b31..4da8a7083c 100644

> --- a/libavcodec/vaapi_encode.c

> +++ b/libavcodec/vaapi_encode.c

> @@ -1391,6 +1391,51 @@ static av_cold int

> vaapi_encode_init_rate_control(AVCodecContext *avctx)

>      return 0;

>  }

>  

> +static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)

> +{

> +#if VA_CHECK_VERSION(0, 36, 0)

> +    VAAPIEncodeContext *ctx = avctx->priv_data;

> +    VAStatus vas;

> +    VAConfigAttrib attr = { VAConfigAttribEncQualityRange };

> +    int quality = avctx->compression_level;

> +

> +    vas = vaGetConfigAttributes(ctx->hwctx->display,

> +                                ctx->va_profile,

> +                                ctx->va_entrypoint,

> +                                &attr, 1);

> +    if (vas != VA_STATUS_SUCCESS) {

> +        av_log(avctx, AV_LOG_ERROR, "Failed to query quality "

> +               "config attribute: %d (%s).\n", vas, vaErrorStr(vas));

> +        return AVERROR_EXTERNAL;

> +    }

> +

> +    if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {

> +        if (quality != 0) {

> +            av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "

> +                   "supported: will use default quality level.\n");

> +        }

> +    } else {

> +        if (quality > attr.value) {

> +            av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "

> +                   "valid range is 0-%d, using %d.\n",

> +                   attr.value, attr.value);

> +            quality = attr.value;

> +        }

> +

> +        ctx->quality_params.misc.type = VAEncMiscParameterTypeQualityLevel;

> +        ctx->quality_params.quality.quality_level = quality;

> +

> +        vaapi_encode_add_global_param(avctx, &ctx->quality_params.misc,

> +                                      sizeof(ctx->quality_params));

> +    }

> +#else

> +    av_log(avctx, AV_LOG_WARNING, "The encode quality option is "

> +           "not supported with this VAAPI version.\n");


Log the minimal VAAPI version for quality attribute?

> +#endif

> +

> +    return 0;

> +}

> +

>  static void vaapi_encode_free_output_buffer(void *opaque,

>                                              uint8_t *data)

>  {

> @@ -1572,6 +1617,12 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)

>      if (err < 0)

>          goto fail;

>  

> +    if (avctx->compression_level >= 0) {

> +        err = vaapi_encode_init_quality(avctx);

> +        if (err < 0)

> +            goto fail;

> +    }

> +

>      vas = vaCreateConfig(ctx->hwctx->display,

>                           ctx->va_profile, ctx->va_entrypoint,

>                           ctx->config_attributes, ctx->nb_config_attributes,

> @@ -1621,39 +1672,6 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)

>              goto fail;

>      }

>  

> -    if (avctx->compression_level >= 0) {

> -#if VA_CHECK_VERSION(0, 36, 0)

> -        VAConfigAttrib attr = { VAConfigAttribEncQualityRange };

> -

> -        vas = vaGetConfigAttributes(ctx->hwctx->display,

> -                                    ctx->va_profile,

> -                                    ctx->va_entrypoint,

> -                                    &attr, 1);

> -        if (vas != VA_STATUS_SUCCESS) {

> -            av_log(avctx, AV_LOG_WARNING, "Failed to query quality "

> -                   "attribute: will use default compression level.\n");

> -        } else {

> -            if (avctx->compression_level > attr.value) {

> -                av_log(avctx, AV_LOG_WARNING, "Invalid compression "

> -                       "level: valid range is 0-%d, using %d.\n",

> -                       attr.value, attr.value);

> -                avctx->compression_level = attr.value;

> -            }

> -

> -            ctx->quality_params.misc.type =

> -                VAEncMiscParameterTypeQualityLevel;

> -            ctx->quality_params.quality.quality_level =

> -                avctx->compression_level;

> -

> -            vaapi_encode_add_global_param(avctx, &ctx->quality_params.misc,

> -                                          sizeof(ctx->quality_params));

> -        }

> -#else

> -        av_log(avctx, AV_LOG_WARNING, "The encode compression level "

> -               "option is not supported with this VAAPI version.\n");

> -#endif

> -    }

> -

>      ctx->input_order  = 0;

>      ctx->output_delay = avctx->max_b_frames;

>      ctx->decode_delay = 1;

> diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c

> index c72fb9f00a..df6f39a946 100644

> --- a/libavcodec/vaapi_encode_h264.c

> +++ b/libavcodec/vaapi_encode_h264.c

> @@ -831,9 +831,6 @@ static av_cold int

> vaapi_encode_h264_configure(AVCodecContext *avctx)

>          av_assert0(0 && "Invalid RC mode.");

>      }

>  

> -    if (avctx->compression_level == FF_COMPRESSION_DEFAULT)

> -        avctx->compression_level = priv->quality;

> -

>      if (priv->sei & SEI_IDENTIFIER) {

>          const char *lavc  = LIBAVCODEC_IDENT;

>          const char *vaapi = VA_VERSION_S;

> @@ -907,6 +904,8 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext

> *avctx)

>          avctx->profile = priv->profile;

>      if (avctx->level == FF_LEVEL_UNKNOWN)

>          avctx->level = priv->level;

> +    if (avctx->compression_level == FF_COMPRESSION_DEFAULT)

> +        avctx->compression_level = priv->quality;

>  

>      // Reject unsupported profiles.

>      switch (avctx->profile) {

> @@ -972,7 +971,7 @@ static const AVOption vaapi_encode_h264_options[] = {

>      { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",

>        OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 20 }, 0, 52, FLAGS },

>      { "quality", "Set encode quality (trades off against speed, higher is

> faster)",

> -      OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8, FLAGS },

> +      OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS },

>      { "coder", "Entropy coder type",

>        OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS, "coder" },

>          { "cavlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN,

> INT_MAX, FLAGS, "coder" },

Patch hide | download patch | download mbox

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 6104470b31..4da8a7083c 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1391,6 +1391,51 @@  static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
     return 0;
 }
 
+static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
+{
+#if VA_CHECK_VERSION(0, 36, 0)
+    VAAPIEncodeContext *ctx = avctx->priv_data;
+    VAStatus vas;
+    VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
+    int quality = avctx->compression_level;
+
+    vas = vaGetConfigAttributes(ctx->hwctx->display,
+                                ctx->va_profile,
+                                ctx->va_entrypoint,
+                                &attr, 1);
+    if (vas != VA_STATUS_SUCCESS) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
+               "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
+        return AVERROR_EXTERNAL;
+    }
+
+    if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
+        if (quality != 0) {
+            av_log(avctx, AV_LOG_WARNING, "Quality attribute is not "
+                   "supported: will use default quality level.\n");
+        }
+    } else {
+        if (quality > attr.value) {
+            av_log(avctx, AV_LOG_WARNING, "Invalid quality level: "
+                   "valid range is 0-%d, using %d.\n",
+                   attr.value, attr.value);
+            quality = attr.value;
+        }
+
+        ctx->quality_params.misc.type = VAEncMiscParameterTypeQualityLevel;
+        ctx->quality_params.quality.quality_level = quality;
+
+        vaapi_encode_add_global_param(avctx, &ctx->quality_params.misc,
+                                      sizeof(ctx->quality_params));
+    }
+#else
+    av_log(avctx, AV_LOG_WARNING, "The encode quality option is "
+           "not supported with this VAAPI version.\n");
+#endif
+
+    return 0;
+}
+
 static void vaapi_encode_free_output_buffer(void *opaque,
                                             uint8_t *data)
 {
@@ -1572,6 +1617,12 @@  av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
     if (err < 0)
         goto fail;
 
+    if (avctx->compression_level >= 0) {
+        err = vaapi_encode_init_quality(avctx);
+        if (err < 0)
+            goto fail;
+    }
+
     vas = vaCreateConfig(ctx->hwctx->display,
                          ctx->va_profile, ctx->va_entrypoint,
                          ctx->config_attributes, ctx->nb_config_attributes,
@@ -1621,39 +1672,6 @@  av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
             goto fail;
     }
 
-    if (avctx->compression_level >= 0) {
-#if VA_CHECK_VERSION(0, 36, 0)
-        VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
-
-        vas = vaGetConfigAttributes(ctx->hwctx->display,
-                                    ctx->va_profile,
-                                    ctx->va_entrypoint,
-                                    &attr, 1);
-        if (vas != VA_STATUS_SUCCESS) {
-            av_log(avctx, AV_LOG_WARNING, "Failed to query quality "
-                   "attribute: will use default compression level.\n");
-        } else {
-            if (avctx->compression_level > attr.value) {
-                av_log(avctx, AV_LOG_WARNING, "Invalid compression "
-                       "level: valid range is 0-%d, using %d.\n",
-                       attr.value, attr.value);
-                avctx->compression_level = attr.value;
-            }
-
-            ctx->quality_params.misc.type =
-                VAEncMiscParameterTypeQualityLevel;
-            ctx->quality_params.quality.quality_level =
-                avctx->compression_level;
-
-            vaapi_encode_add_global_param(avctx, &ctx->quality_params.misc,
-                                          sizeof(ctx->quality_params));
-        }
-#else
-        av_log(avctx, AV_LOG_WARNING, "The encode compression level "
-               "option is not supported with this VAAPI version.\n");
-#endif
-    }
-
     ctx->input_order  = 0;
     ctx->output_delay = avctx->max_b_frames;
     ctx->decode_delay = 1;
diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index c72fb9f00a..df6f39a946 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -831,9 +831,6 @@  static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx)
         av_assert0(0 && "Invalid RC mode.");
     }
 
-    if (avctx->compression_level == FF_COMPRESSION_DEFAULT)
-        avctx->compression_level = priv->quality;
-
     if (priv->sei & SEI_IDENTIFIER) {
         const char *lavc  = LIBAVCODEC_IDENT;
         const char *vaapi = VA_VERSION_S;
@@ -907,6 +904,8 @@  static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx)
         avctx->profile = priv->profile;
     if (avctx->level == FF_LEVEL_UNKNOWN)
         avctx->level = priv->level;
+    if (avctx->compression_level == FF_COMPRESSION_DEFAULT)
+        avctx->compression_level = priv->quality;
 
     // Reject unsupported profiles.
     switch (avctx->profile) {
@@ -972,7 +971,7 @@  static const AVOption vaapi_encode_h264_options[] = {
     { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
       OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 20 }, 0, 52, FLAGS },
     { "quality", "Set encode quality (trades off against speed, higher is faster)",
-      OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8, FLAGS },
+      OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS },
     { "coder", "Entropy coder type",
       OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS, "coder" },
         { "cavlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "coder" },