H264RawAUD raw_aud;
H264RawSPS raw_sps;
H264RawPPS raw_pps;
- H264RawSEI raw_sei;
H264RawSlice raw_slice;
H264RawSEIBufferingPeriod sei_buffering_period;
H264RawSEIPicTiming sei_pic_timing;
H264RawSEIRecoveryPoint sei_recovery_point;
- H264RawSEIUserDataUnregistered sei_identifier;
+ SEIRawUserDataUnregistered sei_identifier;
char *sei_identifier_string;
int aud_needed;
CodedBitstreamFragment *au,
void *nal_unit)
{
- VAAPIEncodeH264Context *priv = avctx->priv_data;
H264RawNALUnitHeader *header = nal_unit;
int err;
- err = ff_cbs_insert_unit_content(priv->cbc, au, -1,
+ err = ff_cbs_insert_unit_content(au, -1,
header->nal_unit_type, nal_unit, NULL);
if (err < 0) {
av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: "
err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au);
fail:
- ff_cbs_fragment_reset(priv->cbc, au);
+ ff_cbs_fragment_reset(au);
return err;
}
err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au);
fail:
- ff_cbs_fragment_reset(priv->cbc, au);
+ ff_cbs_fragment_reset(au);
return err;
}
{
VAAPIEncodeH264Context *priv = avctx->priv_data;
CodedBitstreamFragment *au = &priv->current_access_unit;
- int err, i;
+ int err;
if (priv->sei_needed) {
- H264RawSEI *sei = &priv->raw_sei;
-
if (priv->aud_needed) {
err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_aud);
if (err < 0)
priv->aud_needed = 0;
}
- *sei = (H264RawSEI) {
- .nal_unit_header = {
- .nal_unit_type = H264_NAL_SEI,
- },
- };
-
- i = 0;
-
if (priv->sei_needed & SEI_IDENTIFIER) {
- sei->payload[i].payload_type = H264_SEI_TYPE_USER_DATA_UNREGISTERED;
- sei->payload[i].payload.user_data_unregistered = priv->sei_identifier;
- ++i;
+ err = ff_cbs_sei_add_message(priv->cbc, au, 1,
+ SEI_TYPE_USER_DATA_UNREGISTERED,
+ &priv->sei_identifier, NULL);
+ if (err < 0)
+ goto fail;
}
if (priv->sei_needed & SEI_TIMING) {
if (pic->type == PICTURE_TYPE_IDR) {
- sei->payload[i].payload_type = H264_SEI_TYPE_BUFFERING_PERIOD;
- sei->payload[i].payload.buffering_period = priv->sei_buffering_period;
- ++i;
+ err = ff_cbs_sei_add_message(priv->cbc, au, 1,
+ SEI_TYPE_BUFFERING_PERIOD,
+ &priv->sei_buffering_period, NULL);
+ if (err < 0)
+ goto fail;
}
- sei->payload[i].payload_type = H264_SEI_TYPE_PIC_TIMING;
- sei->payload[i].payload.pic_timing = priv->sei_pic_timing;
- ++i;
+ err = ff_cbs_sei_add_message(priv->cbc, au, 1,
+ SEI_TYPE_PIC_TIMING,
+ &priv->sei_pic_timing, NULL);
+ if (err < 0)
+ goto fail;
}
if (priv->sei_needed & SEI_RECOVERY_POINT) {
- sei->payload[i].payload_type = H264_SEI_TYPE_RECOVERY_POINT;
- sei->payload[i].payload.recovery_point = priv->sei_recovery_point;
- ++i;
+ err = ff_cbs_sei_add_message(priv->cbc, au, 1,
+ SEI_TYPE_RECOVERY_POINT,
+ &priv->sei_recovery_point, NULL);
+ if (err < 0)
+ goto fail;
}
- sei->payload_count = i;
- av_assert0(sei->payload_count > 0);
-
- err = vaapi_encode_h264_add_nal(avctx, au, sei);
- if (err < 0)
- goto fail;
priv->sei_needed = 0;
err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au);
if (err < 0)
goto fail;
- ff_cbs_fragment_reset(priv->cbc, au);
+ ff_cbs_fragment_reset(au);
*type = VAEncPackedHeaderRawData;
return 0;
}
fail:
- ff_cbs_fragment_reset(priv->cbc, au);
+ ff_cbs_fragment_reset(au);
return err;
}
sps->level_idc = avctx->level;
} else {
const H264LevelDescriptor *level;
+ int framerate;
+
+ if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
+ framerate = avctx->framerate.num / avctx->framerate.den;
+ else
+ framerate = 0;
level = ff_h264_guess_level(sps->profile_idc,
avctx->bit_rate,
+ framerate,
priv->mb_width * 16,
priv->mb_height * 16,
priv->dpb_frames);
sps->vui.aspect_ratio_info_present_flag = 1;
}
- if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED ||
- avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
+ // Unspecified video format, from table E-2.
+ sps->vui.video_format = 5;
+ sps->vui.video_full_range_flag =
+ avctx->color_range == AVCOL_RANGE_JPEG;
+ sps->vui.colour_primaries = avctx->color_primaries;
+ sps->vui.transfer_characteristics = avctx->color_trc;
+ sps->vui.matrix_coefficients = avctx->colorspace;
+ if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
avctx->color_trc != AVCOL_TRC_UNSPECIFIED ||
- avctx->colorspace != AVCOL_SPC_UNSPECIFIED) {
+ avctx->colorspace != AVCOL_SPC_UNSPECIFIED)
+ sps->vui.colour_description_present_flag = 1;
+ if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED ||
+ sps->vui.colour_description_present_flag)
sps->vui.video_signal_type_present_flag = 1;
- sps->vui.video_format = 5; // Unspecified.
- sps->vui.video_full_range_flag =
- avctx->color_range == AVCOL_RANGE_JPEG;
-
- if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
- avctx->color_trc != AVCOL_TRC_UNSPECIFIED ||
- avctx->colorspace != AVCOL_SPC_UNSPECIFIED) {
- sps->vui.colour_description_present_flag = 1;
- sps->vui.colour_primaries = avctx->color_primaries;
- sps->vui.transfer_characteristics = avctx->color_trc;
- sps->vui.matrix_coefficients = avctx->colorspace;
- }
- } else {
- sps->vui.video_format = 5;
- sps->vui.video_full_range_flag = 0;
- sps->vui.colour_primaries = avctx->color_primaries;
- sps->vui.transfer_characteristics = avctx->color_trc;
- sps->vui.matrix_coefficients = avctx->colorspace;
- }
if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) {
sps->vui.chroma_loc_info_present_flag = 1;
(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.
// 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;
}
}
+ ctx->roi_quant_range = 51 + 6 * (ctx->profile->depth - 8);
+
return 0;
}
{
VAAPIEncodeH264Context *priv = avctx->priv_data;
- ff_cbs_fragment_free(priv->cbc, &priv->current_access_unit);
+ ff_cbs_fragment_free(&priv->current_access_unit);
ff_cbs_close(&priv->cbc);
av_freep(&priv->sei_identifier_string);
.version = LIBAVUTIL_VERSION_INT,
};
-AVCodec ff_h264_vaapi_encoder = {
+const AVCodec ff_h264_vaapi_encoder = {
.name = "h264_vaapi",
.long_name = NULL_IF_CONFIG_SMALL("H.264/AVC (VAAPI)"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H264,
.priv_data_size = sizeof(VAAPIEncodeH264Context),
.init = &vaapi_encode_h264_init,
- .send_frame = &ff_vaapi_encode_send_frame,
.receive_packet = &ff_vaapi_encode_receive_packet,
.close = &vaapi_encode_h264_close,
.priv_class = &vaapi_encode_h264_class,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
+ AV_CODEC_CAP_DR1,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.defaults = vaapi_encode_h264_defaults,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_VAAPI,
AV_PIX_FMT_NONE,
},
+ .hw_configs = ff_vaapi_encode_hw_configs,
.wrapper_name = "vaapi",
};