diff --git a/src/gallium/frontends/mediafoundation/encode.cpp b/src/gallium/frontends/mediafoundation/encode.cpp index 1f2180ec7be..4517842215f 100644 --- a/src/gallium/frontends/mediafoundation/encode.cpp +++ b/src/gallium/frontends/mediafoundation/encode.cpp @@ -326,7 +326,8 @@ CDX12EncHMFT::PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12E } // Try to get MFSampleExtension_MoveRegions blob only when the HW supports it. - if( m_EncoderCapabilities.m_HWSupportMoveRects.bits.supports_precision_full_pixel && m_EncoderCapabilities.m_HWSupportMoveRects.bits.max_motion_hints > 0) + if( m_EncoderCapabilities.m_HWSupportMoveRects.bits.supports_precision_full_pixel && + m_EncoderCapabilities.m_HWSupportMoveRects.bits.max_motion_hints > 0 ) { UINT32 cMoveRegionBlob = 0; pSample->GetBlobSize( MFSampleExtension_MoveRegions, &cMoveRegionBlob ); @@ -336,7 +337,8 @@ CDX12EncHMFT::PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12E { m_pMoveRegionBlob.resize( cMoveRegionBlob ); } - if( S_OK == pSample->GetBlob( MFSampleExtension_MoveRegions, m_pMoveRegionBlob.data(), cMoveRegionBlob, &cMoveRegionBlob ) ) + if( S_OK == + pSample->GetBlob( MFSampleExtension_MoveRegions, m_pMoveRegionBlob.data(), cMoveRegionBlob, &cMoveRegionBlob ) ) { MOVEREGION_INFO *pMoveRegionInfo = (MOVEREGION_INFO *) m_pMoveRegionBlob.data(); moveRegionFrameNum = pMoveRegionInfo->FrameNumber; @@ -491,9 +493,6 @@ CDX12EncHMFT::PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12E } } - // pDX12EncodeContext->encoderPicInfo is initialized to zero in DX12EncodeContext constructor already - pDX12EncodeContext->encoderPicInfo.base.profile = m_outputPipeProfile; - // Encode region of interest // When m_bVideoROIEnabled, app can (or not) set MFSampleExtension_ROIRectangle on separate frames optionally if( m_bVideoROIEnabled ) @@ -559,7 +558,12 @@ CDX12EncHMFT::PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12E // Call the helper for encoder specific work pDX12EncodeContext->encoderPicInfo.base.in_fence = pPipeEncoderInputFenceHandle; pDX12EncodeContext->encoderPicInfo.base.in_fence_value = pipeEncoderInputFenceHandleValue; - CHECKHR_GOTO( PrepareForEncodeHelper( pDX12EncodeContext, bReceivedDirtyRectBlob, dirtyRectFrameNum, bReceivedMoveRegionBlob, moveRegionFrameNum ), done ); + CHECKHR_GOTO( PrepareForEncodeHelper( pDX12EncodeContext, + bReceivedDirtyRectBlob, + dirtyRectFrameNum, + bReceivedMoveRegionBlob, + moveRegionFrameNum ), + done ); // Needs to be run after PrepareForEncodeHelper to know if current frame is used as reference // Only allocate reconstructed picture copy buffer if feature is enabled and supported diff --git a/src/gallium/frontends/mediafoundation/encode_av1.cpp b/src/gallium/frontends/mediafoundation/encode_av1.cpp index 9109c72a6bc..fd8b620747b 100644 --- a/src/gallium/frontends/mediafoundation/encode_av1.cpp +++ b/src/gallium/frontends/mediafoundation/encode_av1.cpp @@ -29,7 +29,19 @@ extern DWORD CalculateQualityFromQP( DWORD QP ); HRESULT -CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bool dirtyRectFrameNumSet, uint32_t dirtyRectFrameNum, bool moveRegionFrameNumSet, uint32_t moveRegionFrameNum ) +CDX12EncHMFT::UpdateAV1EncPictureDesc( pipe_av1_enc_picture_desc *pPicInfo ) +{ + HRESULT hr = S_OK; + // done: + return hr; +} + +HRESULT +CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, + bool dirtyRectFrameNumSet, + uint32_t dirtyRectFrameNum, + bool moveRegionFrameNumSet, + uint32_t moveRegionFrameNum ) { HRESULT hr = S_OK; // done: diff --git a/src/gallium/frontends/mediafoundation/encode_h264.cpp b/src/gallium/frontends/mediafoundation/encode_h264.cpp index bf91c6e8c3f..70d42df1173 100644 --- a/src/gallium/frontends/mediafoundation/encode_h264.cpp +++ b/src/gallium/frontends/mediafoundation/encode_h264.cpp @@ -113,90 +113,118 @@ ConstraintSetFlagsFromProfile( eAVEncH264VProfile profile ) } // utility function to fill in encoder picture descriptor (pPicInfo) which is used to pass information to DX12 encoder -static void -UpdateH264EncPictureDesc( pipe_h264_enc_picture_desc *pPicInfo, - const pipe_video_codec *pPipeVideoCodec, - const encoder_capabilities &EncoderCapabilities, - const eAVEncH264VProfile uiProfile, - const enum pipe_video_profile outputPipeProfile, - const VUInfo &VUIInfo, - const MFRatio &FrameRate, - BOOL bCabacEnable ) +HRESULT +CDX12EncHMFT::UpdateH264EncPictureDesc( pipe_h264_enc_picture_desc *pPicInfo, const uint32_t intra_period, const uint32_t ip_period ) { - if( EncoderCapabilities.m_bHWSupportsH264CABACEncode ) + HRESULT hr = S_OK; + + // fields are arranged in the same order as pipe_h264_enc_picture_desc + // base + pPicInfo->base.profile = m_outputPipeProfile; + + // seq + pPicInfo->seq.enc_frame_cropping_flag = m_bFrameCroppingFlag; + pPicInfo->seq.vui_parameters_present_flag = 1; // VUI Data - always true because we have timing_info_present_flag = 1 + pPicInfo->seq.video_full_range_flag = m_VUIInfo.stVidSigType.bVideoFullRangeFlag; + + pPicInfo->seq.enc_constraint_set_flags = ConstraintSetFlagsFromProfile( m_uiProfile ); + pPicInfo->seq.level_idc = m_pPipeVideoCodec->level; + + pPicInfo->seq.enc_frame_crop_right_offset = m_uiFrameCropRightOffset; + pPicInfo->seq.enc_frame_crop_bottom_offset = m_uiFrameCropBottomOffset; + + /* TODO: check if we need this in gop_info. + pPicInfo->seq.pic_order_cnt_type = cur_frame_desc->gop_info->pic_order_cnt_type; + pPicInfo->seq.log2_max_frame_num_minus4 = cur_frame_desc->gop_info->log2_max_frame_num_minus4; + pPicInfo->seq.log2_max_pic_order_cnt_lsb_minus4 = cur_frame_desc->gop_info->log2_max_pic_order_cnt_lsb_minus4; + */ + + pPicInfo->seq.pic_order_cnt_type = ( ip_period > 2 ) ? 0u : 2u; // 2 consecutive non reference frames -> 0u + pPicInfo->seq.log2_max_frame_num_minus4 = 4; + pPicInfo->seq.log2_max_pic_order_cnt_lsb_minus4 = pPicInfo->seq.log2_max_frame_num_minus4 + 1; + + pPicInfo->seq.num_temporal_layers = m_bLayerCountSet ? HMFT_MAX_TEMPORAL_LAYERS : 1; + + + if( m_EncoderCapabilities.m_bHWSupportsH264CABACEncode ) { pPicInfo->pic_ctrl.enc_cabac_enable = ( ( pPicInfo->base.profile == PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN ) || ( pPicInfo->base.profile == PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH ) ) && - bCabacEnable ? + m_bCabacEnable ? true : false; } - pPicInfo->base.profile = outputPipeProfile; - pPicInfo->seq.level_idc = pPipeVideoCodec->level; - pPicInfo->seq.max_num_ref_frames = pPipeVideoCodec->max_references; - - // VUI Data - always true because we have timing_info_present_flag = 1 - pPicInfo->seq.vui_parameters_present_flag = 1; - - // SAR - aspect ratio - pPicInfo->seq.vui_flags.aspect_ratio_info_present_flag = VUIInfo.bEnableSAR; - pPicInfo->seq.aspect_ratio_idc = 255 /* EXTENDED_SAR */; - pPicInfo->seq.sar_width = VUIInfo.stSARInfo.usWidth; - pPicInfo->seq.sar_height = VUIInfo.stSARInfo.usHeight; - - // VST - video signal type - pPicInfo->seq.vui_flags.video_signal_type_present_flag = VUIInfo.bEnableVST; - pPicInfo->seq.video_format = VUIInfo.stVidSigType.eVideoFormat; - pPicInfo->seq.video_full_range_flag = VUIInfo.stVidSigType.bVideoFullRangeFlag; - pPicInfo->seq.vui_flags.colour_description_present_flag = VUIInfo.stVidSigType.bColorInfoPresent; - pPicInfo->seq.colour_primaries = VUIInfo.stVidSigType.eColorPrimary; - pPicInfo->seq.transfer_characteristics = VUIInfo.stVidSigType.eColorTransfer; - pPicInfo->seq.matrix_coefficients = VUIInfo.stVidSigType.eColorMatrix; + pPicInfo->seq.max_num_ref_frames = m_pPipeVideoCodec->max_references; + pPicInfo->seq.vui_flags.aspect_ratio_info_present_flag = m_VUIInfo.bEnableSAR; pPicInfo->seq.vui_flags.timing_info_present_flag = 1; - pPicInfo->seq.vui_flags.fixed_frame_rate_flag = 1; - pPicInfo->seq.num_units_in_tick = FrameRate.Denominator; - pPicInfo->seq.time_scale = FrameRate.Numerator * 2; - + pPicInfo->seq.vui_flags.video_signal_type_present_flag = m_VUIInfo.bEnableVST; + pPicInfo->seq.vui_flags.colour_description_present_flag = m_VUIInfo.stVidSigType.bColorInfoPresent; pPicInfo->seq.vui_flags.chroma_loc_info_present_flag = 0; - pPicInfo->seq.chroma_sample_loc_type_top_field = 0; - pPicInfo->seq.chroma_sample_loc_type_bottom_field = 0; - pPicInfo->seq.vui_flags.overscan_info_present_flag = 0; pPicInfo->seq.vui_flags.overscan_appropriate_flag = 0; - + pPicInfo->seq.vui_flags.fixed_frame_rate_flag = 1; pPicInfo->seq.vui_flags.nal_hrd_parameters_present_flag = 0; - memset( &pPicInfo->seq.nal_hrd_parameters, 0, sizeof( pipe_h264_enc_hrd_params ) ); - pPicInfo->seq.vui_flags.vcl_hrd_parameters_present_flag = 0; - memset( &pPicInfo->seq.vcl_hrd_parameters, 0, sizeof( pipe_h264_enc_hrd_params ) ); - pPicInfo->seq.vui_flags.low_delay_hrd_flag = 0; pPicInfo->seq.vui_flags.pic_struct_present_flag = 0; - pPicInfo->seq.vui_flags.bitstream_restriction_flag = 1; if( pPicInfo->seq.vui_flags.bitstream_restriction_flag ) { pPicInfo->seq.vui_flags.motion_vectors_over_pic_boundaries_flag = 0; + } + + pPicInfo->seq.aspect_ratio_idc = 255; // EXTENDED_SAR + pPicInfo->seq.sar_width = m_VUIInfo.stSARInfo.usWidth; + pPicInfo->seq.sar_height = m_VUIInfo.stSARInfo.usHeight; + + pPicInfo->seq.num_units_in_tick = m_FrameRate.Denominator; + pPicInfo->seq.time_scale = m_FrameRate.Numerator * 2; + + pPicInfo->seq.video_format = m_VUIInfo.stVidSigType.eVideoFormat; // VST - video signal type + pPicInfo->seq.colour_primaries = m_VUIInfo.stVidSigType.eColorPrimary; + pPicInfo->seq.transfer_characteristics = m_VUIInfo.stVidSigType.eColorTransfer; + pPicInfo->seq.matrix_coefficients = m_VUIInfo.stVidSigType.eColorMatrix; + pPicInfo->seq.chroma_sample_loc_type_top_field = 0; + pPicInfo->seq.chroma_sample_loc_type_bottom_field = 0; + if( pPicInfo->seq.vui_flags.bitstream_restriction_flag ) + { + pPicInfo->seq.max_num_reorder_frames = 0; + } + memset( &pPicInfo->seq.nal_hrd_parameters, 0, sizeof( pipe_h264_enc_hrd_params ) ); + memset( &pPicInfo->seq.vcl_hrd_parameters, 0, sizeof( pipe_h264_enc_hrd_params ) ); + if( pPicInfo->seq.vui_flags.bitstream_restriction_flag ) + { pPicInfo->seq.max_bytes_per_pic_denom = 0; pPicInfo->seq.max_bits_per_mb_denom = 0; - pPicInfo->seq.log2_max_mv_length_horizontal = 0; pPicInfo->seq.log2_max_mv_length_vertical = 0; - pPicInfo->seq.max_num_reorder_frames = 0; + pPicInfo->seq.log2_max_mv_length_horizontal = 0; pPicInfo->seq.max_dec_frame_buffering = pPicInfo->seq.max_num_ref_frames; // TODO: compute a more accurate value. } - pPicInfo->seq.enc_constraint_set_flags = ConstraintSetFlagsFromProfile( uiProfile ); + pPicInfo->seq.enc_constraint_set_flags = ConstraintSetFlagsFromProfile( m_uiProfile ); + + pPicInfo->intra_idr_period = intra_period; + pPicInfo->ip_period = ip_period; + pPicInfo->gop_size = intra_period; + + return hr; } // internal function which contains the codec specific portion of PrepareForEncode HRESULT -CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bool dirtyRectFrameNumSet, uint32_t dirtyRectFrameNum, bool moveRegionFrameNumSet, uint32_t moveRegionFrameNum ) +CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, + bool dirtyRectFrameNumSet, + uint32_t dirtyRectFrameNum, + bool moveRegionFrameNumSet, + uint32_t moveRegionFrameNum ) { HRESULT hr = S_OK; - const reference_frames_tracker_frame_descriptor_h264 *cur_frame_desc = nullptr; pipe_h264_enc_picture_desc *pPicInfo = &pDX12EncodeContext->encoderPicInfo.h264enc; + const reference_frames_tracker_frame_descriptor_h264 *cur_frame_desc = + (const reference_frames_tracker_frame_descriptor_h264 *) m_pGOPTracker->get_frame_descriptor(); + // Initialize raw headers array pPicInfo->raw_headers = UTIL_DYNARRAY_INIT; @@ -207,18 +235,7 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo pPicInfo->requested_metadata = m_EncoderCapabilities.m_HWSupportedMetadataFlags; pPicInfo->base.input_format = pDX12EncodeContext->pPipeVideoBuffer->buffer_format; - UpdateH264EncPictureDesc( pPicInfo, - m_pPipeVideoCodec, - m_EncoderCapabilities, - m_uiProfile, - m_outputPipeProfile, - m_VUIInfo, - m_FrameRate, - m_bCabacEnable ); - - pPicInfo->seq.enc_frame_cropping_flag = m_bFrameCroppingFlag; - pPicInfo->seq.enc_frame_crop_right_offset = m_uiFrameCropRightOffset; - pPicInfo->seq.enc_frame_crop_bottom_offset = m_uiFrameCropBottomOffset; + UpdateH264EncPictureDesc( pPicInfo, cur_frame_desc->gop_info->intra_period, cur_frame_desc->gop_info->ip_period ); if( pDX12EncodeContext->bROI ) { @@ -242,7 +259,6 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo pPicInfo->dbk.disable_deblocking_filter_idc = D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_SLICES_DEBLOCKING_MODE_0_ALL_LUMA_CHROMA_SLICE_BLOCK_EDGES_ALWAYS_FILTERED; - cur_frame_desc = (const reference_frames_tracker_frame_descriptor_h264 *) m_pGOPTracker->get_frame_descriptor(); // Set the IDR exclusive long_term_reference_flag flag in the slice header or reset it to zero pPicInfo->slice.long_term_reference_flag = ( cur_frame_desc->gop_info->reference_type == frame_descriptor_reference_type_long_term && @@ -256,11 +272,6 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo pPicInfo->frame_num = cur_frame_desc->gop_info->frame_num; pPicInfo->slice.frame_num = cur_frame_desc->gop_info->frame_num; pPicInfo->idr_pic_id = cur_frame_desc->gop_info->idr_pic_id; - pPicInfo->intra_idr_period = cur_frame_desc->gop_info->intra_period; - pPicInfo->seq.pic_order_cnt_type = cur_frame_desc->gop_info->pic_order_cnt_type; - pPicInfo->ip_period = cur_frame_desc->gop_info->ip_period; - - pPicInfo->seq.num_temporal_layers = m_bLayerCountSet ? HMFT_MAX_TEMPORAL_LAYERS : 1; // Insert new headers on IDR if( pPicInfo->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR ) @@ -288,8 +299,6 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo util_dynarray_append( &pPicInfo->raw_headers, header_svc_prefix ); } - pPicInfo->seq.log2_max_frame_num_minus4 = cur_frame_desc->gop_info->log2_max_frame_num_minus4; - pPicInfo->seq.log2_max_pic_order_cnt_lsb_minus4 = cur_frame_desc->gop_info->log2_max_pic_order_cnt_lsb_minus4; pPicInfo->not_referenced = ( cur_frame_desc->gop_info->reference_type == frame_descriptor_reference_type_none ); pPicInfo->is_ltr = ( cur_frame_desc->gop_info->reference_type == frame_descriptor_reference_type_long_term ); pPicInfo->ltr_index = cur_frame_desc->gop_info->ltr_index; @@ -716,21 +725,11 @@ CDX12EncHMFT::GetCodecPrivateData( LPBYTE pSPSPPSData, DWORD dwSPSPPSDataLen, LP UINT alignedHeight = static_cast( std::ceil( m_uiOutputHeight / 16.0 ) ) * 16; int ret = EINVAL; unsigned buf_size = dwSPSPPSDataLen; + const uint32_t intra_period = m_uiGopSize; + const uint32_t ip_period = m_uiBFrameCount + 1; pipe_h264_enc_picture_desc h264_pic_desc = {}; - memset( &h264_pic_desc, 0, sizeof( h264_pic_desc ) ); - uint32_t gop_length = m_uiGopSize; - uint32_t p_picture_period = m_uiBFrameCount + 1; - - UpdateH264EncPictureDesc( &h264_pic_desc, - m_pPipeVideoCodec, - m_EncoderCapabilities, - m_uiProfile, - m_outputPipeProfile, - m_VUIInfo, - m_FrameRate, - m_bCabacEnable ); ComputeCroppingRect( alignedWidth, alignedHeight, m_uiOutputWidth, @@ -739,20 +738,13 @@ CDX12EncHMFT::GetCodecPrivateData( LPBYTE pSPSPPSData, DWORD dwSPSPPSDataLen, LP m_bFrameCroppingFlag, m_uiFrameCropRightOffset, m_uiFrameCropBottomOffset ); - h264_pic_desc.seq.enc_frame_cropping_flag = m_bFrameCroppingFlag; - h264_pic_desc.seq.enc_frame_crop_right_offset = m_uiFrameCropRightOffset; - h264_pic_desc.seq.enc_frame_crop_bottom_offset = m_uiFrameCropBottomOffset; + + UpdateH264EncPictureDesc( &h264_pic_desc, intra_period, ip_period ); h264_pic_desc.pic_order_cnt = 0; // cur_frame_desc->gop_info->picture_order_count; - h264_pic_desc.intra_idr_period = gop_length; // cur_frame_desc->gop_info->base.intra_period; - h264_pic_desc.ip_period = p_picture_period; // cur_frame_desc->gop_info->base.ip_period; h264_pic_desc.picture_type = PIPE_H2645_ENC_PICTURE_TYPE_IDR; // cur_frame_desc->gop_info->frame_type; h264_pic_desc.frame_num = 0; // cur_frame_desc->gop_info->frame_num; h264_pic_desc.idr_pic_id = 0; // cur_frame_desc->gop_info->idr_pic_id; - h264_pic_desc.gop_size = gop_length; - h264_pic_desc.seq.pic_order_cnt_type = ( p_picture_period > 2 ) ? 0u : 2u; // 2 consecutive non reference frames -> 0u - h264_pic_desc.seq.log2_max_frame_num_minus4 = 4; - h264_pic_desc.seq.log2_max_pic_order_cnt_lsb_minus4 = h264_pic_desc.seq.log2_max_frame_num_minus4 + 1; // Rate Control if( m_uiRateControlMode == eAVEncCommonRateControlMode_CBR ) diff --git a/src/gallium/frontends/mediafoundation/encode_hevc.cpp b/src/gallium/frontends/mediafoundation/encode_hevc.cpp index 6eb966509ed..4784a1e791a 100644 --- a/src/gallium/frontends/mediafoundation/encode_hevc.cpp +++ b/src/gallium/frontends/mediafoundation/encode_hevc.cpp @@ -77,46 +77,134 @@ ComputeCroppingRect( const UINT32 textureWidth, } } -// utility function to fill in encoder picture descriptor (pPicInfo) which is used to pass information to DX12 encoder -static void -UpdateH265EncPictureDesc( pipe_h265_enc_picture_desc *pPicInfo, - const encoder_capabilities &EncoderCapabilities, - const VUInfo &VUIInfo, - const MFRatio &FrameRate ) +HRESULT +CDX12EncHMFT::UpdateH265EncPictureDesc( pipe_h265_enc_picture_desc *pPicInfo, + const uint32_t intra_period, + const uint32_t ip_period, + const uint8_t log2_max_pic_order_cnt_lsb_minus4, + const uint16_t pic_width_in_luma_samples, + const uint16_t pic_height_in_luma_samples ) { + HRESULT hr = S_OK; + + // fields are arranged in the same order as pipe_h265_enc_picture_desc + // base + pPicInfo->base.profile = m_outputPipeProfile; + + // vid + pPicInfo->vid.vps_sub_layer_ordering_info_present_flag = 0; + pPicInfo->vid.vps_max_sub_layers_minus1 = 0; + for( int i = ( pPicInfo->vid.vps_sub_layer_ordering_info_present_flag ? 0 : pPicInfo->vid.vps_max_sub_layers_minus1 ); + i <= pPicInfo->vid.vps_max_sub_layers_minus1; + i++ ) + { + pPicInfo->vid.vps_max_dec_pic_buffering_minus1[i] = static_cast( m_pPipeVideoCodec->max_references - 1 ); + pPicInfo->vid.vps_max_num_reorder_pics[i] = 0; // TODO: B-frames / reordering + pPicInfo->vid.vps_max_latency_increase_plus1[i] = 0 + 1; // TODO: B-frames + } + + // seq + pPicInfo->seq.conformance_window_flag = m_bFrameCroppingFlag; + pPicInfo->seq.vui_parameters_present_flag = 1; + pPicInfo->seq.video_full_range_flag = m_VUIInfo.stVidSigType.bVideoFullRangeFlag; + + pPicInfo->seq.general_profile_idc = static_cast( m_pPipeVideoCodec->profile ); + pPicInfo->seq.general_level_idc = static_cast( m_pPipeVideoCodec->level ); + + pPicInfo->seq.intra_period = intra_period; + pPicInfo->seq.ip_period = ip_period; + pPicInfo->seq.pic_width_in_luma_samples = pic_width_in_luma_samples; + pPicInfo->seq.pic_height_in_luma_samples = pic_height_in_luma_samples; + pPicInfo->seq.chroma_format_idc = GetChromaFormatIdc( ConvertProfileToFormat( m_outputPipeProfile ) ); + + pPicInfo->seq.log2_max_pic_order_cnt_lsb_minus4 = log2_max_pic_order_cnt_lsb_minus4; + pPicInfo->seq.log2_min_luma_coding_block_size_minus3 = + m_EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_min_luma_coding_block_size_minus3; + pPicInfo->seq.log2_min_transform_block_size_minus2 = + m_EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_min_luma_transform_block_size_minus2; + pPicInfo->seq.log2_diff_max_min_transform_block_size = static_cast( + ( m_EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_max_luma_transform_block_size_minus2 + 2 ) - + ( m_EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_min_luma_transform_block_size_minus2 + 2 ) ); + pPicInfo->seq.log2_diff_max_min_luma_coding_block_size = + static_cast( ( m_EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_max_coding_tree_block_size_minus3 + 3 ) - + ( m_EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_min_luma_coding_block_size_minus3 + 3 ) ); + pPicInfo->seq.max_transform_hierarchy_depth_inter = + m_EncoderCapabilities.m_HWSupportH265BlockSizes.bits.min_max_transform_hierarchy_depth_inter; + pPicInfo->seq.max_transform_hierarchy_depth_intra = + m_EncoderCapabilities.m_HWSupportH265BlockSizes.bits.min_max_transform_hierarchy_depth_intra; + + pPicInfo->seq.conf_win_right_offset = static_cast( m_uiFrameCropRightOffset ); + pPicInfo->seq.conf_win_bottom_offset = static_cast( m_uiFrameCropBottomOffset ); + + pPicInfo->seq.sps_max_sub_layers_minus1 = static_cast( m_uiLayerCount - 1 ); + + pPicInfo->seq.vui_flags.aspect_ratio_info_present_flag = m_VUIInfo.bEnableSAR; + pPicInfo->seq.vui_flags.timing_info_present_flag = 1; + pPicInfo->seq.vui_flags.video_signal_type_present_flag = m_VUIInfo.bEnableVST; + pPicInfo->seq.vui_flags.colour_description_present_flag = m_VUIInfo.stVidSigType.bColorInfoPresent; + pPicInfo->seq.vui_flags.chroma_loc_info_present_flag = 0; + pPicInfo->seq.vui_flags.overscan_info_present_flag = 0; + pPicInfo->seq.vui_flags.overscan_appropriate_flag = 0; + + pPicInfo->seq.vui_flags.bitstream_restriction_flag = 1; + + pPicInfo->seq.aspect_ratio_idc = 255 /* EXTENDED_SAR */; + pPicInfo->seq.sar_width = m_VUIInfo.stSARInfo.usWidth; + pPicInfo->seq.sar_height = m_VUIInfo.stSARInfo.usHeight; + + pPicInfo->seq.num_units_in_tick = m_FrameRate.Denominator; + pPicInfo->seq.time_scale = m_FrameRate.Numerator * 2; + + pPicInfo->seq.video_format = m_VUIInfo.stVidSigType.eVideoFormat; + pPicInfo->seq.colour_primaries = m_VUIInfo.stVidSigType.eColorPrimary; + pPicInfo->seq.transfer_characteristics = m_VUIInfo.stVidSigType.eColorTransfer; + pPicInfo->seq.matrix_coefficients = m_VUIInfo.stVidSigType.eColorMatrix; + + pPicInfo->seq.chroma_sample_loc_type_top_field = 0; + pPicInfo->seq.chroma_sample_loc_type_bottom_field = 0; + + if( pPicInfo->seq.vui_flags.bitstream_restriction_flag ) // not needed, remove later + { + pPicInfo->seq.vui_flags.motion_vectors_over_pic_boundaries_flag = 0; + pPicInfo->seq.max_bytes_per_pic_denom = 0; + pPicInfo->seq.log2_max_mv_length_vertical = 0; + pPicInfo->seq.log2_max_mv_length_horizontal = 0; + } + + // TODO: unsorted fields if( pPicInfo->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN10_422 || pPicInfo->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_444 || pPicInfo->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN10_444 ) { pPicInfo->seq.sps_range_extension.sps_range_extension_flag = 1; // SPS Range ext flags - if( EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_transform_skip_rotation_enabled_flag ) + if( m_EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_transform_skip_rotation_enabled_flag ) pPicInfo->seq.sps_range_extension.transform_skip_rotation_enabled_flag = 1; - if( EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_transform_skip_context_enabled_flag ) + if( m_EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_transform_skip_context_enabled_flag ) pPicInfo->seq.sps_range_extension.transform_skip_context_enabled_flag = 1; - if( EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_implicit_rdpcm_enabled_flag ) + if( m_EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_implicit_rdpcm_enabled_flag ) pPicInfo->seq.sps_range_extension.implicit_rdpcm_enabled_flag = 1; - if( EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_explicit_rdpcm_enabled_flag ) + if( m_EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_explicit_rdpcm_enabled_flag ) pPicInfo->seq.sps_range_extension.explicit_rdpcm_enabled_flag = 1; - if( EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_extended_precision_processing_flag ) + if( m_EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_extended_precision_processing_flag ) pPicInfo->seq.sps_range_extension.extended_precision_processing_flag = 1; - if( EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_intra_smoothing_disabled_flag ) + if( m_EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_intra_smoothing_disabled_flag ) pPicInfo->seq.sps_range_extension.intra_smoothing_disabled_flag = 0; - if( EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_high_precision_offsets_enabled_flag ) + if( m_EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_high_precision_offsets_enabled_flag ) pPicInfo->seq.sps_range_extension.high_precision_offsets_enabled_flag = 1; - if( EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_persistent_rice_adaptation_enabled_flag ) + if( m_EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_persistent_rice_adaptation_enabled_flag ) pPicInfo->seq.sps_range_extension.persistent_rice_adaptation_enabled_flag = 1; - if( EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_cabac_bypass_alignment_enabled_flag ) + if( m_EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_cabac_bypass_alignment_enabled_flag ) pPicInfo->seq.sps_range_extension.cabac_bypass_alignment_enabled_flag = 1; // PPS Range ext flags pPicInfo->pic.pps_range_extension.pps_range_extension_flag = 1; - if( EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_cross_component_prediction_enabled_flag ) + if( m_EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_cross_component_prediction_enabled_flag ) pPicInfo->pic.pps_range_extension.cross_component_prediction_enabled_flag = 1; // Codec valid range for support for log2_max_transform_skip_block_size_minus2 is [0, 3] for( unsigned i = 0; i < 4; i++ ) { - if( ( EncoderCapabilities.m_HWSupportH265RangeExtension.bits.supported_log2_max_transform_skip_block_size_minus2_values & + if( ( m_EncoderCapabilities.m_HWSupportH265RangeExtension.bits.supported_log2_max_transform_skip_block_size_minus2_values & ( 1 << i ) ) != 0 ) { pPicInfo->pic.pps_range_extension.log2_max_transform_skip_block_size_minus2 = i; @@ -124,7 +212,7 @@ UpdateH265EncPictureDesc( pipe_h265_enc_picture_desc *pPicInfo, } } - if( EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_chroma_qp_offset_list_enabled_flag ) + if( m_EncoderCapabilities.m_HWSupportH265RangeExtensionFlags.bits.supports_chroma_qp_offset_list_enabled_flag ) pPicInfo->pic.pps_range_extension.chroma_qp_offset_list_enabled_flag = 1; if( pPicInfo->pic.pps_range_extension.chroma_qp_offset_list_enabled_flag ) @@ -132,7 +220,7 @@ UpdateH265EncPictureDesc( pipe_h265_enc_picture_desc *pPicInfo, // Codec valid range for support for diff_cu_chroma_qp_offset_depth is [0, 3]. for( unsigned i = 0; i < 4; i++ ) { - if( ( EncoderCapabilities.m_HWSupportH265RangeExtension.bits.supported_diff_cu_chroma_qp_offset_depth_values & + if( ( m_EncoderCapabilities.m_HWSupportH265RangeExtension.bits.supported_diff_cu_chroma_qp_offset_depth_values & ( 1 << i ) ) != 0 ) { pPicInfo->pic.pps_range_extension.diff_cu_chroma_qp_offset_depth = i; @@ -141,7 +229,7 @@ UpdateH265EncPictureDesc( pipe_h265_enc_picture_desc *pPicInfo, } pPicInfo->pic.pps_range_extension.chroma_qp_offset_list_len_minus1 = - EncoderCapabilities.m_HWSupportH265RangeExtension.bits.min_chroma_qp_offset_list_len_minus1_values; + m_EncoderCapabilities.m_HWSupportH265RangeExtension.bits.min_chroma_qp_offset_list_len_minus1_values; for( unsigned i = 0; i < pPicInfo->pic.pps_range_extension.chroma_qp_offset_list_len_minus1 + 1; i++ ) { pPicInfo->pic.pps_range_extension.cb_qp_offset_list[i] = 0; @@ -152,8 +240,8 @@ UpdateH265EncPictureDesc( pipe_h265_enc_picture_desc *pPicInfo, // Codec valid range for support for log2_sao_offset_scale_luma is [0, 6]. for( unsigned i = 0; i < 7; i++ ) { - if( ( EncoderCapabilities.m_HWSupportH265RangeExtension.bits.supported_log2_sao_offset_scale_luma_values & ( 1 << i ) ) != - 0 ) + if( ( m_EncoderCapabilities.m_HWSupportH265RangeExtension.bits.supported_log2_sao_offset_scale_luma_values & + ( 1 << i ) ) != 0 ) { pPicInfo->pic.pps_range_extension.log2_sao_offset_scale_luma = i; break; @@ -163,7 +251,7 @@ UpdateH265EncPictureDesc( pipe_h265_enc_picture_desc *pPicInfo, // Codec valid range for support for log2_sao_offset_scale_chroma is [0, 6]. for( unsigned i = 0; i < 7; i++ ) { - if( ( EncoderCapabilities.m_HWSupportH265RangeExtension.bits.supported_log2_sao_offset_scale_chroma_values & + if( ( m_EncoderCapabilities.m_HWSupportH265RangeExtension.bits.supported_log2_sao_offset_scale_chroma_values & ( 1 << i ) ) != 0 ) { pPicInfo->pic.pps_range_extension.log2_sao_offset_scale_chroma = i; @@ -172,68 +260,16 @@ UpdateH265EncPictureDesc( pipe_h265_enc_picture_desc *pPicInfo, } } - pPicInfo->seq.log2_min_luma_coding_block_size_minus3 = - EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_min_luma_coding_block_size_minus3; - - pPicInfo->seq.log2_diff_max_min_luma_coding_block_size = - static_cast( ( EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_max_coding_tree_block_size_minus3 + 3 ) - - ( EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_min_luma_coding_block_size_minus3 + 3 ) ); - - pPicInfo->seq.log2_min_transform_block_size_minus2 = - EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_min_luma_transform_block_size_minus2; - - pPicInfo->seq.log2_diff_max_min_transform_block_size = - static_cast( ( EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_max_luma_transform_block_size_minus2 + 2 ) - - ( EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_min_luma_transform_block_size_minus2 + 2 ) ); - - pPicInfo->seq.max_transform_hierarchy_depth_inter = - EncoderCapabilities.m_HWSupportH265BlockSizes.bits.min_max_transform_hierarchy_depth_inter; - - pPicInfo->seq.max_transform_hierarchy_depth_intra = - EncoderCapabilities.m_HWSupportH265BlockSizes.bits.min_max_transform_hierarchy_depth_intra; - - // VUI Data - always true because we have timing_info_present_flag = 1 - pPicInfo->seq.vui_parameters_present_flag = 1; - - // SAR - aspect ratio - pPicInfo->seq.vui_flags.aspect_ratio_info_present_flag = VUIInfo.bEnableSAR; - pPicInfo->seq.aspect_ratio_idc = 255 /* EXTENDED_SAR */; - pPicInfo->seq.sar_width = VUIInfo.stSARInfo.usWidth; - pPicInfo->seq.sar_height = VUIInfo.stSARInfo.usHeight; - - // VST - video signal type - pPicInfo->seq.vui_flags.video_signal_type_present_flag = VUIInfo.bEnableVST; - pPicInfo->seq.video_format = VUIInfo.stVidSigType.eVideoFormat; - pPicInfo->seq.video_full_range_flag = VUIInfo.stVidSigType.bVideoFullRangeFlag; - pPicInfo->seq.vui_flags.colour_description_present_flag = VUIInfo.stVidSigType.bColorInfoPresent; - pPicInfo->seq.colour_primaries = VUIInfo.stVidSigType.eColorPrimary; - pPicInfo->seq.transfer_characteristics = VUIInfo.stVidSigType.eColorTransfer; - pPicInfo->seq.matrix_coefficients = VUIInfo.stVidSigType.eColorMatrix; - - pPicInfo->seq.vui_flags.timing_info_present_flag = 1; - pPicInfo->seq.num_units_in_tick = FrameRate.Denominator; - pPicInfo->seq.time_scale = FrameRate.Numerator * 2; - - pPicInfo->seq.vui_flags.chroma_loc_info_present_flag = 0; - pPicInfo->seq.chroma_sample_loc_type_top_field = 0; - pPicInfo->seq.chroma_sample_loc_type_bottom_field = 0; - - pPicInfo->seq.vui_flags.overscan_info_present_flag = 0; - pPicInfo->seq.vui_flags.overscan_appropriate_flag = 0; - - pPicInfo->seq.vui_flags.bitstream_restriction_flag = 1; - if( pPicInfo->seq.vui_flags.bitstream_restriction_flag ) - { - pPicInfo->seq.vui_flags.motion_vectors_over_pic_boundaries_flag = 0; - pPicInfo->seq.max_bytes_per_pic_denom = 0; - pPicInfo->seq.log2_max_mv_length_horizontal = 0; - pPicInfo->seq.log2_max_mv_length_vertical = 0; - } + return hr; } // internal function which contains the codec specific portion of PrepareForEncode HRESULT -CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bool dirtyRectFrameNumSet, uint32_t dirtyRectFrameNum, bool moveRegionFrameNumSet, uint32_t moveRegionFrameNum ) +CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, + bool dirtyRectFrameNumSet, + uint32_t dirtyRectFrameNum, + bool moveRegionFrameNumSet, + uint32_t moveRegionFrameNum ) { HRESULT hr = S_OK; pipe_h265_enc_picture_desc *pPicInfo = &pDX12EncodeContext->encoderPicInfo.h265enc; @@ -463,21 +499,12 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo pPicInfo->twopass_frame_config.skip_1st_pass = false; } - // Setup Level, not sure why this is represented twice on the codec? - pPicInfo->seq.general_level_idc = static_cast( m_pPipeVideoCodec->level ); - - pPicInfo->seq.intra_period = cur_frame_desc->gop_info->intra_period; - pPicInfo->seq.ip_period = cur_frame_desc->gop_info->ip_period; - pPicInfo->seq.log2_max_pic_order_cnt_lsb_minus4 = cur_frame_desc->gop_info->log2_max_pic_order_cnt_lsb_minus4; - - UpdateH265EncPictureDesc( pPicInfo, m_EncoderCapabilities, m_VUIInfo, m_FrameRate ); - - pPicInfo->seq.conformance_window_flag = m_bFrameCroppingFlag; - pPicInfo->seq.conf_win_right_offset = static_cast( m_uiFrameCropRightOffset ); - pPicInfo->seq.conf_win_bottom_offset = static_cast( m_uiFrameCropBottomOffset ); - - pPicInfo->seq.pic_width_in_luma_samples = static_cast( pDX12EncodeContext->pPipeVideoBuffer->width ); - pPicInfo->seq.pic_height_in_luma_samples = static_cast( pDX12EncodeContext->pPipeVideoBuffer->height ); + UpdateH265EncPictureDesc( pPicInfo, + cur_frame_desc->gop_info->intra_period, + cur_frame_desc->gop_info->ip_period, + cur_frame_desc->gop_info->log2_max_pic_order_cnt_lsb_minus4, + static_cast( pDX12EncodeContext->pPipeVideoBuffer->width ), + static_cast( pDX12EncodeContext->pPipeVideoBuffer->height ) ); // Slices data height_in_blocks = ( ( pDX12EncodeContext->pPipeVideoBuffer->height + 15 ) >> 4 ); @@ -678,18 +705,6 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo pPicInfo->rc[rate_ctrl_active_layer_index].frame_rate_num = m_FrameRate.Numerator; pPicInfo->rc[rate_ctrl_active_layer_index].frame_rate_den = m_FrameRate.Denominator; - // VPS - pPicInfo->vid.vps_sub_layer_ordering_info_present_flag = 0; - pPicInfo->vid.vps_max_sub_layers_minus1 = 0; - for( int i = ( pPicInfo->vid.vps_sub_layer_ordering_info_present_flag ? 0 : pPicInfo->vid.vps_max_sub_layers_minus1 ); - i <= pPicInfo->vid.vps_max_sub_layers_minus1; - i++ ) - { - pPicInfo->vid.vps_max_dec_pic_buffering_minus1[i] = static_cast( m_pPipeVideoCodec->max_references ); - pPicInfo->vid.vps_max_num_reorder_pics[i] = 0; // TODO: B-frames / reordering - pPicInfo->vid.vps_max_latency_increase_plus1[i] = 0 + 1; // TODO: B-frames - } - // sanity checks for future, currently these two values are all zeros. if( m_uiDirtyRectEnabled ) { @@ -740,27 +755,16 @@ CDX12EncHMFT::GetCodecPrivateData( LPBYTE pSPSPPSData, DWORD dwSPSPPSDataLen, LP UINT alignedHeight = static_cast( std::ceil( m_uiOutputHeight / 16.0 ) ) * 16; int ret = EINVAL; unsigned buf_size = dwSPSPPSDataLen; + const uint32_t intra_period = m_uiGopSize; + const uint32_t ip_period = m_uiBFrameCount + 1; + const uint8_t log2_max_pic_order_cnt_lsb_minus4 = 4; pipe_h265_enc_picture_desc h265_pic_desc = {}; - memset( &h265_pic_desc, 0, sizeof( h265_pic_desc ) ); - uint32_t gop_length = m_uiGopSize; - uint32_t p_picture_period = m_uiBFrameCount + 1; - - h265_pic_desc.base.profile = m_outputPipeProfile; - - h265_pic_desc.pic_order_cnt_type = ( p_picture_period > 2 ) ? 0u : 2u; + h265_pic_desc.pic_order_cnt_type = ( ip_period > 2 ) ? 0u : 2u; h265_pic_desc.pic_order_cnt = 0; // cur_frame_desc->gop_info->picture_order_count; h265_pic_desc.picture_type = PIPE_H2645_ENC_PICTURE_TYPE_IDR; // cur_frame_desc->gop_info->frame_type; - h265_pic_desc.seq.ip_period = p_picture_period; // cur_frame_desc->gop_info->base.ip_period; - h265_pic_desc.seq.intra_period = gop_length; // cur_frame_desc->gop_info->base.intra_period; - h265_pic_desc.seq.general_profile_idc = static_cast( m_pPipeVideoCodec->profile ); - h265_pic_desc.seq.general_level_idc = static_cast( m_pPipeVideoCodec->level ); - h265_pic_desc.seq.chroma_format_idc = GetChromaFormatIdc( ConvertProfileToFormat( m_outputPipeProfile ) ); - h265_pic_desc.seq.log2_max_pic_order_cnt_lsb_minus4 = 4; - - UpdateH265EncPictureDesc( &h265_pic_desc, m_EncoderCapabilities, m_VUIInfo, m_FrameRate ); ComputeCroppingRect( alignedWidth, alignedHeight, m_uiOutputWidth, @@ -770,12 +774,12 @@ CDX12EncHMFT::GetCodecPrivateData( LPBYTE pSPSPPSData, DWORD dwSPSPPSDataLen, LP m_uiFrameCropRightOffset, m_uiFrameCropBottomOffset ); - h265_pic_desc.seq.conformance_window_flag = m_bFrameCroppingFlag; - h265_pic_desc.seq.conf_win_right_offset = static_cast( m_uiFrameCropRightOffset ); - h265_pic_desc.seq.conf_win_bottom_offset = static_cast( m_uiFrameCropBottomOffset ); - - h265_pic_desc.seq.pic_width_in_luma_samples = static_cast( alignedWidth ); - h265_pic_desc.seq.pic_height_in_luma_samples = static_cast( alignedHeight ); + UpdateH265EncPictureDesc( &h265_pic_desc, + intra_period, + ip_period, + log2_max_pic_order_cnt_lsb_minus4, + static_cast( alignedWidth ), + static_cast( alignedHeight ) ); // Rate Control if( m_uiRateControlMode == eAVEncCommonRateControlMode_CBR ) @@ -797,17 +801,6 @@ CDX12EncHMFT::GetCodecPrivateData( LPBYTE pSPSPPSData, DWORD dwSPSPPSDataLen, LP h265_pic_desc.rc[0].quant_p_frames = m_uiEncodeFrameTypeIQP[0]; h265_pic_desc.rc[0].quant_b_frames = m_uiEncodeFrameTypeIQP[0]; - h265_pic_desc.vid.vps_sub_layer_ordering_info_present_flag = 0; - h265_pic_desc.vid.vps_max_sub_layers_minus1 = 0; - for( int i = ( h265_pic_desc.vid.vps_sub_layer_ordering_info_present_flag ? 0 : h265_pic_desc.vid.vps_max_sub_layers_minus1 ); - i <= h265_pic_desc.vid.vps_max_sub_layers_minus1; - i++ ) - { - h265_pic_desc.vid.vps_max_dec_pic_buffering_minus1[i] = static_cast( m_pPipeVideoCodec->max_references - 1 ); - h265_pic_desc.vid.vps_max_num_reorder_pics[i] = 0; // TODO: B-frames / reordering - h265_pic_desc.vid.vps_max_latency_increase_plus1[i] = 0 + 1; // TODO: B-frames - } - ret = m_pPipeVideoCodec->get_encode_headers( m_pPipeVideoCodec, &h265_pic_desc.base, pSPSPPSData, &buf_size ); CHECKHR_GOTO( ConvertErrnoRetToHR( ret ), done ); diff --git a/src/gallium/frontends/mediafoundation/hmft_entrypoints.h b/src/gallium/frontends/mediafoundation/hmft_entrypoints.h index 7110717cd86..3308de44313 100644 --- a/src/gallium/frontends/mediafoundation/hmft_entrypoints.h +++ b/src/gallium/frontends/mediafoundation/hmft_entrypoints.h @@ -393,7 +393,8 @@ DEFINE_CODECAPI_GUID( AVEncVideoD3D12ReconstructedPictureOutputMode, 0xc5, 0xa7, 0xd3 ) -#define CODECAPI_AVEncVideoD3D12ReconstructedPictureOutputMode DEFINE_CODECAPI_GUIDNAMED( AVEncVideoD3D12ReconstructedPictureOutputMode ) +#define CODECAPI_AVEncVideoD3D12ReconstructedPictureOutputMode \ + DEFINE_CODECAPI_GUIDNAMED( AVEncVideoD3D12ReconstructedPictureOutputMode ) #endif @@ -841,7 +842,28 @@ class __declspec( uuid( HMFT_GUID ) ) CDX12EncHMFT : CMFD3DManager, bool m_bUnlocked = false; HRESULT IsUnlocked( void ); - HRESULT PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bool dirtyRectFrameNumSet, uint32_t dirtyRectFrameNum, bool moveRegionFrameNumSet, uint32_t moveRegionFrameNum ); +#if MFT_CODEC_H264ENC + HRESULT UpdateH264EncPictureDesc( pipe_h264_enc_picture_desc *pPicInfo, const uint32_t intra_period, const uint32_t ip_period ); +#endif + +#if MFT_CODEC_H265ENC + HRESULT UpdateH265EncPictureDesc( pipe_h265_enc_picture_desc *pPicInfo, + const uint32_t intra_period, + const uint32_t ip_period, + const uint8_t log2_max_pic_order_cnt_lsb_minus4, + const uint16_t pic_width_in_luma_samples, + const uint16_t pic_height_in_luma_samples ); +#endif + +#if MFT_CODEC_AV1ENC + HRESULT UpdateAV1EncPictureDesc( pipe_av1_enc_picture_desc *pPicInfo ); +#endif + + HRESULT PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, + bool dirtyRectFrameNumSet, + uint32_t dirtyRectFrameNum, + bool moveRegionFrameNumSet, + uint32_t moveRegionFrameNum ); HRESULT PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12EncodeContext ); std::vector m_pDirtyRectBlob = std::vector( sizeof( DIRTYRECT_INFO ) ); diff --git a/src/gallium/frontends/mediafoundation/mftransform.cpp b/src/gallium/frontends/mediafoundation/mftransform.cpp index 7dee27fb05d..2c96bbacca5 100644 --- a/src/gallium/frontends/mediafoundation/mftransform.cpp +++ b/src/gallium/frontends/mediafoundation/mftransform.cpp @@ -22,13 +22,13 @@ */ #include +#include "gallium/drivers/d3d12/d3d12_interop_public.h" #include "d3d12_suballoc_mediabuffer.h" #include "dpb_buffer_manager.h" #include "hmft_entrypoints.h" #include "mfbufferhelp.h" #include "mfpipeinterop.h" #include "wpptrace.h" -#include "gallium/drivers/d3d12/d3d12_interop_public.h" #include "mftransform.tmh" @@ -1187,7 +1187,7 @@ CDX12EncHMFT::ConfigureAsyncStatsMetadataOutputSampleAttributes( IMFSample *pSam pPipeResourceQPMapStats, pSyncObjectQueue, pSample ), - done ); + done ); } // Conditionally attach output bits used map (d3d12resource), tracking will be added to the d3d12resource and when @@ -1342,7 +1342,7 @@ CDX12EncHMFT::FinalizeAndEmitOutputSample( LPDX12EncodeContext pDX12EncodeContex // Check if codec units are non-contiguous in memory // If they are not contiguous, we need to copy them to a contiguous buffer // to match the reported nalu length information - assert (CodecUnitMetadataCount > 0); + assert( CodecUnitMetadataCount > 0 ); bool bNonContiguousNALs = false; for( unsigned i = 0; i < CodecUnitMetadataCount - 1; i++ ) { @@ -1350,9 +1350,9 @@ CDX12EncHMFT::FinalizeAndEmitOutputSample( LPDX12EncodeContext pDX12EncodeContex { bNonContiguousNALs = true; debug_printf( "[dx12 hmft 0x%p] FinalizeAndEmitOutputSample - Non-contiguous codec unit %i detected, " - "performing copy into a contiguous buffer for MFT output\n", - this, - i ); + "performing copy into a contiguous buffer for MFT output\n", + this, + i ); } } @@ -1512,8 +1512,9 @@ CDX12EncHMFT::xThreadProc( void *pCtx ) HANDLE fence_handle = (HANDLE) pThis->m_pPipeContext->screen->fence_get_win32_handle( pThis->m_pPipeContext->screen, pDX12EncodeContext->pAsyncFence, &ResolveStatsCompletionFenceValue ); - if (!fence_handle || - FAILED(pThis->m_spDevice->OpenSharedHandle(fence_handle, IID_PPV_ARGS(pDX12EncodeContext->spAsyncFence.ReleaseAndGetAddressOf())))) + if( !fence_handle || FAILED( pThis->m_spDevice->OpenSharedHandle( + fence_handle, + IID_PPV_ARGS( pDX12EncodeContext->spAsyncFence.ReleaseAndGetAddressOf() ) ) ) ) { debug_printf( "[dx12 hmft 0x%p] Failed to open frame pAsyncFence\n", pThis ); MFE_ERROR( "[dx12 hmft 0x%p] Failed to open frame pAsyncFence", pThis ); @@ -2630,19 +2631,20 @@ CDX12EncHMFT::ProcessInput( DWORD dwInputStreamIndex, IMFSample *pSample, DWORD if( !m_bLowLatency ) { debug_printf( "[dx12 hmft 0x%p] Zero copy read only reconstructed picture is ONLY supported in low latency mode\n", - this ); + this ); assert( m_bLowLatency ); CHECKHR_GOTO( E_FAIL, done ); } // Get read-only handle directly from the video buffer struct d3d12_interop_video_buffer_associated_data *associated_data = - static_cast( src_buffer->associated_data ); - if(associated_data->get_read_only_resource && - (!associated_data->get_read_only_resource( src_buffer, + static_cast( src_buffer->associated_data ); + if( associated_data->get_read_only_resource && + ( !associated_data->get_read_only_resource( src_buffer, m_pPipeContext, &pDX12EncodeContext->pPipeResourceReconstructedPicture, - &pDX12EncodeContext->PipeResourceReconstructedPictureSubresource ) || !pDX12EncodeContext->pPipeResourceReconstructedPicture) ) + &pDX12EncodeContext->PipeResourceReconstructedPictureSubresource ) || + !pDX12EncodeContext->pPipeResourceReconstructedPicture ) ) { debug_printf( "[dx12 hmft 0x%p] Failed to get read-only resource from reference video buffer\n", this ); } @@ -2673,8 +2675,7 @@ CDX12EncHMFT::ProcessInput( DWORD dwInputStreamIndex, IMFSample *pSample, DWORD whandle.type = WINSYS_HANDLE_TYPE_D3D12_RES; whandle.modifier = 2; // Expected by video_buffer_from_handle to place a pipe_resource in the pipe_video_buffer whandle.com_obj = (void *) pDX12EncodeContext->pPipeResourceReconstructedPicture; - struct pipe_video_buffer *dst_buffer = - m_pPipeContext->video_buffer_from_handle( m_pPipeContext, src_buffer, &whandle, 0 ); + struct pipe_video_buffer *dst_buffer = m_pPipeContext->video_buffer_from_handle( m_pPipeContext, src_buffer, &whandle, 0 ); assert( dst_buffer ); pDX12EncodeContext->PipeResourceReconstructedPictureSubresource = 0; @@ -2701,11 +2702,10 @@ CDX12EncHMFT::ProcessInput( DWORD dwInputStreamIndex, IMFSample *pSample, DWORD &pDX12EncodeContext->ReconstructedPictureCompletionFenceValue ); if( fence_handle ) { - CHECKHR_GOTO( - m_spDevice->OpenSharedHandle( - fence_handle, - IID_PPV_ARGS( pDX12EncodeContext->spReconstructedPictureCompletionFence.ReleaseAndGetAddressOf() ) ), - done ); + CHECKHR_GOTO( m_spDevice->OpenSharedHandle( + fence_handle, + IID_PPV_ARGS( pDX12EncodeContext->spReconstructedPictureCompletionFence.ReleaseAndGetAddressOf() ) ), + done ); CloseHandle( fence_handle ); } } diff --git a/src/gallium/frontends/mediafoundation/stats_buffer_manager.cpp b/src/gallium/frontends/mediafoundation/stats_buffer_manager.cpp index 2da59031e6a..3c004d5b7b7 100644 --- a/src/gallium/frontends/mediafoundation/stats_buffer_manager.cpp +++ b/src/gallium/frontends/mediafoundation/stats_buffer_manager.cpp @@ -275,8 +275,7 @@ stats_buffer_manager::stats_buffer_manager( void *logId, } stats_buffer_manager::~stats_buffer_manager() -{ -} +{ } // callback from IMFTrackSample (i.e. application) IFACEMETHODIMP