diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.h b/src/gallium/drivers/d3d12/d3d12_video_enc.h index 8e62be4271c..699278c9f33 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.h +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.h @@ -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 pendingShowableFrames; } m_encoderCodecSpecificStateDescAV1; + struct pipe_h264_enc_seq_param m_encoderCodecSpecificSequenceStateDescH264; }; struct EncodedBitstreamResolvedMetadata diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp index 36215843522..37a80d5baae 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp @@ -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(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, diff --git a/src/gallium/drivers/d3d12/d3d12_video_encoder_bitstream_builder_h264.cpp b/src/gallium/drivers/d3d12/d3d12_video_encoder_bitstream_builder_h264.cpp index 54b76ea948d..d53664b057a 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_encoder_bitstream_builder_h264.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_encoder_bitstream_builder_h264.cpp @@ -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"); } diff --git a/src/gallium/drivers/d3d12/d3d12_video_encoder_bitstream_builder_h264.h b/src/gallium/drivers/d3d12/d3d12_video_encoder_bitstream_builder_h264.h index c44eb1898b5..7be98e18b93 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_encoder_bitstream_builder_h264.h +++ b/src/gallium/drivers/d3d12/d3d12_video_encoder_bitstream_builder_h264.h @@ -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, diff --git a/src/gallium/drivers/d3d12/d3d12_video_encoder_nalu_writer_h264.cpp b/src/gallium/drivers/d3d12/d3d12_video_encoder_nalu_writer_h264.cpp index 10a8090a009..5e0f218de4e 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_encoder_nalu_writer_h264.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_encoder_nalu_writer_h264.cpp @@ -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, diff --git a/src/gallium/drivers/d3d12/d3d12_video_encoder_nalu_writer_h264.h b/src/gallium/drivers/d3d12/d3d12_video_encoder_nalu_writer_h264.h index 77477054609..a20c17b4357 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_encoder_nalu_writer_h264.h +++ b/src/gallium/drivers/d3d12/d3d12_video_encoder_nalu_writer_h264.h @@ -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,