d3d12: Support H264 slice L0/L1 active number override

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28424>
This commit is contained in:
Sil Vilerino
2024-03-19 11:39:33 -04:00
committed by Marge Bot
parent cc04a04f13
commit 33336a2766
3 changed files with 95 additions and 69 deletions
@@ -351,7 +351,13 @@ d3d12_video_encoder_update_current_frame_pic_params_info_h264(struct d3d12_video
bUsedAsReference = !h264Pic->not_referenced;
picParams.pH264PicData->pic_parameter_set_id = pH264BitstreamBuilder->get_active_pps_id();
if (pD3D12Enc->m_currentEncodeCapabilities.m_encoderCodecSpecificConfigCaps.m_H264CodecCaps.SupportFlags &
D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264_FLAG_NUM_REF_IDX_ACTIVE_OVERRIDE_FLAG_SLICE_SUPPORT)
{
picParams.pH264PicData->Flags |= D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_H264_FLAG_REQUEST_NUM_REF_IDX_ACTIVE_OVERRIDE_FLAG_SLICE;
}
picParams.pH264PicData->pic_parameter_set_id = pH264BitstreamBuilder->get_active_pps().pic_parameter_set_id;
picParams.pH264PicData->idr_pic_id = h264Pic->idr_pic_id;
picParams.pH264PicData->FrameType = d3d12_video_encoder_convert_frame_type_h264(h264Pic->picture_type);
picParams.pH264PicData->PictureOrderCountNumber = h264Pic->pic_order_cnt;
@@ -1117,6 +1123,31 @@ d3d12_video_encoder_compare_slice_config_h264_hevc(
sizeof(D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES)) == 0);
}
static inline bool
d3d12_video_encoder_needs_new_pps_h264(struct d3d12_video_encoder *pD3D12Enc,
bool writeNewSPS,
H264_PPS &tentative_pps,
const H264_PPS &active_pps)
{
bool bUseSliceL0L1Override = (pD3D12Enc->m_currentEncodeConfig.m_encoderPicParamsDesc.m_H264PicData.Flags &
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_H264_FLAG_REQUEST_NUM_REF_IDX_ACTIVE_OVERRIDE_FLAG_SLICE);
bool bDifferentL0L1Lists = !bUseSliceL0L1Override &&
((tentative_pps.num_ref_idx_l0_active_minus1 != active_pps.num_ref_idx_l0_active_minus1) ||
(tentative_pps.num_ref_idx_l1_active_minus1 != active_pps.num_ref_idx_l1_active_minus1));
bool bDidPPSChange =
((tentative_pps.constrained_intra_pred_flag != active_pps.constrained_intra_pred_flag) ||
(tentative_pps.entropy_coding_mode_flag != active_pps.entropy_coding_mode_flag) ||
bDifferentL0L1Lists ||
(tentative_pps.pic_order_present_flag != active_pps.pic_order_present_flag) ||
(tentative_pps.pic_parameter_set_id != active_pps.pic_parameter_set_id) ||
(tentative_pps.seq_parameter_set_id != active_pps.seq_parameter_set_id) ||
(tentative_pps.transform_8x8_mode_flag != active_pps.transform_8x8_mode_flag));
return writeNewSPS || bDidPPSChange;
}
uint32_t
d3d12_video_encoder_build_codec_headers_h264(struct d3d12_video_encoder *pD3D12Enc,
std::vector<uint64_t> &pWrittenCodecUnitsSizes)
@@ -1149,41 +1180,40 @@ d3d12_video_encoder_build_codec_headers_h264(struct d3d12_video_encoder *pD3D12E
// Also on input format dirty flag for new SPS, VUI etc
|| (pD3D12Enc->m_currentEncodeConfig.m_ConfigDirtyFlags & d3d12_video_encoder_config_dirty_flag_sequence_info);
uint32_t active_seq_parameter_set_id = pH264BitstreamBuilder->get_active_sps_id();
uint32_t active_seq_parameter_set_id = pH264BitstreamBuilder->get_active_sps().seq_parameter_set_id;
size_t writtenSPSBytesCount = 0;
if (writeNewSPS) {
pH264BitstreamBuilder->build_sps(pD3D12Enc->m_currentEncodeConfig.m_encoderCodecSpecificSequenceStateDescH264,
pD3D12Enc->base.profile,
*levelDesc.pH264LevelSetting,
pD3D12Enc->m_currentEncodeConfig.m_encodeFormatInfo.Format,
*codecConfigDesc.pH264Config,
pD3D12Enc->m_currentEncodeConfig.m_encoderGOPConfigDesc.m_H264GroupOfPictures,
active_seq_parameter_set_id,
MaxDPBCapacity, // max_num_ref_frames
pD3D12Enc->m_currentEncodeConfig.m_currentResolution,
pD3D12Enc->m_currentEncodeConfig.m_FrameCroppingCodecConfig,
pD3D12Enc->m_BitstreamHeadersBuffer,
pD3D12Enc->m_BitstreamHeadersBuffer.begin() + writtenAUDBytesCount,
writtenSPSBytesCount);
H264_SPS sps = pH264BitstreamBuilder->build_sps(pD3D12Enc->m_currentEncodeConfig.m_encoderCodecSpecificSequenceStateDescH264,
pD3D12Enc->base.profile,
*levelDesc.pH264LevelSetting,
pD3D12Enc->m_currentEncodeConfig.m_encodeFormatInfo.Format,
*codecConfigDesc.pH264Config,
pD3D12Enc->m_currentEncodeConfig.m_encoderGOPConfigDesc.m_H264GroupOfPictures,
active_seq_parameter_set_id,
MaxDPBCapacity, // max_num_ref_frames
pD3D12Enc->m_currentEncodeConfig.m_currentResolution,
pD3D12Enc->m_currentEncodeConfig.m_FrameCroppingCodecConfig,
pD3D12Enc->m_BitstreamHeadersBuffer,
pD3D12Enc->m_BitstreamHeadersBuffer.begin() + writtenAUDBytesCount,
writtenSPSBytesCount);
pH264BitstreamBuilder->set_active_sps(sps);
pWrittenCodecUnitsSizes.push_back(writtenSPSBytesCount);
}
size_t writtenPPSBytesCount = 0;
pH264BitstreamBuilder->build_pps(pD3D12Enc->base.profile,
*codecConfigDesc.pH264Config,
*currentPicParams.pH264PicData,
currentPicParams.pH264PicData->pic_parameter_set_id,
active_seq_parameter_set_id,
pD3D12Enc->m_StagingHeadersBuffer,
pD3D12Enc->m_StagingHeadersBuffer.begin(),
writtenPPSBytesCount);
H264_PPS tentative_pps = pH264BitstreamBuilder->build_pps(pD3D12Enc->base.profile,
*codecConfigDesc.pH264Config,
*currentPicParams.pH264PicData,
currentPicParams.pH264PicData->pic_parameter_set_id,
active_seq_parameter_set_id,
pD3D12Enc->m_StagingHeadersBuffer,
pD3D12Enc->m_StagingHeadersBuffer.begin(),
writtenPPSBytesCount);
std::vector<uint8_t>& active_pps = pH264BitstreamBuilder->get_active_pps();
if (writeNewSPS ||
(writtenPPSBytesCount != active_pps.size()) ||
memcmp(pD3D12Enc->m_StagingHeadersBuffer.data(), active_pps.data(), writtenPPSBytesCount)) {
active_pps = pD3D12Enc->m_StagingHeadersBuffer;
const H264_PPS &active_pps = pH264BitstreamBuilder->get_active_pps();
if (d3d12_video_encoder_needs_new_pps_h264(pD3D12Enc, writeNewSPS, tentative_pps, active_pps)) {
pH264BitstreamBuilder->set_active_pps(tentative_pps);
pD3D12Enc->m_BitstreamHeadersBuffer.resize(writtenAUDBytesCount + writtenSPSBytesCount + writtenPPSBytesCount);
memcpy(&pD3D12Enc->m_BitstreamHeadersBuffer.data()[writtenAUDBytesCount + writtenSPSBytesCount], pD3D12Enc->m_StagingHeadersBuffer.data(), writtenPPSBytesCount);
pWrittenCodecUnitsSizes.push_back(writtenPPSBytesCount);
@@ -53,7 +53,7 @@ Convert12ToSpecH264Profiles(D3D12_VIDEO_ENCODER_PROFILE_H264 profile12)
}
}
void
H264_SPS
d3d12_video_bitstream_builder_h264::build_sps(const struct pipe_h264_enc_seq_param & seqData,
const enum pipe_video_profile & profile,
const D3D12_VIDEO_ENCODER_LEVELS_H264 & level,
@@ -168,6 +168,8 @@ d3d12_video_bitstream_builder_h264::build_sps(const struct pipe_h264_enc_seq_par
// Convert the H264 SPS structure into bytes
m_h264Encoder.sps_to_nalu_bytes(&spsStructure, headerBitstream, placingPositionStart, writtenBytes);
return spsStructure;
}
void
@@ -194,7 +196,7 @@ d3d12_video_bitstream_builder_h264::write_aud(std::vector<uint8_t> & hea
m_h264Encoder.write_access_unit_delimiter_nalu(headerBitstream, placingPositionStart, writtenBytes);
}
void
H264_PPS
d3d12_video_bitstream_builder_h264::build_pps(const enum pipe_video_profile & profile,
const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264 & codecConfig,
const D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_H264 &pictureControl,
@@ -236,6 +238,8 @@ d3d12_video_bitstream_builder_h264::build_pps(const enum pipe_video_profile &
// Convert the H264 SPS structure into bytes
m_h264Encoder.pps_to_nalu_bytes(&ppsStructure, headerBitstream, bIsHighProfile, placingPositionStart, writtenBytes);
return ppsStructure;
}
void
@@ -34,28 +34,28 @@ class d3d12_video_bitstream_builder_h264 : public d3d12_video_bitstream_builder_
d3d12_video_bitstream_builder_h264(bool insert_aud_nalu = false);
~d3d12_video_bitstream_builder_h264() {};
void build_sps(const struct pipe_h264_enc_seq_param & seqData,
const enum pipe_video_profile & profile,
const D3D12_VIDEO_ENCODER_LEVELS_H264 & level,
const DXGI_FORMAT & inputFmt,
const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264 & codecConfig,
const D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_H264 &gopConfig,
uint32_t seq_parameter_set_id,
uint32_t max_num_ref_frames,
D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC sequenceTargetResolution,
D3D12_BOX frame_cropping_codec_config,
std::vector<uint8_t> & headerBitstream,
std::vector<uint8_t>::iterator placingPositionStart,
size_t & writtenBytes);
H264_SPS build_sps(const struct pipe_h264_enc_seq_param & seqData,
const enum pipe_video_profile & profile,
const D3D12_VIDEO_ENCODER_LEVELS_H264 & level,
const DXGI_FORMAT & inputFmt,
const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264 & codecConfig,
const D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_H264 &gopConfig,
uint32_t seq_parameter_set_id,
uint32_t max_num_ref_frames,
D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC sequenceTargetResolution,
D3D12_BOX frame_cropping_codec_config,
std::vector<uint8_t> & headerBitstream,
std::vector<uint8_t>::iterator placingPositionStart,
size_t & writtenBytes);
void build_pps(const enum pipe_video_profile & profile,
const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264 & codecConfig,
const D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_H264 &pictureControl,
uint32_t pic_parameter_set_id,
uint32_t seq_parameter_set_id,
std::vector<uint8_t> & headerBitstream,
std::vector<uint8_t>::iterator placingPositionStart,
size_t & writtenBytes);
H264_PPS build_pps(const enum pipe_video_profile & profile,
const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264 & codecConfig,
const D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_H264 &pictureControl,
uint32_t pic_parameter_set_id,
uint32_t seq_parameter_set_id,
std::vector<uint8_t> & headerBitstream,
std::vector<uint8_t>::iterator placingPositionStart,
size_t & writtenBytes);
void write_end_of_stream_nalu(std::vector<uint8_t> & headerBitstream,
std::vector<uint8_t>::iterator placingPositionStart,
@@ -71,38 +71,30 @@ class d3d12_video_bitstream_builder_h264 : public d3d12_video_bitstream_builder_
void print_pps(const H264_PPS &pps);
void print_sps(const H264_SPS &sps);
uint32_t get_active_sps_id()
const H264_SPS& get_active_sps()
{
return m_activeSPSIndex;
return m_activeSPSStructure;
};
uint32_t get_active_pps_id()
const H264_PPS& get_active_pps()
{
return m_activePPSIndex;
return m_activePPSStructure;
};
std::vector<uint8_t>& get_active_pps()
void set_active_sps(H264_SPS &active_sps)
{
return m_activePPS;
m_activeSPSStructure = active_sps;
};
void set_active_sps_id(uint32_t active_sps_id)
void set_active_pps(H264_PPS &active_pps)
{
m_activeSPSIndex = active_sps_id;
debug_printf("[d3d12_video_bitstream_builder_h264] Setting new active SPS ID: %d ", m_activeSPSIndex);
};
void set_active_pps_id(uint32_t active_pps_id)
{
m_activePPSIndex = active_pps_id;
debug_printf("[d3d12_video_bitstream_builder_h264] Setting new active PPS ID: %d ", m_activePPSIndex);
m_activePPSStructure = active_pps;
};
bool insert_aud_nalu_requested() { return m_insert_aud_nalu; }
private:
d3d12_video_nalu_writer_h264 m_h264Encoder;
std::vector<uint8_t> m_activePPS;
uint32_t m_activeSPSIndex = 0;
uint32_t m_activePPSIndex = 0;
H264_SPS m_activeSPSStructure = {};
H264_PPS m_activePPSStructure = {};
bool m_insert_aud_nalu = false;
};