vaapi_encode: Refactor encode misc parameter buffer creation

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.
This commit is contained in:
Mark Thompson 2019-05-06 16:21:29 +01:00
parent 7056002796
commit 2880a32c66
3 changed files with 61 additions and 42 deletions

View File

@ -103,6 +103,29 @@ static int vaapi_encode_make_param_buffer(AVCodecContext *avctx,
return 0; 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, static int vaapi_encode_wait(AVCodecContext *avctx,
VAAPIEncodePicture *pic) VAAPIEncodePicture *pic)
{ {
@ -212,10 +235,10 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
if (pic->type == PICTURE_TYPE_IDR) { if (pic->type == PICTURE_TYPE_IDR) {
for (i = 0; i < ctx->nb_global_params; i++) { for (i = 0; i < ctx->nb_global_params; i++) {
err = vaapi_encode_make_param_buffer(avctx, pic, err = vaapi_encode_make_misc_param_buffer(avctx, pic,
VAEncMiscParameterBufferType, ctx->global_params_type[i],
(char*)ctx->global_params[i], ctx->global_params[i],
ctx->global_params_size[i]); ctx->global_params_size[i]);
if (err < 0) if (err < 0)
goto fail; goto fail;
} }
@ -1047,14 +1070,15 @@ int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
return 0; return 0;
} }
static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx,
VAEncMiscParameterBuffer *buffer, static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, int type,
size_t size) void *buffer, size_t size)
{ {
VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodeContext *ctx = avctx->priv_data;
av_assert0(ctx->nb_global_params < MAX_GLOBAL_PARAMS); 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 [ctx->nb_global_params] = buffer;
ctx->global_params_size[ctx->nb_global_params] = size; ctx->global_params_size[ctx->nb_global_params] = size;
@ -1588,8 +1612,7 @@ rc_mode_found:
rc_bits_per_second, rc_window_size); rc_bits_per_second, rc_window_size);
} }
ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl; ctx->rc_params = (VAEncMiscParameterRateControl) {
ctx->rc_params.rc = (VAEncMiscParameterRateControl) {
.bits_per_second = rc_bits_per_second, .bits_per_second = rc_bits_per_second,
.target_percentage = rc_target_percentage, .target_percentage = rc_target_percentage,
.window_size = rc_window_size, .window_size = rc_window_size,
@ -1604,7 +1627,9 @@ rc_mode_found:
.quality_factor = rc_quality, .quality_factor = rc_quality,
#endif #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)); sizeof(ctx->rc_params));
} }
@ -1613,12 +1638,13 @@ rc_mode_found:
"initial fullness %"PRId64" bits.\n", "initial fullness %"PRId64" bits.\n",
hrd_buffer_size, hrd_initial_buffer_fullness); hrd_buffer_size, hrd_initial_buffer_fullness);
ctx->hrd_params.misc.type = VAEncMiscParameterTypeHRD; ctx->hrd_params = (VAEncMiscParameterHRD) {
ctx->hrd_params.hrd = (VAEncMiscParameterHRD) {
.initial_buffer_fullness = hrd_initial_buffer_fullness, .initial_buffer_fullness = hrd_initial_buffer_fullness,
.buffer_size = hrd_buffer_size, .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)); sizeof(ctx->hrd_params));
} }
@ -1632,11 +1658,13 @@ rc_mode_found:
av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n", av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
fr_num, fr_den, (double)fr_num / fr_den); fr_num, fr_den, (double)fr_num / fr_den);
ctx->fr_params.misc.type = VAEncMiscParameterTypeFrameRate; ctx->fr_params = (VAEncMiscParameterFrameRate) {
ctx->fr_params.fr.framerate = (unsigned int)fr_den << 16 | fr_num; .framerate = (unsigned int)fr_den << 16 | fr_num,
};
#if VA_CHECK_VERSION(0, 40, 0) #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)); sizeof(ctx->fr_params));
#endif #endif
@ -1898,10 +1926,12 @@ static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
quality = attr.value; quality = attr.value;
} }
ctx->quality_params.misc.type = VAEncMiscParameterTypeQualityLevel; ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
ctx->quality_params.quality.quality_level = quality; .quality_level = quality,
};
vaapi_encode_add_global_param(avctx, &ctx->quality_params.misc, vaapi_encode_add_global_param(avctx,
VAEncMiscParameterTypeQualityLevel,
&ctx->quality_params,
sizeof(ctx->quality_params)); sizeof(ctx->quality_params));
} }
#else #else

View File

@ -244,28 +244,17 @@ typedef struct VAAPIEncodeContext {
// Global parameters which will be applied at the start of the // Global parameters which will be applied at the start of the
// sequence (includes rate control parameters below). // 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]; size_t global_params_size[MAX_GLOBAL_PARAMS];
int nb_global_params; int nb_global_params;
// Rate control parameters. // Rate control parameters.
struct { VAEncMiscParameterRateControl rc_params;
VAEncMiscParameterBuffer misc; VAEncMiscParameterHRD hrd_params;
VAEncMiscParameterRateControl rc; VAEncMiscParameterFrameRate fr_params;
} rc_params;
struct {
VAEncMiscParameterBuffer misc;
VAEncMiscParameterHRD hrd;
} hrd_params;
struct {
VAEncMiscParameterBuffer misc;
VAEncMiscParameterFrameRate fr;
} fr_params;
#if VA_CHECK_VERSION(0, 36, 0) #if VA_CHECK_VERSION(0, 36, 0)
struct { VAEncMiscParameterBufferQualityLevel quality_params;
VAEncMiscParameterBuffer misc;
VAEncMiscParameterBufferQualityLevel quality;
} quality_params;
#endif #endif
// Per-sequence parameter structure (VAEncSequenceParameterBuffer*). // Per-sequence parameter structure (VAEncSequenceParameterBuffer*).

View 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; (ctx->va_bit_rate >> hrd->bit_rate_scale + 6) - 1;
hrd->cpb_size_scale = 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] = 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 // CBR mode as defined for the HRD cannot be achieved without filler
// data, so this flag cannot be set even with VAAPI CBR modes. // 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. // This calculation can easily overflow 32 bits.
bp->nal.initial_cpb_removal_delay[0] = 90000 * bp->nal.initial_cpb_removal_delay[0] = 90000 *
(uint64_t)ctx->hrd_params.hrd.initial_buffer_fullness / (uint64_t)ctx->hrd_params.initial_buffer_fullness /
ctx->hrd_params.hrd.buffer_size; ctx->hrd_params.buffer_size;
bp->nal.initial_cpb_removal_delay_offset[0] = 0; bp->nal.initial_cpb_removal_delay_offset[0] = 0;
} else { } else {
sps->vui.nal_hrd_parameters_present_flag = 0; sps->vui.nal_hrd_parameters_present_flag = 0;