Signed-off-by: Anton Khirnov <anton@khirnov.net>tags/n3.1
| @@ -202,6 +202,19 @@ static int vaapi_encode_issue(AVCodecContext *avctx, | |||
| pic->nb_param_buffers = 0; | |||
| if (pic->encode_order == 0) { | |||
| // Global parameter buffers are set on the first picture only. | |||
| 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]); | |||
| if (err < 0) | |||
| goto fail; | |||
| } | |||
| } | |||
| if (pic->type == PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) { | |||
| err = vaapi_encode_make_param_buffer(avctx, pic, | |||
| VAEncSequenceParameterBufferType, | |||
| @@ -32,6 +32,8 @@ struct VAAPIEncodeType; | |||
| struct VAAPIEncodePicture; | |||
| enum { | |||
| MAX_CONFIG_ATTRIBUTES = 4, | |||
| MAX_GLOBAL_PARAMS = 4, | |||
| MAX_PICTURE_REFERENCES = 2, | |||
| MAX_PICTURE_SLICES = 1, | |||
| MAX_PARAM_BUFFERS = 16, | |||
| @@ -128,15 +130,19 @@ typedef struct VAAPIEncodeContext { | |||
| AVBufferRef *recon_frames_ref; | |||
| AVHWFramesContext *recon_frames; | |||
| VAConfigAttrib *config_attributes; | |||
| VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES]; | |||
| int nb_config_attributes; | |||
| VAEncMiscParameterBuffer *global_params[MAX_GLOBAL_PARAMS]; | |||
| size_t global_params_size[MAX_GLOBAL_PARAMS]; | |||
| int nb_global_params; | |||
| // Per-sequence parameter structure (VAEncSequenceParameterBuffer*). | |||
| void *codec_sequence_params; | |||
| // Per-sequence parameters found in the per-picture parameter | |||
| // structure (VAEncPictureParameterBuffer*). | |||
| void *codec_picture_params; | |||
| void *codec_picture_params; | |||
| // Current encoding window, in display (input) order. | |||
| VAAPIEncodePicture *pic_start, *pic_end; | |||
| @@ -690,20 +690,21 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, | |||
| return 0; | |||
| } | |||
| static VAConfigAttrib vaapi_encode_h264_config_attributes[] = { | |||
| { .type = VAConfigAttribRTFormat, | |||
| .value = VA_RT_FORMAT_YUV420 }, | |||
| { .type = VAConfigAttribRateControl, | |||
| .value = VA_RC_CQP }, | |||
| { .type = VAConfigAttribEncPackedHeaders, | |||
| .value = (VA_ENC_PACKED_HEADER_SEQUENCE | | |||
| VA_ENC_PACKED_HEADER_SLICE) }, | |||
| }; | |||
| static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx) | |||
| { | |||
| static const VAConfigAttrib default_config_attributes[] = { | |||
| { .type = VAConfigAttribRTFormat, | |||
| .value = VA_RT_FORMAT_YUV420 }, | |||
| { .type = VAConfigAttribRateControl, | |||
| .value = VA_RC_CQP }, | |||
| { .type = VAConfigAttribEncPackedHeaders, | |||
| .value = (VA_ENC_PACKED_HEADER_SEQUENCE | | |||
| VA_ENC_PACKED_HEADER_SLICE) }, | |||
| }; | |||
| VAAPIEncodeContext *ctx = avctx->priv_data; | |||
| VAAPIEncodeH264Context *priv = ctx->priv_data; | |||
| int i; | |||
| switch (avctx->profile) { | |||
| case FF_PROFILE_H264_CONSTRAINED_BASELINE: | |||
| @@ -759,6 +760,11 @@ static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx) | |||
| return AVERROR_PATCHWELCOME; | |||
| } | |||
| for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) { | |||
| ctx->config_attributes[ctx->nb_config_attributes++] = | |||
| default_config_attributes[i]; | |||
| } | |||
| priv->fixed_qp_p = avctx->global_quality; | |||
| if (avctx->i_quant_factor > 0.0) | |||
| priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor + | |||
| @@ -773,10 +779,6 @@ static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx) | |||
| av_log(avctx, AV_LOG_DEBUG, "QP = %d / %d / %d for IDR / P / B frames.\n", | |||
| priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); | |||
| ctx->config_attributes = vaapi_encode_h264_config_attributes; | |||
| ctx->nb_config_attributes = | |||
| FF_ARRAY_ELEMS(vaapi_encode_h264_config_attributes); | |||
| ctx->nb_recon_frames = 20; | |||
| return 0; | |||
| @@ -1125,20 +1125,21 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, | |||
| return 0; | |||
| } | |||
| static VAConfigAttrib vaapi_encode_h265_config_attributes[] = { | |||
| { .type = VAConfigAttribRTFormat, | |||
| .value = VA_RT_FORMAT_YUV420 }, | |||
| { .type = VAConfigAttribRateControl, | |||
| .value = VA_RC_CQP }, | |||
| { .type = VAConfigAttribEncPackedHeaders, | |||
| .value = (VA_ENC_PACKED_HEADER_SEQUENCE | | |||
| VA_ENC_PACKED_HEADER_SLICE) }, | |||
| }; | |||
| static av_cold int vaapi_encode_h265_init_internal(AVCodecContext *avctx) | |||
| { | |||
| static const VAConfigAttrib default_config_attributes[] = { | |||
| { .type = VAConfigAttribRTFormat, | |||
| .value = VA_RT_FORMAT_YUV420 }, | |||
| { .type = VAConfigAttribEncPackedHeaders, | |||
| .value = (VA_ENC_PACKED_HEADER_SEQUENCE | | |||
| VA_ENC_PACKED_HEADER_SLICE) }, | |||
| { .type = VAConfigAttribRateControl, | |||
| .value = VA_RC_CQP }, | |||
| }; | |||
| VAAPIEncodeContext *ctx = avctx->priv_data; | |||
| VAAPIEncodeH265Context *priv = ctx->priv_data; | |||
| int i; | |||
| switch (avctx->profile) { | |||
| case FF_PROFILE_HEVC_MAIN: | |||
| @@ -1156,8 +1157,6 @@ static av_cold int vaapi_encode_h265_init_internal(AVCodecContext *avctx) | |||
| } | |||
| ctx->va_entrypoint = VAEntrypointEncSlice; | |||
| ctx->va_rc_mode = VA_RC_CQP; | |||
| ctx->input_width = avctx->width; | |||
| ctx->input_height = avctx->height; | |||
| ctx->aligned_width = FFALIGN(ctx->input_width, 16); | |||
| @@ -1169,6 +1168,19 @@ static av_cold int vaapi_encode_h265_init_internal(AVCodecContext *avctx) | |||
| ctx->input_width, ctx->input_height, ctx->aligned_width, | |||
| ctx->aligned_height, priv->ctu_width, priv->ctu_height); | |||
| for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) { | |||
| ctx->config_attributes[ctx->nb_config_attributes++] = | |||
| default_config_attributes[i]; | |||
| } | |||
| if (avctx->bit_rate > 0) { | |||
| av_log(avctx, AV_LOG_ERROR, "H.265 constant-bitrate encoding " | |||
| "is not supported.\n"); | |||
| return AVERROR_PATCHWELCOME; | |||
| } | |||
| ctx->va_rc_mode = VA_RC_CQP; | |||
| priv->fixed_qp_p = avctx->global_quality; | |||
| if (avctx->i_quant_factor > 0.0) | |||
| priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor + | |||
| @@ -1183,10 +1195,6 @@ static av_cold int vaapi_encode_h265_init_internal(AVCodecContext *avctx) | |||
| av_log(avctx, AV_LOG_DEBUG, "QP = %d / %d / %d for IDR / P / B frames.\n", | |||
| priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); | |||
| ctx->config_attributes = vaapi_encode_h265_config_attributes; | |||
| ctx->nb_config_attributes = | |||
| FF_ARRAY_ELEMS(vaapi_encode_h265_config_attributes); | |||
| ctx->nb_recon_frames = 20; | |||
| return 0; | |||
| @@ -333,17 +333,18 @@ static int vaapi_encode_mjpeg_init_slice_params(AVCodecContext *avctx, | |||
| return 0; | |||
| } | |||
| static VAConfigAttrib vaapi_encode_mjpeg_config_attributes[] = { | |||
| { .type = VAConfigAttribRTFormat, | |||
| .value = VA_RT_FORMAT_YUV420 }, | |||
| { .type = VAConfigAttribEncPackedHeaders, | |||
| .value = VA_ENC_PACKED_HEADER_SEQUENCE }, | |||
| }; | |||
| static av_cold int vaapi_encode_mjpeg_init_internal(AVCodecContext *avctx) | |||
| { | |||
| static const VAConfigAttrib default_config_attributes[] = { | |||
| { .type = VAConfigAttribRTFormat, | |||
| .value = VA_RT_FORMAT_YUV420 }, | |||
| { .type = VAConfigAttribEncPackedHeaders, | |||
| .value = VA_ENC_PACKED_HEADER_SEQUENCE }, | |||
| }; | |||
| VAAPIEncodeContext *ctx = avctx->priv_data; | |||
| VAAPIEncodeMJPEGContext *priv = ctx->priv_data; | |||
| int i; | |||
| ctx->va_profile = VAProfileJPEGBaseline; | |||
| ctx->va_entrypoint = VAEntrypointEncPicture; | |||
| @@ -353,9 +354,10 @@ static av_cold int vaapi_encode_mjpeg_init_internal(AVCodecContext *avctx) | |||
| ctx->aligned_width = FFALIGN(ctx->input_width, 8); | |||
| ctx->aligned_height = FFALIGN(ctx->input_height, 8); | |||
| ctx->config_attributes = vaapi_encode_mjpeg_config_attributes; | |||
| ctx->nb_config_attributes = | |||
| FF_ARRAY_ELEMS(vaapi_encode_mjpeg_config_attributes); | |||
| for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) { | |||
| ctx->config_attributes[ctx->nb_config_attributes++] = | |||
| default_config_attributes[i]; | |||
| } | |||
| priv->quality = avctx->global_quality; | |||
| if (priv->quality < 1 || priv->quality > 100) { | |||