1 /*
2 * Copyright (c) 2018-2022, 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_basic_feature.cpp
24 //! \brief Defines the common interface for encode basic feature
25 //!
26
27 #include "encode_basic_feature.h"
28 #include "encode_utils.h"
29 #include "encode_allocator.h"
30 #include "mos_interface.h"
31 #include "codec_def_common_encode.h"
32 #include "codec_def_encode_vp9.h"
33 #include "codec_def_encode_hevc.h"
34
35 namespace encode
36 {
EncodeBasicFeature(EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,TrackedBuffer * trackedBuf,RecycleResource * recycleBuf)37 EncodeBasicFeature::EncodeBasicFeature(
38 EncodeAllocator *allocator,
39 CodechalHwInterfaceNext *hwInterface,
40 TrackedBuffer *trackedBuf,
41 RecycleResource *recycleBuf):
42 MediaFeature(hwInterface ? hwInterface->GetOsInterface() : nullptr),
43 m_trackedBuf(trackedBuf),
44 m_recycleBuf(recycleBuf),
45 m_allocator(allocator)
46 {
47 if(hwInterface)
48 {
49 m_osInterface = hwInterface->GetOsInterface();
50 }
51
52 }
53
Init(void * setting)54 MOS_STATUS EncodeBasicFeature::Init(void *setting)
55 {
56 ENCODE_FUNC_CALL();
57 ENCODE_CHK_NULL_RETURN(setting);
58
59 CodechalSetting *codecSettings = (CodechalSetting*)setting;
60 m_standard = codecSettings->standard;
61 m_mode = codecSettings->mode;
62 m_codecFunction = codecSettings->codecFunction;
63
64 m_is10Bit = codecSettings->lumaChromaDepth == CODECHAL_LUMA_CHROMA_DEPTH_10_BITS ? true : false;
65 m_chromaFormat = codecSettings->chromaFormat;
66 m_bitDepth = codecSettings->lumaChromaDepth == CODECHAL_LUMA_CHROMA_DEPTH_8_BITS ?
67 8 : (codecSettings->lumaChromaDepth == CODECHAL_LUMA_CHROMA_DEPTH_10_BITS ? 10 : 12);
68 m_standard = codecSettings->standard;
69
70 m_oriFrameWidth = codecSettings->width;
71 m_oriFrameHeight = codecSettings->height;
72 m_picWidthInMb = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_oriFrameWidth);
73 m_picHeightInMb = (uint16_t)CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_oriFrameHeight);
74 m_frameWidth = m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH;
75 m_frameHeight = m_picHeightInMb * CODECHAL_MACROBLOCK_HEIGHT;
76
77 m_currOriginalPic.PicFlags = PICTURE_INVALID;
78 m_currOriginalPic.FrameIdx = 0;
79 m_currOriginalPic.PicEntry = 0;
80
81 //RCPanic settings
82 MediaUserSetting::Value outValue;
83 ReadUserSetting(
84 m_userSettingPtr,
85 outValue,
86 "RC Panic Mode",
87 MediaUserSetting::Group::Sequence);
88 m_panicEnable = outValue.Get<bool>();
89
90 ReadUserSetting(
91 m_userSettingPtr,
92 outValue,
93 "HEVC Encode Enable HW Stitch",
94 MediaUserSetting::Group::Sequence);
95 m_enableTileStitchByHW = outValue.Get<bool>();
96
97 return MOS_STATUS_SUCCESS;
98 }
99
Update(void * params)100 MOS_STATUS EncodeBasicFeature::Update(void *params)
101 {
102 ENCODE_FUNC_CALL();
103 ENCODE_CHK_NULL_RETURN(params);
104 ENCODE_CHK_NULL_RETURN(m_allocator);
105
106 EncoderParams* encodeParams = (EncoderParams*)params;
107
108 m_newSeq = encodeParams->bNewSeq; // used by all except JPEG
109 m_mbDataBufferSize = encodeParams->dwMbDataBufferSize;// used by all except JPEG
110 m_newVuiData = encodeParams->bNewVuiData; // used by AVC and MPEG2
111 m_picQuant = encodeParams->bPicQuant ; // used by AVC and MPEG2
112 m_newQmatrixData = encodeParams->bNewQmatrixData; // used by AVC and MPEG2
113 m_numSlices = encodeParams->dwNumSlices; // used by all except VP9
114 m_slcData = (PCODEC_ENCODER_SLCDATA)(encodeParams->pSlcHeaderData);// used by AVC, MPEG2, and HEVC
115
116 ENCODE_CHK_NULL_RETURN(encodeParams->psRawSurface);
117 m_rawSurface = *(encodeParams->psRawSurface); // used by all
118 m_allocator->GetSurfaceInfo(&m_rawSurface);
119 ENCODE_CHK_STATUS_RETURN(m_allocator->UpdateResourceUsageType(&m_rawSurface.OsResource, MOS_HW_RESOURCE_USAGE_ENCODE_INPUT_RAW));
120
121 ENCODE_CHK_NULL_RETURN(encodeParams->presBitstreamBuffer);
122 m_resBitstreamBuffer = *(encodeParams->presBitstreamBuffer); // used by all
123
124 m_resMetadataBuffer = (encodeParams->presMetadataBuffer);
125 m_metaDataOffset = encodeParams->metaDataOffset;
126
127 // Get resource details of the bitstream resource
128 MOS_SURFACE bsSurface;
129 MOS_ZeroMemory(&bsSurface, sizeof(bsSurface));
130 bsSurface.OsResource = m_resBitstreamBuffer;
131 m_allocator->GetSurfaceInfo(&bsSurface);
132 ENCODE_CHK_STATUS_RETURN(m_allocator->UpdateResourceUsageType(&m_resBitstreamBuffer, MOS_HW_RESOURCE_USAGE_ENCODE_OUTPUT_BITSTREAM));
133
134 m_bitstreamSize = encodeParams->dwBitstreamSize = bsSurface.dwHeight * bsSurface.dwWidth;
135
136 if (Mos_ResourceIsNull(&m_rawSurface.OsResource))
137 {
138 ENCODE_ASSERTMESSAGE("Raw surface is nullptr!");
139 return MOS_STATUS_INVALID_PARAMETER;
140 }
141
142 #if (_DEBUG || _RELEASE_INTERNAL)
143 ReportUserSettingForDebug(
144 m_userSettingPtr,
145 "Encode Raw Surface Tile",
146 m_rawSurface.TileType,
147 MediaUserSetting::Group::Sequence);
148 #endif
149
150 m_rawSurfaceToEnc =
151 m_rawSurfaceToPak = &m_rawSurface;
152
153 if (encodeParams->psReconSurface != nullptr)
154 {
155 m_reconSurface = *(encodeParams->psReconSurface); // used by all except JPEG
156 ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(&m_reconSurface));
157 ENCODE_CHK_STATUS_RETURN(m_allocator->UpdateResourceUsageType(&m_reconSurface.OsResource, MOS_HW_RESOURCE_USAGE_ENCODE_OUTPUT_PICTURE));
158 }
159
160 if (encodeParams->pBSBuffer != nullptr)
161 {
162 m_bsBuffer = *(encodeParams->pBSBuffer); // used by all except VP9
163 }
164
165 m_mbDisableSkipMapEnabled = encodeParams->bMbDisableSkipMapEnabled;
166 m_mbQpDataEnabled = encodeParams->bMbQpDataEnabled;
167
168 if (encodeParams->bMbQpDataEnabled && encodeParams->psMbQpDataSurface != nullptr)
169 {
170 m_mbQpDataSurface = *(encodeParams->psMbQpDataSurface);
171 ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(&m_mbQpDataSurface));
172 }
173
174 if (encodeParams->psMbDisableSkipMapSurface != nullptr)
175 {
176 m_mbDisableSkipMapSurface = *(encodeParams->psMbDisableSkipMapSurface);
177 ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(&m_mbDisableSkipMapSurface));
178 }
179
180 m_slcData =
181 (PCODEC_ENCODER_SLCDATA)(encodeParams->pSlcHeaderData); // used by AVC, MPEG2, and HEVC
182
183 m_newSeqHeader = encodeParams->newSeqHeader;
184 m_newPpsHeader = encodeParams->newPpsHeader;
185
186 if (CodecHalUsesVideoEngine(m_codecFunction))
187 {
188 //UpdateBitstreamSize()
189 // Get resource details of the bitstream resource
190 MOS_SURFACE details;
191 MOS_ZeroMemory(&details, sizeof(details));
192 details.Format = Format_Invalid;
193 ENCODE_CHK_STATUS_RETURN(
194 m_osInterface->pfnGetResourceInfo(m_osInterface, &m_resBitstreamBuffer, &details));
195 m_bitstreamSize = details.dwHeight * details.dwWidth;
196 }
197
198 // check output Chroma format
199 UpdateFormat(params);
200
201 m_predicationNotEqualZero = encodeParams->m_predicationNotEqualZero;
202 m_predicationEnabled = encodeParams->m_predicationEnabled;
203 m_setMarkerEnabled = encodeParams->m_setMarkerEnabled;
204 m_predicationResOffset = encodeParams->m_predicationResOffset;
205 m_presPredication = encodeParams->m_presPredication;
206 m_tempPredicationBuffer = encodeParams->m_tempPredicationBuffer;
207
208 if (m_predicationBuffer == nullptr && m_predicationEnabled)
209 {
210 // initiate allocation parameters and lock flags
211 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
212 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
213 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
214 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
215 allocParamsForBufferLinear.Format = Format_Buffer;
216 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
217 allocParamsForBufferLinear.dwBytes = sizeof(uint32_t);
218 allocParamsForBufferLinear.pBufName = "PredicationBuffer";
219 m_predicationBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
220 }
221
222 return MOS_STATUS_SUCCESS;
223 }
224
UpdateFormat(void * params)225 MOS_STATUS EncodeBasicFeature::UpdateFormat(void *params)
226 {
227 ENCODE_FUNC_CALL();
228 ENCODE_CHK_NULL_RETURN(params);
229 EncoderParams* encodeParams = (EncoderParams*)params;
230
231 PCODEC_VP9_ENCODE_SEQUENCE_PARAMS vp9SeqParams = nullptr;
232 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS hevcSeqParams = nullptr;
233
234 // check output Chroma format
235 switch (m_standard)
236 {
237 case CODECHAL_HEVC:
238 hevcSeqParams = static_cast<PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS>(encodeParams->pSeqParams);
239 ENCODE_CHK_NULL_RETURN(hevcSeqParams);
240 m_outputChromaFormat = hevcSeqParams->chroma_format_idc;
241 break;
242
243 case CODECHAL_VP9:
244 // check output Chroma format
245 vp9SeqParams = static_cast<PCODEC_VP9_ENCODE_SEQUENCE_PARAMS>(encodeParams->pSeqParams);
246 if (VP9_ENCODED_CHROMA_FORMAT_YUV420 == vp9SeqParams->SeqFlags.fields.EncodedFormat)
247 {
248 m_outputChromaFormat = HCP_CHROMA_FORMAT_YUV420;
249 }
250 else if (VP9_ENCODED_CHROMA_FORMAT_YUV422 == vp9SeqParams->SeqFlags.fields.EncodedFormat)
251 {
252 m_outputChromaFormat = HCP_CHROMA_FORMAT_YUV422;
253 }
254 else if (VP9_ENCODED_CHROMA_FORMAT_YUV444 == vp9SeqParams->SeqFlags.fields.EncodedFormat)
255 {
256 m_outputChromaFormat = HCP_CHROMA_FORMAT_YUV444;
257 }
258 else
259 {
260 ENCODE_ASSERTMESSAGE("Invalid output chromat format in VP9 Seq param!");
261 return MOS_STATUS_INVALID_PARAMETER;
262 }
263 break;
264
265 default:
266 break;
267 }
268
269 if (m_outputChromaFormat == HCP_CHROMA_FORMAT_YUV422)
270 {
271 if (Format_YUY2 != m_reconSurface.Format && Format_Y216 != m_reconSurface.Format)
272 {
273 ENCODE_ASSERTMESSAGE("Recon surface format is not correct!");
274 return MOS_STATUS_INVALID_PARAMETER;
275 }
276 else if (m_reconSurface.dwHeight < m_oriFrameHeight * 2 ||
277 m_reconSurface.dwWidth < m_oriFrameWidth / 2)
278 {
279 ENCODE_ASSERTMESSAGE("Recon surface allocation size is not correct!");
280 return MOS_STATUS_INVALID_PARAMETER;
281 }
282 }
283 return MOS_STATUS_SUCCESS;
284 }
285
UpdateTrackedBufferParameters()286 MOS_STATUS EncodeBasicFeature::UpdateTrackedBufferParameters()
287 {
288 ENCODE_CHK_NULL_RETURN(m_trackedBuf);
289
290 MOS_ALLOC_GFXRES_PARAMS allocParamsForLinear;
291 MOS_ZeroMemory(&allocParamsForLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
292 allocParamsForLinear.Type = MOS_GFXRES_BUFFER;
293 allocParamsForLinear.TileType = MOS_TILE_LINEAR;
294 allocParamsForLinear.Format = Format_Buffer;
295
296 MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
297 MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
298 allocParamsForBuffer2D.Type = MOS_GFXRES_2D;
299 allocParamsForBuffer2D.TileType = MOS_TILE_Y;
300 allocParamsForBuffer2D.Format = Format_NV12;
301 allocParamsForBuffer2D.Flags.bNotLockable = allocParamsForLinear.Flags.bNotLockable
302 = ((m_standard == CODECHAL_AV1) && !m_lockableResource);
303
304 if (m_mbCodeSize > 0 && !m_isMbCodeRegistered)
305 {
306 allocParamsForLinear.pBufName = "mbCodeBuffer";
307 // Must reserve at least 8 cachelines after MI_BATCH_BUFFER_END_CMD since HW prefetch max 8 cachelines from BB everytime
308 // + 8 * CODECHAL_CACHELINE_SIZE is inherient from legacy code
309 allocParamsForLinear.dwBytes = m_mbCodeSize + 8 * CODECHAL_CACHELINE_SIZE;
310 allocParamsForLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
311 ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::mbCodedBuffer, allocParamsForLinear));
312 }
313
314 if (m_mvDataSize > 0)
315 {
316 allocParamsForLinear.pBufName = "mvDataBuffer";
317 allocParamsForLinear.dwBytes = m_mvDataSize;
318 ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::mvDataBuffer, allocParamsForLinear));
319 }
320
321 if (m_downscaledWidth4x > 0 && m_downscaledHeight4x > 0)
322 {
323 allocParamsForBuffer2D.dwWidth = m_downscaledWidth4x;
324 allocParamsForBuffer2D.dwHeight = m_downscaledHeight4x;
325 allocParamsForBuffer2D.pBufName = "4xDSSurface";
326 allocParamsForBuffer2D.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
327 ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::ds4xSurface, allocParamsForBuffer2D));
328
329 allocParamsForBuffer2D.dwWidth = m_downscaledWidth4x >> 1;
330 allocParamsForBuffer2D.dwHeight = MOS_ALIGN_CEIL(m_downscaledHeight4x >> 1, MOS_YTILE_H_ALIGNMENT) << 1;
331 allocParamsForBuffer2D.pBufName = "8xDSSurface";
332 allocParamsForBuffer2D.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
333 ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(encode::BufferType::ds8xSurface, allocParamsForBuffer2D));
334 }
335
336 return MOS_STATUS_SUCCESS;
337 }
338
Reset(CODEC_REF_LIST * refList)339 MOS_STATUS EncodeBasicFeature::Reset(CODEC_REF_LIST *refList)
340 {
341 ENCODE_CHK_NULL_RETURN(refList);
342 ENCODE_CHK_NULL_RETURN(m_trackedBuf);
343
344 m_trackedBuf->Release(refList);
345 return MOS_STATUS_SUCCESS;
346 }
347 } // namespace encode
348