1 /*
2 * Copyright (c) 2021-2024, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,HevcEncodeTile
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     encode_hevc_aqm.cpp
24 //! \brief    Defines the common interface for hevc aqm
25 //!
26 
27 #include "encode_hevc_aqm.h"
28 #include "encode_hevc_vdenc_feature_manager.h"
29 #include "encode_hevc_basic_feature.h"
30 
31 namespace encode
32 {
HevcEncodeAqm(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)33 HevcEncodeAqm::HevcEncodeAqm(MediaFeatureManager *featureManager,
34     EncodeAllocator *                           allocator,
35     CodechalHwInterfaceNext *                       hwInterface,
36     void *                                      constSettings) : EncodeAqmFeature(featureManager, allocator, hwInterface, constSettings)
37 {
38     auto encFeatureManager = dynamic_cast<EncodeHevcVdencFeatureManager *>(featureManager);
39     ENCODE_CHK_NULL_NO_STATUS_RETURN(encFeatureManager);
40 
41     m_basicFeature = dynamic_cast<EncodeBasicFeature *>(encFeatureManager->GetFeature(HevcFeatureIDs::basicFeature));
42     ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
43 
44     if (HCP_CHROMA_FORMAT_YUV422 == m_basicFeature->m_chromaFormat)
45     {
46         m_enabled = false;
47         ENCODE_VERBOSEMESSAGE("422 is not supported for VDAQM feature!");
48     }
49 };
50 
Update(void * params)51 MOS_STATUS HevcEncodeAqm::Update(void *params)
52 {
53     auto basicFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature);
54     ENCODE_CHK_NULL_RETURN(basicFeature);
55     if (basicFeature->m_hevcPicParams->QualityInfoSupportFlags.fields.enable_frame)
56     {
57         m_enabled = true;
58     }
59     m_numTiles = (basicFeature->m_hevcPicParams->num_tile_rows_minus1 + 1) * (basicFeature->m_hevcPicParams->num_tile_columns_minus1 + 1);
60     m_tileBasedEngine = m_numTiles > 1 ? true : false;
61     uint32_t minCodingBlkSize = basicFeature->m_hevcSeqParams->log2_min_coding_block_size_minus3 + 3;
62     if (!basicFeature->m_hevcPicParams->tiles_enabled_flag)
63     {
64         m_tile_width[0]     = (1 << minCodingBlkSize) * (basicFeature->m_hevcSeqParams->wFrameWidthInMinCbMinus1 + 1);
65         m_tile_height[0]    = (1 << minCodingBlkSize) * (basicFeature->m_hevcSeqParams->wFrameHeightInMinCbMinus1 + 1);
66     }
67     else
68     {
69         for (uint32_t tileIdx = 0; tileIdx < m_numTiles && tileIdx < ENCODE_VDENC_MAX_TILE_NUM; tileIdx++)
70         {
71             EncodeTileData tileData = {};
72             RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, HevcFeatureIDs::encodeTile, GetTileByIndex, tileData, tileIdx);
73             m_tile_width[tileIdx]       = ((tileData.tileWidthInMinCbMinus1 + 1) << minCodingBlkSize);
74             m_tile_height[tileIdx]      = ((tileData.tileHeightInMinCbMinus1 + 1) << minCodingBlkSize);
75         }
76     }
77 #if USE_CODECHAL_DEBUG_TOOL
78     UpdateFrameDisplayOrder(basicFeature->m_pictureCodingType, basicFeature->m_hevcPicParams->CurrPicOrderCnt, basicFeature->m_hevcSeqParams->GopPicSize);
79 #endif
80     if (basicFeature->m_hevcPicParams->num_tile_columns_minus1 == 1)
81     {
82         m_numRowStore = 2;
83     }
84     ENCODE_CHK_STATUS_RETURN(EncodeAqmFeature::Update(params));
85     return MOS_STATUS_SUCCESS;
86 }
87 
MHW_SETPAR_DECL_SRC(AQM_PIC_STATE,HevcEncodeAqm)88 MHW_SETPAR_DECL_SRC(AQM_PIC_STATE, HevcEncodeAqm)
89 {
90     ENCODE_CHK_STATUS_RETURN(EncodeAqmFeature::MHW_SETPAR_F(AQM_PIC_STATE)(params));
91 
92     params.lcuSize   = LCU_SIZE_64X64;
93     params.codectype = CODECTYPE_HEVC;
94 
95     return MOS_STATUS_SUCCESS;
96 }
97 
MHW_SETPAR_DECL_SRC(HCP_PIC_STATE,HevcEncodeAqm)98 MHW_SETPAR_DECL_SRC(HCP_PIC_STATE, HevcEncodeAqm)
99 {
100 
101     params.vdaqmEnable = m_enabled;
102 
103     return MOS_STATUS_SUCCESS;
104 }
105 
MHW_SETPAR_DECL_SRC(AQM_TILE_CODING,HevcEncodeAqm)106 MHW_SETPAR_DECL_SRC(AQM_TILE_CODING, HevcEncodeAqm)
107 {
108     auto encFeatureManager = dynamic_cast<EncodeHevcVdencFeatureManager *>(m_featureManager);
109     ENCODE_CHK_NULL_RETURN(encFeatureManager);
110 
111     auto hevcTile = dynamic_cast<HevcEncodeTile *>(encFeatureManager->GetFeature(HevcFeatureIDs::encodeTile));
112     ENCODE_CHK_NULL_RETURN(hevcTile);
113 
114     HevcTileInfo hevcTileInfo;
115 
116     hevcTile->GetTileInfo(&hevcTileInfo);
117 
118     params.tileId               = hevcTileInfo.tileId;
119     params.tileColPositionInSb  = hevcTileInfo.tileColPositionInSb;
120     params.tileRowPositionInSb  = hevcTileInfo.tileRowPositionInSb;
121     params.tileWidthInSbMinus1  = hevcTileInfo.tileWidthInSbMinus1;
122     params.tileHeightInSbMinus1 = hevcTileInfo.tileHeightInSbMinus1;
123     params.tileNum              = hevcTileInfo.tileNum;
124     params.tileGroupId          = hevcTileInfo.tileGroupId;
125 
126     return MOS_STATUS_SUCCESS;
127 }
128 
MHW_SETPAR_DECL_SRC(AQM_SLICE_STATE,HevcEncodeAqm)129 MHW_SETPAR_DECL_SRC(AQM_SLICE_STATE, HevcEncodeAqm)
130 {
131     auto encFeatureManager = dynamic_cast<EncodeHevcVdencFeatureManager *>(m_featureManager);
132     ENCODE_CHK_NULL_RETURN(encFeatureManager);
133 
134     auto hevcTile = dynamic_cast<HevcEncodeTile *>(encFeatureManager->GetFeature(HevcFeatureIDs::encodeTile));
135     ENCODE_CHK_NULL_RETURN(hevcTile);
136 
137     HevcTileInfo hevcTileInfo;
138 
139     hevcTile->GetTileInfo(&hevcTileInfo);
140 
141     auto hevcBasicFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature);
142     ENCODE_CHK_NULL_RETURN(hevcBasicFeature);
143     auto picParams = hevcBasicFeature->m_hevcPicParams;
144     ENCODE_CHK_NULL_RETURN(picParams);
145     auto seqParams = hevcBasicFeature->m_hevcSeqParams;
146     ENCODE_CHK_NULL_RETURN(seqParams);
147     auto t_sliceParams = hevcBasicFeature->m_hevcSliceParams;
148     ENCODE_CHK_NULL_RETURN(t_sliceParams);
149     CODEC_HEVC_ENCODE_SLICE_PARAMS *sliceParams = (CODEC_HEVC_ENCODE_SLICE_PARAMS *)&t_sliceParams[hevcBasicFeature->m_curNumSlices];
150 
151     uint32_t ctbSize     = 1 << (seqParams->log2_max_coding_block_size_minus3 + 3);
152     uint32_t widthInPix  = (1 << (seqParams->log2_min_coding_block_size_minus3 + 3)) * (seqParams->wFrameWidthInMinCbMinus1 + 1);
153     uint32_t widthInCtb  = (widthInPix / ctbSize) + ((widthInPix % ctbSize) ? 1 : 0);  // round up
154     uint32_t heightInPix = (1 << (seqParams->log2_min_coding_block_size_minus3 + 3)) * (seqParams->wFrameHeightInMinCbMinus1 + 1);
155     uint32_t heightInCtb = (heightInPix / ctbSize) + ((heightInPix % ctbSize) ? 1 : 0);  // round up
156     uint32_t shift       = seqParams->log2_max_coding_block_size_minus3 - seqParams->log2_min_coding_block_size_minus3;
157 
158     bool m_enabled = false;
159     ENCODE_CHK_STATUS_RETURN(hevcTile->IsEnabled(m_enabled));
160     if (!m_enabled)
161     {
162         params.firstSuperSlice = 0;
163         // No tiling support
164         params.tileSliceStartLcuMbY     = sliceParams->slice_segment_address / widthInCtb;
165         params.nextTileSliceStartLcuMbX = (sliceParams->slice_segment_address + sliceParams->NumLCUsInSlice) / heightInCtb;
166         params.nextTileSliceStartLcuMbY = (sliceParams->slice_segment_address + sliceParams->NumLCUsInSlice) / widthInCtb;
167     }
168     else
169     {
170         params.tileSliceStartLcuMbX     = hevcTileInfo.tileStartXInLCU;
171         params.tileSliceStartLcuMbY     = hevcTileInfo.tileStartYInLCU;
172         params.nextTileSliceStartLcuMbX = hevcTileInfo.tileEndXInLCU;
173         params.nextTileSliceStartLcuMbY = hevcTileInfo.tileEndYInLCU;
174     }
175 
176     return MOS_STATUS_SUCCESS;
177 }
178 
179 #if USE_CODECHAL_DEBUG_TOOL
UpdateFrameDisplayOrder(const uint16_t pictureCodingType,const uint32_t framePOC,const uint32_t gopPicSize)180 MOS_STATUS HevcEncodeAqm::UpdateFrameDisplayOrder(const uint16_t pictureCodingType, const uint32_t framePOC, const uint32_t gopPicSize)
181 {
182     auto basicFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature);
183     ENCODE_CHK_NULL_RETURN(basicFeature);
184     if (basicFeature->m_hevcPicParams->CurrPicOrderCnt == 0)
185     {
186         m_frameNumPrevious += m_gopSizePrevious;
187     }
188     uint32_t    displayOrderInGOP   = framePOC;
189     uint32_t    displayOrderInSeq   = displayOrderInGOP + m_frameNumPrevious;
190     m_gopSizePrevious               = gopPicSize;
191     m_frameIdxQueue.push(displayOrderInSeq);
192     return MOS_STATUS_SUCCESS;
193 }
194 #endif
195 
196 }  // namespace encode
197