d3d12: Implement H264 VUI Writer

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26223>
This commit is contained in:
Sil Vilerino
2023-11-09 16:36:44 -05:00
committed by Marge Bot
parent cf8cbf0647
commit fdc8b7cdc4
6 changed files with 261 additions and 9 deletions

View File

@@ -112,6 +112,7 @@ enum d3d12_video_encoder_config_dirty_flags
d3d12_video_encoder_config_dirty_flag_slices = 0x80,
d3d12_video_encoder_config_dirty_flag_gop = 0x100,
d3d12_video_encoder_config_dirty_flag_motion_precision_limit = 0x200,
d3d12_video_encoder_config_dirty_flag_sequence_info = 0x400,
};
DEFINE_ENUM_FLAG_OPERATORS(d3d12_video_encoder_config_dirty_flags);
@@ -274,6 +275,7 @@ struct D3D12EncodeConfiguration
std::list<UINT/*PictureIndex*/> pendingShowableFrames;
} m_encoderCodecSpecificStateDescAV1;
struct pipe_h264_enc_seq_param m_encoderCodecSpecificSequenceStateDescH264;
};
struct EncodedBitstreamResolvedMetadata

View File

@@ -823,6 +823,14 @@ d3d12_video_encoder_update_current_encoder_config_state_h264(struct d3d12_video_
}
pD3D12Enc->m_currentEncodeConfig.m_encoderCodecDesc = D3D12_VIDEO_ENCODER_CODEC_H264;
// Set Sequence information
if (memcmp(&pD3D12Enc->m_currentEncodeConfig.m_encoderCodecSpecificSequenceStateDescH264,
&h264Pic->seq,
sizeof(h264Pic->seq)) != 0) {
pD3D12Enc->m_currentEncodeConfig.m_ConfigDirtyFlags |= d3d12_video_encoder_config_dirty_flag_sequence_info;
}
pD3D12Enc->m_currentEncodeConfig.m_encoderCodecSpecificSequenceStateDescH264 = h264Pic->seq;
// Set input format
DXGI_FORMAT targetFmt = d3d12_convert_pipe_video_profile_to_dxgi_format(pD3D12Enc->base.profile);
if (pD3D12Enc->m_currentEncodeConfig.m_encodeFormatInfo.Format != targetFmt) {
@@ -1022,7 +1030,9 @@ d3d12_video_encoder_build_codec_headers_h264(struct d3d12_video_encoder *pD3D12E
bool isFirstFrame = (pD3D12Enc->m_fenceValue == 1);
bool writeNewSPS = isFirstFrame // on first frame
|| ((pD3D12Enc->m_currentEncodeConfig.m_seqFlags & // also on resolution change
D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAG_RESOLUTION_CHANGE) != 0);
D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAG_RESOLUTION_CHANGE) != 0)
// Also on input format dirty flag for new SPS, VUI etc
|| (pD3D12Enc->m_currentEncodeConfig.m_ConfigDirtyFlags & d3d12_video_encoder_config_dirty_flag_sequence_info);
d3d12_video_bitstream_builder_h264 *pH264BitstreamBuilder =
static_cast<d3d12_video_bitstream_builder_h264 *>(pD3D12Enc->m_upBitstreamBuilder.get());
@@ -1036,7 +1046,8 @@ d3d12_video_encoder_build_codec_headers_h264(struct d3d12_video_encoder *pD3D12E
active_seq_parameter_set_id++;
pH264BitstreamBuilder->set_active_sps_id(active_seq_parameter_set_id);
}
pH264BitstreamBuilder->build_sps(*profDesc.pH264Profile,
pH264BitstreamBuilder->build_sps(pD3D12Enc->m_currentEncodeConfig.m_encoderCodecSpecificSequenceStateDescH264,
*profDesc.pH264Profile,
*levelDesc.pH264LevelSetting,
pD3D12Enc->m_currentEncodeConfig.m_encodeFormatInfo.Format,
*codecConfigDesc.pH264Config,

View File

@@ -49,7 +49,8 @@ Convert12ToSpecH264Profiles(D3D12_VIDEO_ENCODER_PROFILE_H264 profile12)
}
void
d3d12_video_bitstream_builder_h264::build_sps(const D3D12_VIDEO_ENCODER_PROFILE_H264 & profile,
d3d12_video_bitstream_builder_h264::build_sps(const struct pipe_h264_enc_seq_param & seqData,
const D3D12_VIDEO_ENCODER_PROFILE_H264 & profile,
const D3D12_VIDEO_ENCODER_LEVELS_H264 & level,
const DXGI_FORMAT & inputFmt,
const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264 & codecConfig,
@@ -129,6 +130,43 @@ d3d12_video_bitstream_builder_h264::build_sps(const D3D12_VIDEO_ENCODER_PROFILE_
frame_cropping_codec_config.top,
frame_cropping_codec_config.bottom };
// Copy VUI params from seqData
spsStructure.vui_parameters_present_flag = seqData.vui_parameters_present_flag;
spsStructure.vui.aspect_ratio_info_present_flag = seqData.vui_flags.aspect_ratio_info_present_flag;
spsStructure.vui.timing_info_present_flag = seqData.vui_flags.timing_info_present_flag;
spsStructure.vui.video_signal_type_present_flag = seqData.vui_flags.video_signal_type_present_flag;
spsStructure.vui.colour_description_present_flag = seqData.vui_flags.colour_description_present_flag;
spsStructure.vui.chroma_loc_info_present_flag = seqData.vui_flags.chroma_loc_info_present_flag;
spsStructure.vui.overscan_info_present_flag = seqData.vui_flags.overscan_info_present_flag;
spsStructure.vui.overscan_appropriate_flag = seqData.vui_flags.overscan_appropriate_flag;
spsStructure.vui.fixed_frame_rate_flag = seqData.vui_flags.fixed_frame_rate_flag;
spsStructure.vui.nal_hrd_parameters_present_flag = seqData.vui_flags.nal_hrd_parameters_present_flag;
spsStructure.vui.vcl_hrd_parameters_present_flag = seqData.vui_flags.vcl_hrd_parameters_present_flag;
spsStructure.vui.low_delay_hrd_flag = seqData.vui_flags.low_delay_hrd_flag;
spsStructure.vui.pic_struct_present_flag = seqData.vui_flags.pic_struct_present_flag;
spsStructure.vui.bitstream_restriction_flag = seqData.vui_flags.bitstream_restriction_flag;
spsStructure.vui.motion_vectors_over_pic_boundaries_flag = seqData.vui_flags.motion_vectors_over_pic_boundaries_flag;
spsStructure.vui.aspect_ratio_idc = seqData.aspect_ratio_idc;
spsStructure.vui.sar_width = seqData.sar_width;
spsStructure.vui.sar_height = seqData.sar_height;
spsStructure.vui.video_format = seqData.video_format;
spsStructure.vui.video_full_range_flag = seqData.video_full_range_flag;
spsStructure.vui.colour_primaries = seqData.colour_primaries;
spsStructure.vui.transfer_characteristics = seqData.transfer_characteristics;
spsStructure.vui.matrix_coefficients = seqData.matrix_coefficients;
spsStructure.vui.chroma_sample_loc_type_top_field = seqData.chroma_sample_loc_type_top_field;
spsStructure.vui.chroma_sample_loc_type_bottom_field = seqData.chroma_sample_loc_type_bottom_field;
spsStructure.vui.time_scale = seqData.time_scale;
spsStructure.vui.num_units_in_tick = seqData.num_units_in_tick;
memset(&spsStructure.vui.nal_hrd_parameters, 0, sizeof(H264_HRD_PARAMS));
memset(&spsStructure.vui.vcl_hrd_parameters, 0, sizeof(H264_HRD_PARAMS));
spsStructure.vui.max_bytes_per_pic_denom = seqData.max_bytes_per_pic_denom;
spsStructure.vui.max_bits_per_mb_denom = seqData.max_bits_per_mb_denom;
spsStructure.vui.log2_max_mv_length_vertical = seqData.log2_max_mv_length_vertical;
spsStructure.vui.log2_max_mv_length_horizontal = seqData.log2_max_mv_length_horizontal;
spsStructure.vui.num_reorder_frames = seqData.max_num_reorder_frames;
spsStructure.vui.max_dec_frame_buffering = seqData.max_dec_frame_buffering;
// Print built PPS structure
debug_printf(
"[D3D12 d3d12_video_bitstream_builder_h264] H264_SPS Structure generated before writing to bitstream:\n");
@@ -223,6 +261,24 @@ d3d12_video_bitstream_builder_h264::print_pps(const H264_PPS &pps)
"[D3D12 d3d12_video_bitstream_builder_h264] H264_PPS values end\n--------------------------------------\n");
}
static void
print_hrd(const H264_HRD_PARAMS *pHrd)
{
debug_printf("cpb_cnt_minus1: %d\n", pHrd->cpb_cnt_minus1);
debug_printf("bit_rate_scale: %d\n", pHrd->bit_rate_scale);
debug_printf("cpb_size_scale: %d\n", pHrd->cpb_size_scale);
for (uint32_t i = 0; i <= pHrd->cpb_cnt_minus1; i++)
{
debug_printf("bit_rate_value_minus1[%d]: %d\n", i, pHrd->bit_rate_value_minus1[i]);
debug_printf("cpb_size_value_minus1[%d]: %d\n", i, pHrd->cpb_size_value_minus1[i]);
debug_printf("cbr_flag[%d]: %d\n", i, pHrd->cbr_flag[i]);
}
debug_printf("initial_cpb_removal_delay_length_minus1: %d\n", pHrd->initial_cpb_removal_delay_length_minus1);
debug_printf("cpb_removal_delay_length_minus1: %d\n", pHrd->cpb_removal_delay_length_minus1);
debug_printf("dpb_output_delay_length_minus1: %d\n", pHrd->dpb_output_delay_length_minus1);
debug_printf("time_offset_length: %d\n", pHrd->time_offset_length);
}
void
d3d12_video_bitstream_builder_h264::print_sps(const H264_SPS &sps)
{
@@ -231,11 +287,15 @@ d3d12_video_bitstream_builder_h264::print_sps(const H264_SPS &sps)
// d3d12_video_encoder_bitstream_builder_h264.h
static_assert(sizeof(H264_SPS) ==
(sizeof(uint32_t) *
20), "Update the number of uint32_t in struct in assert and add case below if structure changes");
(sizeof(uint32_t) * 21 + sizeof(H264_VUI_PARAMS)), "Update the print function if structure changes");
static_assert(sizeof(H264_VUI_PARAMS) ==
(sizeof(uint32_t) * 32 + 2*sizeof(H264_HRD_PARAMS)), "Update the print function if structure changes");
static_assert(sizeof(H264_HRD_PARAMS) ==
(sizeof(uint32_t) * 7 + 3*32*sizeof(uint32_t)), "Update the print function if structure changes");
// Declared fields from definition in d3d12_video_encoder_bitstream_builder_h264.h
debug_printf("[D3D12 d3d12_video_bitstream_builder_h264] H264_SPS values below:\n");
debug_printf("profile_idc: %d\n", sps.profile_idc);
debug_printf("constraint_set1_flag: %d\n", sps.constraint_set1_flag);
@@ -257,6 +317,44 @@ d3d12_video_bitstream_builder_h264::print_sps(const H264_SPS &sps)
debug_printf("frame_cropping_rect_right_offset: %d\n", sps.frame_cropping_rect_right_offset);
debug_printf("frame_cropping_rect_top_offset: %d\n", sps.frame_cropping_rect_top_offset);
debug_printf("frame_cropping_rect_bottom_offset: %d\n", sps.frame_cropping_rect_bottom_offset);
debug_printf("VUI.vui_parameters_present_flag: %d\n", sps.vui_parameters_present_flag);
debug_printf("VUI.aspect_ratio_info_present_flag: %d\n", sps.vui.aspect_ratio_info_present_flag);
debug_printf("VUI.aspect_ratio_idc: %d\n", sps.vui.aspect_ratio_idc);
debug_printf("VUI.sar_width: %d\n", sps.vui.sar_width);
debug_printf("VUI.sar_height: %d\n", sps.vui.sar_height);
debug_printf("VUI.overscan_info_present_flag: %d\n", sps.vui.overscan_info_present_flag);
debug_printf("VUI.overscan_appropriate_flag: %d\n", sps.vui.overscan_appropriate_flag);
debug_printf("VUI.video_signal_type_present_flag: %d\n", sps.vui.video_signal_type_present_flag);
debug_printf("VUI.video_format: %d\n", sps.vui.video_format);
debug_printf("VUI.video_full_range_flag: %d\n", sps.vui.video_full_range_flag);
debug_printf("VUI.colour_description_present_flag: %d\n", sps.vui.colour_description_present_flag);
debug_printf("VUI.colour_primaries: %d\n", sps.vui.colour_primaries);
debug_printf("VUI.transfer_characteristics: %d\n", sps.vui.transfer_characteristics);
debug_printf("VUI.matrix_coefficients: %d\n", sps.vui.matrix_coefficients);
debug_printf("VUI.chroma_loc_info_present_flag: %d\n", sps.vui.chroma_loc_info_present_flag);
debug_printf("VUI.chroma_sample_loc_type_top_field: %d\n", sps.vui.chroma_sample_loc_type_top_field);
debug_printf("VUI.chroma_sample_loc_type_bottom_field: %d\n", sps.vui.chroma_sample_loc_type_bottom_field);
debug_printf("VUI.timing_info_present_flag: %d\n", sps.vui.timing_info_present_flag);
debug_printf("VUI.time_scale: %d\n", sps.vui.time_scale);
debug_printf("VUI.num_units_in_tick: %d\n", sps.vui.num_units_in_tick);
debug_printf("VUI.fixed_frame_rate_flag: %d\n", sps.vui.fixed_frame_rate_flag);
debug_printf("VUI.nal_hrd_parameters_present_flag: %d\n", sps.vui.nal_hrd_parameters_present_flag);
debug_printf("VUI.sps.vui.nal_hrd_parameters\n");
print_hrd(&sps.vui.nal_hrd_parameters);
debug_printf("VUI.vcl_hrd_parameters_present_flag: %d\n", sps.vui.vcl_hrd_parameters_present_flag);
debug_printf("VUI.sps.vui.vcl_hrd_parameters\n");
print_hrd(&sps.vui.vcl_hrd_parameters);
debug_printf("VUI.low_delay_hrd_flag: %d\n", sps.vui.low_delay_hrd_flag);
debug_printf("VUI.pic_struct_present_flag: %d\n", sps.vui.pic_struct_present_flag);
debug_printf("VUI.bitstream_restriction_flag: %d\n", sps.vui.bitstream_restriction_flag);
debug_printf("VUI.motion_vectors_over_pic_boundaries_flag: %d\n", sps.vui.motion_vectors_over_pic_boundaries_flag);
debug_printf("VUI.max_bytes_per_pic_denom: %d\n", sps.vui.max_bytes_per_pic_denom);
debug_printf("VUI.max_bits_per_mb_denom: %d\n", sps.vui.max_bits_per_mb_denom);
debug_printf("VUI.log2_max_mv_length_vertical: %d\n", sps.vui.log2_max_mv_length_vertical);
debug_printf("VUI.log2_max_mv_length_horizontal: %d\n", sps.vui.log2_max_mv_length_horizontal);
debug_printf("VUI.num_reorder_frames: %d\n", sps.vui.num_reorder_frames);
debug_printf("VUI.max_dec_frame_buffering: %d\n", sps.vui.max_dec_frame_buffering);
debug_printf(
"[D3D12 d3d12_video_bitstream_builder_h264] H264_SPS values end\n--------------------------------------\n");
}

View File

@@ -34,7 +34,8 @@ class d3d12_video_bitstream_builder_h264 : public d3d12_video_bitstream_builder_
d3d12_video_bitstream_builder_h264() {};
~d3d12_video_bitstream_builder_h264() {};
void build_sps(const D3D12_VIDEO_ENCODER_PROFILE_H264 & profile,
void build_sps(const struct pipe_h264_enc_seq_param & seqData,
const D3D12_VIDEO_ENCODER_PROFILE_H264 & profile,
const D3D12_VIDEO_ENCODER_LEVELS_H264 & level,
const DXGI_FORMAT & inputFmt,
const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264 & codecConfig,

View File

@@ -101,8 +101,76 @@ d3d12_video_nalu_writer_h264::write_sps_bytes(d3d12_video_encoder_bitstream *pBi
pBitstream->exp_Golomb_ue(pSPS->frame_cropping_rect_bottom_offset);
}
// We're not including the VUI so this better be zero.
pBitstream->put_bits(1, 0); // vui_paramenters_present_flag
pBitstream->put_bits(1, pSPS->vui_parameters_present_flag);
if (pSPS->vui_parameters_present_flag)
{
pBitstream->put_bits(1, pSPS->vui.aspect_ratio_info_present_flag);
if (pSPS->vui.aspect_ratio_info_present_flag) {
pBitstream->put_bits(8, pSPS->vui.aspect_ratio_idc);
if (pSPS->vui.aspect_ratio_idc == 255 /*EXTENDED_SAR*/) {
pBitstream->put_bits(16, pSPS->vui.sar_width);
pBitstream->put_bits(16, pSPS->vui.sar_height);
}
}
pBitstream->put_bits(1, pSPS->vui.overscan_info_present_flag);
if (pSPS->vui.overscan_info_present_flag) {
pBitstream->put_bits(1, pSPS->vui.overscan_appropriate_flag);
}
pBitstream->put_bits(1, pSPS->vui.video_signal_type_present_flag);
if (pSPS->vui.video_signal_type_present_flag) {
pBitstream->put_bits(3, pSPS->vui.video_format);
pBitstream->put_bits(1, pSPS->vui.video_full_range_flag);
pBitstream->put_bits(1, pSPS->vui.colour_description_present_flag);
if (pSPS->vui.colour_description_present_flag) {
pBitstream->put_bits(8, pSPS->vui.colour_primaries);
pBitstream->put_bits(8, pSPS->vui.transfer_characteristics);
pBitstream->put_bits(8, pSPS->vui.matrix_coefficients);
}
}
pBitstream->put_bits(1, pSPS->vui.chroma_loc_info_present_flag);
if (pSPS->vui.chroma_loc_info_present_flag) {
pBitstream->exp_Golomb_ue(pSPS->vui.chroma_sample_loc_type_top_field);
pBitstream->exp_Golomb_ue(pSPS->vui.chroma_sample_loc_type_bottom_field);
}
pBitstream->put_bits(1, pSPS->vui.timing_info_present_flag);
if (pSPS->vui.timing_info_present_flag) {
pBitstream->put_bits(16, pSPS->vui.num_units_in_tick >> 16);
pBitstream->put_bits(16, pSPS->vui.num_units_in_tick & 0xffff);
pBitstream->put_bits(16, pSPS->vui.time_scale >> 16);
pBitstream->put_bits(16, pSPS->vui.time_scale & 0xffff);
pBitstream->put_bits(1, pSPS->vui.fixed_frame_rate_flag);
}
pBitstream->put_bits(1, pSPS->vui.nal_hrd_parameters_present_flag);
if (pSPS->vui.nal_hrd_parameters_present_flag) {
write_hrd(pBitstream, &pSPS->vui.nal_hrd_parameters);
}
pBitstream->put_bits(1, pSPS->vui.vcl_hrd_parameters_present_flag);
if (pSPS->vui.vcl_hrd_parameters_present_flag) {
write_hrd(pBitstream, &pSPS->vui.vcl_hrd_parameters);
}
if (pSPS->vui.nal_hrd_parameters_present_flag || pSPS->vui.vcl_hrd_parameters_present_flag) {
pBitstream->put_bits(1, pSPS->vui.low_delay_hrd_flag);
}
pBitstream->put_bits(1, pSPS->vui.pic_struct_present_flag);
pBitstream->put_bits(1, pSPS->vui.bitstream_restriction_flag);
if (pSPS->vui.bitstream_restriction_flag) {
pBitstream->put_bits(1, pSPS->vui.motion_vectors_over_pic_boundaries_flag);
pBitstream->exp_Golomb_ue(pSPS->vui.max_bytes_per_pic_denom);
pBitstream->exp_Golomb_ue(pSPS->vui.max_bits_per_mb_denom);
pBitstream->exp_Golomb_ue(pSPS->vui.log2_max_mv_length_horizontal);
pBitstream->exp_Golomb_ue(pSPS->vui.log2_max_mv_length_vertical);
pBitstream->exp_Golomb_ue(pSPS->vui.num_reorder_frames);
pBitstream->exp_Golomb_ue(pSPS->vui.max_dec_frame_buffering);
}
}
rbsp_trailing(pBitstream);
pBitstream->flush();
@@ -111,6 +179,23 @@ d3d12_video_nalu_writer_h264::write_sps_bytes(d3d12_video_encoder_bitstream *pBi
return (uint32_t) iBytesWritten;
}
void
d3d12_video_nalu_writer_h264::write_hrd(d3d12_video_encoder_bitstream *pBitstream, H264_HRD_PARAMS *pHrd)
{
pBitstream->exp_Golomb_ue(pHrd->cpb_cnt_minus1);
pBitstream->put_bits(4, pHrd->bit_rate_scale);
pBitstream->put_bits(4, pHrd->cpb_size_scale);
for (uint32_t i = 0; i <= pHrd->cpb_cnt_minus1; i++) {
pBitstream->exp_Golomb_ue(pHrd->bit_rate_value_minus1[i]);
pBitstream->exp_Golomb_ue(pHrd->cpb_size_value_minus1[i]);
pBitstream->put_bits(1, pHrd->cbr_flag[i]);
}
pBitstream->put_bits(5, pHrd->initial_cpb_removal_delay_length_minus1);
pBitstream->put_bits(5, pHrd->cpb_removal_delay_length_minus1);
pBitstream->put_bits(5, pHrd->dpb_output_delay_length_minus1);
pBitstream->put_bits(5, pHrd->time_offset_length);
}
uint32_t
d3d12_video_nalu_writer_h264::write_pps_bytes(d3d12_video_encoder_bitstream *pBitstream,
H264_PPS * pPPS,

View File

@@ -55,6 +55,58 @@ enum H264_NALU_TYPE
/* 24...31 UNSPECIFIED */
};
typedef struct H264_HRD_PARAMS
{
uint32_t cpb_cnt_minus1;
uint32_t bit_rate_scale;
uint32_t cpb_size_scale;
uint32_t bit_rate_value_minus1[32];
uint32_t cpb_size_value_minus1[32];
uint32_t cbr_flag[32];
uint32_t initial_cpb_removal_delay_length_minus1;
uint32_t cpb_removal_delay_length_minus1;
uint32_t dpb_output_delay_length_minus1;
uint32_t time_offset_length;
} H264_HRD_PARAMS;
struct H264_VUI_PARAMS
{
uint32_t aspect_ratio_info_present_flag;
uint32_t aspect_ratio_idc;
uint32_t sar_width;
uint32_t sar_height;
uint32_t overscan_info_present_flag;
uint32_t overscan_appropriate_flag;
uint32_t video_signal_type_present_flag;
uint32_t video_format;
uint32_t video_full_range_flag;
uint32_t colour_description_present_flag;
uint32_t colour_primaries;
uint32_t transfer_characteristics;
uint32_t matrix_coefficients;
uint32_t chroma_loc_info_present_flag;
uint32_t chroma_sample_loc_type_top_field;
uint32_t chroma_sample_loc_type_bottom_field;
uint32_t timing_info_present_flag;
uint32_t time_scale;
uint32_t num_units_in_tick;
uint32_t fixed_frame_rate_flag;
uint32_t nal_hrd_parameters_present_flag;
H264_HRD_PARAMS nal_hrd_parameters;
uint32_t vcl_hrd_parameters_present_flag;
H264_HRD_PARAMS vcl_hrd_parameters;
uint32_t low_delay_hrd_flag;
uint32_t pic_struct_present_flag;
uint32_t bitstream_restriction_flag;
uint32_t motion_vectors_over_pic_boundaries_flag;
uint32_t max_bytes_per_pic_denom;
uint32_t max_bits_per_mb_denom;
uint32_t log2_max_mv_length_vertical;
uint32_t log2_max_mv_length_horizontal;
uint32_t num_reorder_frames;
uint32_t max_dec_frame_buffering;
};
struct H264_SPS
{
uint32_t profile_idc;
@@ -77,6 +129,8 @@ struct H264_SPS
uint32_t frame_cropping_rect_right_offset;
uint32_t frame_cropping_rect_top_offset;
uint32_t frame_cropping_rect_bottom_offset;
uint32_t vui_parameters_present_flag;
H264_VUI_PARAMS vui;
};
struct H264_PPS
@@ -141,6 +195,7 @@ class d3d12_video_nalu_writer_h264
uint32_t wrap_pps_nalu(d3d12_video_encoder_bitstream *pNALU, d3d12_video_encoder_bitstream *pRBSP);
// Helpers
void write_hrd(d3d12_video_encoder_bitstream *pBitstream, H264_HRD_PARAMS *pHrd);
void write_nalu_end(d3d12_video_encoder_bitstream *pNALU);
void rbsp_trailing(d3d12_video_encoder_bitstream *pBitstream);
uint32_t wrap_rbsp_into_nalu(d3d12_video_encoder_bitstream *pNALU,