1 /*
2 * Copyright (c) 2023-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,
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_av1_fastpass.cpp
24 //! \brief    Fast Pass feature
25 //!
26 
27 #include "encode_av1_fastpass.h"
28 
29 namespace encode
30 {
Av1FastPass(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)31 Av1FastPass::Av1FastPass(MediaFeatureManager *featureManager,
32     EncodeAllocator                          *allocator,
33     CodechalHwInterfaceNext                  *hwInterface,
34     void                                     *constSettings):
35     MediaFeature(constSettings, hwInterface ? hwInterface->GetOsInterface() : nullptr)
36     {
37         ENCODE_FUNC_CALL();
38 
39         ENCODE_CHK_NULL_NO_STATUS_RETURN(featureManager);
40 
41         m_basicFeature = dynamic_cast<Av1BasicFeature *>(featureManager->GetFeature(Av1FeatureIDs::basicFeature));
42         ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
43 
44         //regkey to control fast pass encode settings
45         MediaUserSetting::Value outValue;
46         ReadUserSetting(m_userSettingPtr,
47             outValue,
48             "Enable Fast Pass Encode",
49             MediaUserSetting::Group::Sequence);
50 
51         m_enabled = outValue.Get<bool>();
52 
53         if (m_enabled)
54         {
55             MediaUserSetting::Value outValue_ratio;
56             MediaUserSetting::Value outValue_type;
57 #if (_DEBUG || _RELEASE_INTERNAL)
58 
59             ReadUserSetting(m_userSettingPtr,
60                 outValue_ratio,
61                 "Fast Pass Encode Downscale Ratio",
62                 MediaUserSetting::Group::Sequence);
63             ReadUserSetting(m_userSettingPtr,
64                 outValue_type,
65                 "Fast Pass Encode Downscale Type",
66                 MediaUserSetting::Group::Sequence);
67 #endif
68 
69             m_fastPassDownScaleRatio = (outValue_ratio.Get<int32_t>() == 1) ? 1 : 2;
70             m_fastPassDownScaleType  = (uint8_t)outValue_type.Get<int32_t>();
71         }
72     }
73 
~Av1FastPass()74     Av1FastPass::~Av1FastPass()
75     {
76         ENCODE_FUNC_CALL();
77     }
78 
Update(void * params)79     MOS_STATUS Av1FastPass::Update(void *params)
80     {
81         ENCODE_CHK_NULL_RETURN(m_basicFeature);
82         PCODEC_AV1_ENCODE_PICTURE_PARAMS av1PicParams = m_basicFeature->m_av1PicParams;
83         ENCODE_CHK_NULL_RETURN(av1PicParams);
84 
85         if (AV1_FAST_PASS_4X_DS(m_fastPassDownScaleRatio))
86         {
87             // 4x down scale and av1 needs 8-pixels aligned
88             m_dsWidth  = MOS_ALIGN_FLOOR((av1PicParams->frame_width_minus1 + 1) >> 2, 8);
89             m_dsHeight = MOS_ALIGN_FLOOR((av1PicParams->frame_height_minus1 + 1) >> 2, 8);
90         }else
91         {
92             // 2x down scale and av1 needs 8-pixels aligned
93             m_dsWidth  = MOS_ALIGN_FLOOR((av1PicParams->frame_width_minus1 + 1) >> 1, 8);
94             m_dsHeight = MOS_ALIGN_FLOOR((av1PicParams->frame_height_minus1 + 1) >> 1, 8);
95         }
96 
97         return MOS_STATUS_SUCCESS;
98     }
99 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,Av1FastPass)100     MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, Av1FastPass)
101     {
102         if (m_enabled)
103         {
104             params.fastPassEn    = m_enabled;
105             params.fastPassScale = m_fastPassDownScaleRatio;  // fastPassScale:0 indicates 4x4 ds, 1 indicates 2x2 ds
106             params.DownScaleType = m_fastPassDownScaleType;   // DownScaleType:0 indicates bilinear, 1 indicates NN
107 
108             params.chromaType     = AVP_CHROMA_FORMAT_YUV420;
109             params.bitDepthMinus8 = 0;
110         }
111         return MOS_STATUS_SUCCESS;
112     }
113 
MHW_SETPAR_DECL_SRC(VDENC_CMD2,Av1FastPass)114     MHW_SETPAR_DECL_SRC(VDENC_CMD2, Av1FastPass)
115     {
116         ENCODE_FUNC_CALL();
117 
118         if (m_enabled)
119         {
120             params.width  = m_dsWidth;
121             params.height = m_dsHeight;
122         }
123         return MOS_STATUS_SUCCESS;
124     }
125 
MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE,Av1FastPass)126     MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE, Av1FastPass)
127     {
128         ENCODE_FUNC_CALL();
129 
130         PCODEC_AV1_ENCODE_PICTURE_PARAMS av1PicParams = m_basicFeature->m_av1PicParams;
131         ENCODE_CHK_NULL_RETURN(av1PicParams);
132         bool m_enablePalette = av1PicParams->PicFlags.fields.PaletteModeEnable;
133 
134         if (m_enabled)
135         {
136             params.tileWidth   = m_dsWidth;
137             params.tileHeight  = m_dsHeight;
138 
139             if (m_enablePalette && m_basicFeature->m_is10Bit)
140             {
141                 params.VdencHEVCVP9TileSlicePar5 -= 2;
142             }
143         }
144         return MOS_STATUS_SUCCESS;
145     }
146 
MHW_SETPAR_DECL_SRC(VDENC_WALKER_STATE,Av1FastPass)147     MHW_SETPAR_DECL_SRC(VDENC_WALKER_STATE, Av1FastPass)
148     {
149         ENCODE_FUNC_CALL();
150 
151         if (m_enabled)
152         {
153             //one tile supported only
154             params.tileSliceStartLcuMbX = 0;
155             params.tileSliceStartLcuMbY = 0;
156             params.nextTileSliceStartLcuMbX = MOS_ROUNDUP_DIVIDE(m_dsWidth, av1SuperBlockWidth);
157             params.nextTileSliceStartLcuMbY = MOS_ROUNDUP_DIVIDE(m_dsHeight, av1SuperBlockHeight);
158         }
159 
160         return MOS_STATUS_SUCCESS;
161     }
162 
MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE,Av1FastPass)163     MHW_SETPAR_DECL_SRC(VDENC_REF_SURFACE_STATE, Av1FastPass)
164     {
165         ENCODE_FUNC_CALL();
166 
167         if (m_enabled)
168         {
169             params.width  = m_dsWidth;
170             params.height = m_dsHeight;
171             params.format = Format_NV12;
172 
173             if (m_basicFeature->m_chromaFormat == AVP_CHROMA_FORMAT_YUV444
174                 || m_basicFeature->m_chromaFormat == AVP_CHROMA_FORMAT_YUV422)
175             {
176                 params.vOffset = params.uOffset;
177             }
178         }
179 
180         return MOS_STATUS_SUCCESS;
181     }
182 
MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE,Av1FastPass)183     MHW_SETPAR_DECL_SRC(VDENC_DS_REF_SURFACE_STATE, Av1FastPass)
184     {
185         ENCODE_FUNC_CALL();
186 
187         if (m_enabled)
188         {
189             uint32_t dsWidth4x  = m_dsWidth / SCALE_FACTOR_4x;
190             uint32_t dsHeight4x = m_dsHeight / SCALE_FACTOR_4x;
191 
192             params.heightStage1 = dsHeight4x >> 1;
193             params.widthStage1  = dsWidth4x >> 1;
194             params.heightStage2 = dsHeight4x;
195             params.widthStage2  = dsWidth4x;
196         }
197 
198         return MOS_STATUS_SUCCESS;
199     }
200 
MHW_SETPAR_DECL_SRC(AVP_TILE_CODING,Av1FastPass)201     MHW_SETPAR_DECL_SRC(AVP_TILE_CODING, Av1FastPass)
202     {
203         ENCODE_FUNC_CALL();
204 
205         if (m_enabled)
206         {
207             //one tile supported only
208             params.tileColPositionInSb = 0;
209             params.tileRowPositionInSb = 0;
210             params.tileWidthInSbMinus1  = MOS_ROUNDUP_DIVIDE(m_dsWidth, av1SuperBlockWidth) - 1;
211             params.tileHeightInSbMinus1 = MOS_ROUNDUP_DIVIDE(m_dsHeight, av1SuperBlockHeight) - 1;
212         }
213 
214         return MOS_STATUS_SUCCESS;
215     }
216 
MHW_SETPAR_DECL_SRC(AVP_PIC_STATE,Av1FastPass)217     MHW_SETPAR_DECL_SRC(AVP_PIC_STATE, Av1FastPass)
218     {
219         ENCODE_FUNC_CALL();
220 
221         if (m_enabled)
222         {
223             params.frameWidthMinus1  = m_dsWidth - 1;
224             params.frameHeightMinus1 = m_dsHeight - 1;
225             for (auto i = 0; i <= av1NumInterRefFrames; i++)
226             {
227                 params.refFrameRes[i] = CAT2SHORTS(m_dsWidth - 1, m_dsHeight - 1);
228             }
229             params.chromaFormat = AVP_CHROMA_FORMAT_YUV420;
230             params.bitDepthIdc  = 0;
231         }
232 
233         return MOS_STATUS_SUCCESS;
234     }
235 
MHW_SETPAR_DECL_SRC(AVP_SURFACE_STATE,Av1FastPass)236     MHW_SETPAR_DECL_SRC(AVP_SURFACE_STATE, Av1FastPass)
237     {
238         ENCODE_FUNC_CALL();
239 
240         if (m_enabled)
241         {
242             if (m_basicFeature->m_chromaFormat == AVP_CHROMA_FORMAT_YUV444
243                 || m_basicFeature->m_chromaFormat == AVP_CHROMA_FORMAT_YUV422)
244             {
245                 params.vOffset = params.uOffset;
246             }
247             params.srcFormat          = mhw::vdbox::avp::SURFACE_FORMAT::SURFACE_FORMAT_PLANAR4208;
248             params.bitDepthLumaMinus8 = 0;
249         }
250 
251         return MOS_STATUS_SUCCESS;
252     }
253 
254 }  // namespace encode
255