vaapi_encode: Refactor encode misc parameter buffer creation
authorMark Thompson <sw@jkqxz.net>
Mon, 6 May 2019 15:21:29 +0000 (16:21 +0100)
committerMark Thompson <sw@jkqxz.net>
Mon, 3 Jun 2019 20:16:22 +0000 (21:16 +0100)
This removes the use of the nonstandard combined structures, which
generated some warnings with clang and will cause alignment problems
with some parameter buffer types.

libavcodec/vaapi_encode.c
libavcodec/vaapi_encode.h
libavcodec/vaapi_encode_h264.c

index eda8b13..dd2a24d 100644 (file)
@@ -103,6 +103,29 @@ static int vaapi_encode_make_param_buffer(AVCodecContext *avctx,
     return 0;
 }
 
+static int vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx,
+                                               VAAPIEncodePicture *pic,
+                                               int type,
+                                               const void *data, size_t len)
+{
+    // Construct the buffer on the stack - 1KB is much larger than any
+    // current misc parameter buffer type (the largest is EncQuality at
+    // 224 bytes).
+    uint8_t buffer[1024];
+    VAEncMiscParameterBuffer header = {
+        .type = type,
+    };
+    size_t buffer_size = sizeof(header) + len;
+    av_assert0(buffer_size <= sizeof(buffer));
+
+    memcpy(buffer, &header, sizeof(header));
+    memcpy(buffer + sizeof(header), data, len);
+
+    return vaapi_encode_make_param_buffer(avctx, pic,
+                                          VAEncMiscParameterBufferType,
+                                          buffer, buffer_size);
+}
+
 static int vaapi_encode_wait(AVCodecContext *avctx,
                              VAAPIEncodePicture *pic)
 {
@@ -212,10 +235,10 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
 
     if (pic->type == PICTURE_TYPE_IDR) {
         for (i = 0; i < ctx->nb_global_params; i++) {
-            err = vaapi_encode_make_param_buffer(avctx, pic,
-                                                 VAEncMiscParameterBufferType,
-                                                 (char*)ctx->global_params[i],
-                                                 ctx->global_params_size[i]);
+            err = vaapi_encode_make_misc_param_buffer(avctx, pic,
+                                                      ctx->global_params_type[i],
+                                                      ctx->global_params[i],
+                                                      ctx->global_params_size[i]);
             if (err < 0)
                 goto fail;
         }
@@ -1047,14 +1070,15 @@ int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
     return 0;
 }
 
-static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx,
-                                                  VAEncMiscParameterBuffer *buffer,
-                                                  size_t size)
+
+static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, int type,
+                                                  void *buffer, size_t size)
 {
     VAAPIEncodeContext *ctx = avctx->priv_data;
 
     av_assert0(ctx->nb_global_params < MAX_GLOBAL_PARAMS);
 
+    ctx->global_params_type[ctx->nb_global_params] = type;
     ctx->global_params     [ctx->nb_global_params] = buffer;
     ctx->global_params_size[ctx->nb_global_params] = size;
 
@@ -1588,8 +1612,7 @@ rc_mode_found:
                    rc_bits_per_second, rc_window_size);
         }
 
-        ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl;
-        ctx->rc_params.rc = (VAEncMiscParameterRateControl) {
+        ctx->rc_params = (VAEncMiscParameterRateControl) {
             .bits_per_second    = rc_bits_per_second,
             .target_percentage  = rc_target_percentage,
             .window_size        = rc_window_size,
@@ -1604,7 +1627,9 @@ rc_mode_found:
             .quality_factor     = rc_quality,
 #endif
         };
-        vaapi_encode_add_global_param(avctx, &ctx->rc_params.misc,
+        vaapi_encode_add_global_param(avctx,
+                                      VAEncMiscParameterTypeRateControl,
+                                      &ctx->rc_params,
                                       sizeof(ctx->rc_params));
     }
 
@@ -1613,12 +1638,13 @@ rc_mode_found:
                "initial fullness %"PRId64" bits.\n",
                hrd_buffer_size, hrd_initial_buffer_fullness);
 
-        ctx->hrd_params.misc.type = VAEncMiscParameterTypeHRD;
-        ctx->hrd_params.hrd = (VAEncMiscParameterHRD) {
+        ctx->hrd_params = (VAEncMiscParameterHRD) {
             .initial_buffer_fullness = hrd_initial_buffer_fullness,
             .buffer_size             = hrd_buffer_size,
         };
-        vaapi_encode_add_global_param(avctx, &ctx->hrd_params.misc,
+        vaapi_encode_add_global_param(avctx,
+                                      VAEncMiscParameterTypeHRD,
+                                      &ctx->hrd_params,
                                       sizeof(ctx->hrd_params));
     }
 
@@ -1632,11 +1658,13 @@ rc_mode_found:
     av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
            fr_num, fr_den, (double)fr_num / fr_den);
 
-    ctx->fr_params.misc.type = VAEncMiscParameterTypeFrameRate;
-    ctx->fr_params.fr.framerate = (unsigned int)fr_den << 16 | fr_num;
-
+    ctx->fr_params = (VAEncMiscParameterFrameRate) {
+        .framerate = (unsigned int)fr_den << 16 | fr_num,
+    };
 #if VA_CHECK_VERSION(0, 40, 0)
-    vaapi_encode_add_global_param(avctx, &ctx->fr_params.misc,
+    vaapi_encode_add_global_param(avctx,
+                                  VAEncMiscParameterTypeFrameRate,
+                                  &ctx->fr_params,
                                   sizeof(ctx->fr_params));
 #endif
 
@@ -1898,10 +1926,12 @@ static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
             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,
+        ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
+            .quality_level = quality,
+        };
+        vaapi_encode_add_global_param(avctx,
+                                      VAEncMiscParameterTypeQualityLevel,
+                                      &ctx->quality_params,
                                       sizeof(ctx->quality_params));
     }
 #else
index 9456606..eeec060 100644 (file)
@@ -244,28 +244,17 @@ typedef struct VAAPIEncodeContext {
 
     // Global parameters which will be applied at the start of the
     // sequence (includes rate control parameters below).
-    VAEncMiscParameterBuffer *global_params[MAX_GLOBAL_PARAMS];
+    int             global_params_type[MAX_GLOBAL_PARAMS];
+    const void     *global_params     [MAX_GLOBAL_PARAMS];
     size_t          global_params_size[MAX_GLOBAL_PARAMS];
     int          nb_global_params;
 
     // Rate control parameters.
-    struct {
-        VAEncMiscParameterBuffer misc;
-        VAEncMiscParameterRateControl rc;
-    } rc_params;
-    struct {
-        VAEncMiscParameterBuffer misc;
-        VAEncMiscParameterHRD hrd;
-    } hrd_params;
-    struct {
-        VAEncMiscParameterBuffer misc;
-        VAEncMiscParameterFrameRate fr;
-    } fr_params;
+    VAEncMiscParameterRateControl rc_params;
+    VAEncMiscParameterHRD        hrd_params;
+    VAEncMiscParameterFrameRate   fr_params;
 #if VA_CHECK_VERSION(0, 36, 0)
-    struct {
-        VAEncMiscParameterBuffer misc;
-        VAEncMiscParameterBufferQualityLevel quality;
-    } quality_params;
+    VAEncMiscParameterBufferQualityLevel quality_params;
 #endif
 
     // Per-sequence parameter structure (VAEncSequenceParameterBuffer*).
index 4cf99d7..d142711 100644 (file)
@@ -471,9 +471,9 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
             (ctx->va_bit_rate >> hrd->bit_rate_scale + 6) - 1;
 
         hrd->cpb_size_scale =
-            av_clip_uintp2(av_log2(ctx->hrd_params.hrd.buffer_size) - 15 - 4, 4);
+            av_clip_uintp2(av_log2(ctx->hrd_params.buffer_size) - 15 - 4, 4);
         hrd->cpb_size_value_minus1[0] =
-            (ctx->hrd_params.hrd.buffer_size >> hrd->cpb_size_scale + 4) - 1;
+            (ctx->hrd_params.buffer_size >> hrd->cpb_size_scale + 4) - 1;
 
         // CBR mode as defined for the HRD cannot be achieved without filler
         // data, so this flag cannot be set even with VAAPI CBR modes.
@@ -488,8 +488,8 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
 
         // This calculation can easily overflow 32 bits.
         bp->nal.initial_cpb_removal_delay[0] = 90000 *
-            (uint64_t)ctx->hrd_params.hrd.initial_buffer_fullness /
-            ctx->hrd_params.hrd.buffer_size;
+            (uint64_t)ctx->hrd_params.initial_buffer_fullness /
+            ctx->hrd_params.buffer_size;
         bp->nal.initial_cpb_removal_delay_offset[0] = 0;
     } else {
         sps->vui.nal_hrd_parameters_present_flag = 0;