1 /*
2 * Copyright (c) 2017-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 codechal_encode_avc_base.cpp
24 //! \brief Defines base class for AVC encoder.
25 //!
26 #include "codechal_encode_avc_base.h"
27 #include "codechal_vdenc_avc.h"
28 #include "codechal_encode_avc.h"
29 #include "codechal_mmc_encode_avc.h"
30 #include "hal_oca_interface.h"
31
32 #define CODECHAL_ENCODE_AVC_CQP_NUM_OF_PASSES 2
33 #define CODECHAL_ENCODE_AVC_ICQ_NUM_OF_PASSES 2
34 #define CODECHAL_ENCODE_AVC_EXTENDED_SAR 255
35
36 const uint8_t CODECHAL_ENCODE_AVC_SFD_CostTable_P_FRAME[CODEC_AVC_NUM_QP] =
37 {
38 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 60, 60, 60, 60, 73, 73, 73, 76, 76, 76, 88, 89, 89, 91, 92, 93, 104, 104, 106, 107, 108, 109, 120, 120, 122, 123, 124, 125, 136, 136, 138, 139, 140, 141, 143, 143};
39
40 const uint8_t CODECHAL_ENCODE_AVC_SFD_CostTable_B_FRAME[CODEC_AVC_NUM_QP] =
41 {
42 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 73, 73, 73, 73, 77, 77, 77, 89, 89, 89, 91, 93, 93, 95, 105, 106, 107, 108, 110, 111, 121, 122, 123, 124, 125, 127, 137, 138, 139, 140, 142, 143, 143, 143, 143, 143};
43
CodecHalAvcEncode_GetMaxVmvR(uint8_t levelIdc)44 uint32_t CodecHalAvcEncode_GetMaxVmvR(uint8_t levelIdc)
45 {
46 int maxVmvR = 128 * 4;
47
48 // See JVT Spec Annex A Table A-1 Level limits for below mapping
49 // maxVmvR is in luma quarter pel unit
50 switch (levelIdc)
51 {
52 case CODEC_AVC_LEVEL_1:
53 case CODEC_AVC_LEVEL_1b:
54 maxVmvR = 64 * 4;
55 break;
56 case CODEC_AVC_LEVEL_11:
57 case CODEC_AVC_LEVEL_12:
58 case CODEC_AVC_LEVEL_13:
59 case CODEC_AVC_LEVEL_2:
60 maxVmvR = 128 * 4;
61 break;
62 case CODEC_AVC_LEVEL_21:
63 case CODEC_AVC_LEVEL_22:
64 case CODEC_AVC_LEVEL_3:
65 maxVmvR = 256 * 4;
66 break;
67 case CODEC_AVC_LEVEL_31:
68 case CODEC_AVC_LEVEL_32:
69 case CODEC_AVC_LEVEL_4:
70 case CODEC_AVC_LEVEL_41:
71 case CODEC_AVC_LEVEL_42:
72 case CODEC_AVC_LEVEL_5:
73 case CODEC_AVC_LEVEL_51:
74 case CODEC_AVC_LEVEL_52:
75 maxVmvR = 512 * 4;
76 break;
77 default:
78 CODECHAL_ENCODE_NORMALMESSAGE("Unsupported LevelIDC setting.");
79 CODECHAL_ENCODE_ASSERT(false);
80 break;
81 }
82
83 return maxVmvR;
84 }
85
CodecHalAvcEncode_GetMaxMvLen(uint8_t levelIdc)86 uint32_t CodecHalAvcEncode_GetMaxMvLen(uint8_t levelIdc)
87 {
88 int maxMvLen = 127;
89
90 // See JVT Spec Annex A Table A-1 Level limits for below mapping
91 // MaxVmvR is in luma quarter pel unit
92 switch (levelIdc)
93 {
94 case CODEC_AVC_LEVEL_1:
95 case CODEC_AVC_LEVEL_1b:
96 maxMvLen = 63;
97 break;
98 case CODEC_AVC_LEVEL_11:
99 case CODEC_AVC_LEVEL_12:
100 case CODEC_AVC_LEVEL_13:
101 case CODEC_AVC_LEVEL_2:
102 maxMvLen = 127;
103 break;
104 case CODEC_AVC_LEVEL_21:
105 case CODEC_AVC_LEVEL_22:
106 case CODEC_AVC_LEVEL_3:
107 maxMvLen = 255;
108 break;
109 case CODEC_AVC_LEVEL_31:
110 case CODEC_AVC_LEVEL_32:
111 case CODEC_AVC_LEVEL_4:
112 case CODEC_AVC_LEVEL_41:
113 case CODEC_AVC_LEVEL_42:
114 case CODEC_AVC_LEVEL_5:
115 case CODEC_AVC_LEVEL_51:
116 case CODEC_AVC_LEVEL_52:
117 maxMvLen = 511;
118 break;
119 default:
120 CODECHAL_ENCODE_NORMALMESSAGE("Unsupported LevelIDC setting.");
121 CODECHAL_ENCODE_ASSERT(false);
122 break;
123 }
124
125 return maxMvLen;
126 }
127
CodecHalAvcEncode_GetFieldParity(PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams,uint32_t list,uint32_t index)128 bool CodecHalAvcEncode_GetFieldParity(
129 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams,
130 uint32_t list,
131 uint32_t index)
132 {
133 uint32_t fieldParity = 0;
134
135 if (slcParams == nullptr)
136 {
137 CODECHAL_ENCODE_ASSERTMESSAGE("Invalid (NULL) Pointer.");
138 return false;
139 }
140 CODECHAL_ENCODE_ASSERT(list == LIST_0 || list == LIST_1);
141 CODECHAL_ENCODE_ASSERT(index < CODEC_AVC_MAX_NUM_REF_FRAME * 2);
142
143 if (!CodecHal_PictureIsInvalid(slcParams->RefPicList[list][index]))
144 {
145 fieldParity = CodecHal_PictureIsBottomField(slcParams->RefPicList[list][index]);
146 }
147
148 return (fieldParity ? true : false);
149 }
150
SendSlice(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_AVC_SLICE_STATE params)151 MOS_STATUS CodechalEncodeAvcBase::SendSlice(
152 PMOS_COMMAND_BUFFER cmdBuffer,
153 PMHW_VDBOX_AVC_SLICE_STATE params)
154 {
155 PCODEC_AVC_ENCODE_SLICE_PARAMS avcSlcParams;
156 MHW_VDBOX_AVC_REF_IDX_PARAMS refIdxParams;
157 MHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS weightOffsetParams;
158 MHW_BATCH_BUFFER secondLevelBatchBuffer;
159 MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
160 MHW_VDBOX_VDENC_WALKER_STATE_PARAMS vdencWalkerStateParams;
161 PMOS_COMMAND_BUFFER cmdBufferInUse;
162 PMHW_BATCH_BUFFER batchBufferInUse;
163 uint32_t bitSize, offSet;
164 uint32_t maxBytesInPakInsertObjCmd;
165 uint32_t nalunitPosiSize, nalunitPosiOffset;
166 bool insertZeroByteWA = false;
167
168 CODECHAL_ENCODE_FUNCTION_ENTER;
169
170 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
171 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
172 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcPicIdx);
173 CODECHAL_ENCODE_CHK_NULL_RETURN(params->presDataBuffer);
174 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pEncodeAvcSeqParams);
175 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pEncodeAvcPicParams);
176 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pEncodeAvcSliceParams);
177 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
178 CODECHAL_ENCODE_CHK_NULL_RETURN(params->ppNalUnitParams);
179
180 avcSlcParams = params->pEncodeAvcSliceParams;
181 maxBytesInPakInsertObjCmd = ((2 << 11) - 1) * 4; // 12 bits for DwordLength field in PAK_INSERT_OBJ cmd
182 nalunitPosiSize = 0;
183 nalunitPosiOffset = 0;
184
185 // VDENC does not use batch buffer for slice state
186 if (params->bSingleTaskPhaseSupported && !params->bVdencInUse)
187 {
188 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBatchBufferForPakSlices);
189 batchBufferInUse = params->pBatchBufferForPakSlices;
190 cmdBufferInUse = nullptr;
191 }
192 else
193 {
194 batchBufferInUse = nullptr;
195 cmdBufferInUse = cmdBuffer;
196 }
197
198 // Add reference index and weight offset commands
199 refIdxParams.CurrPic = params->pEncodeAvcPicParams->CurrReconstructedPic;
200 refIdxParams.isEncode = true;
201 refIdxParams.bVdencInUse = params->bVdencInUse;
202 refIdxParams.pAvcPicIdx = params->pAvcPicIdx;
203 refIdxParams.avcRefList = (void **)m_refList;
204 refIdxParams.oneOnOneMapping = params->oneOnOneMapping;
205
206 CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
207 &refIdxParams.RefPicList,
208 2 * 32 * sizeof(CODEC_PICTURE),
209 avcSlcParams->RefPicList,
210 2 * 32 * sizeof(CODEC_PICTURE)));
211 if (Slice_Type[avcSlcParams->slice_type] == SLICE_P)
212 {
213 refIdxParams.uiList = LIST_0;
214 refIdxParams.uiNumRefForList[LIST_0] = avcSlcParams->num_ref_idx_l0_active_minus1 + 1;
215
216 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcRefIdx(cmdBufferInUse, batchBufferInUse, &refIdxParams));
217
218 if (params->pEncodeAvcPicParams->weighted_pred_flag == EXPLICIT_WEIGHTED_INTER_PRED_MODE)
219 {
220 weightOffsetParams.uiList = LIST_0;
221 weightOffsetParams.uiLumaLogWeightDenom = avcSlcParams->luma_log2_weight_denom;
222 weightOffsetParams.uiChromaLogWeightDenom = avcSlcParams->chroma_log2_weight_denom;
223 weightOffsetParams.uiLumaWeightFlag = avcSlcParams->luma_weight_flag[LIST_0];
224 weightOffsetParams.uiChromaWeightFlag = avcSlcParams->chroma_weight_flag[LIST_0];
225 weightOffsetParams.uiNumRefForList = avcSlcParams->num_ref_idx_l0_active_minus1 + 1;
226
227 CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
228 &weightOffsetParams.Weights,
229 sizeof(weightOffsetParams.Weights),
230 &avcSlcParams->Weights,
231 sizeof(avcSlcParams->Weights)));
232 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcWeightOffset(
233 cmdBufferInUse,
234 batchBufferInUse,
235 &weightOffsetParams));
236 }
237 }
238
239 else if (Slice_Type[avcSlcParams->slice_type] == SLICE_B)
240 {
241 refIdxParams.uiList = LIST_0;
242 refIdxParams.uiNumRefForList[LIST_0] = avcSlcParams->num_ref_idx_l0_active_minus1 + 1;
243
244 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcRefIdx(cmdBufferInUse, batchBufferInUse, &refIdxParams));
245
246 refIdxParams.uiList = LIST_1;
247 refIdxParams.uiNumRefForList[LIST_1] = avcSlcParams->num_ref_idx_l1_active_minus1 + 1;
248
249 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcRefIdx(cmdBufferInUse, batchBufferInUse, &refIdxParams));
250
251 if (params->pEncodeAvcPicParams->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE)
252 {
253 CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
254 &weightOffsetParams.Weights,
255 sizeof(weightOffsetParams.Weights),
256 &avcSlcParams->Weights,
257 sizeof(avcSlcParams->Weights)));
258 weightOffsetParams.uiList = LIST_0;
259 weightOffsetParams.uiLumaLogWeightDenom = avcSlcParams->luma_log2_weight_denom;
260 weightOffsetParams.uiChromaLogWeightDenom = avcSlcParams->chroma_log2_weight_denom;
261 weightOffsetParams.uiLumaWeightFlag = avcSlcParams->luma_weight_flag[LIST_0];
262 weightOffsetParams.uiChromaWeightFlag = avcSlcParams->chroma_weight_flag[LIST_0];
263 weightOffsetParams.uiNumRefForList = avcSlcParams->num_ref_idx_l0_active_minus1 + 1;
264 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcWeightOffset(
265 cmdBufferInUse,
266 batchBufferInUse,
267 &weightOffsetParams));
268
269 weightOffsetParams.uiList = LIST_1;
270 weightOffsetParams.uiLumaLogWeightDenom = avcSlcParams->luma_log2_weight_denom;
271 weightOffsetParams.uiChromaLogWeightDenom = avcSlcParams->chroma_log2_weight_denom;
272 weightOffsetParams.uiLumaWeightFlag = avcSlcParams->luma_weight_flag[LIST_1];
273 weightOffsetParams.uiChromaWeightFlag = avcSlcParams->chroma_weight_flag[LIST_1];
274 weightOffsetParams.uiNumRefForList = avcSlcParams->num_ref_idx_l1_active_minus1 + 1;
275 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcWeightOffset(
276 cmdBufferInUse,
277 batchBufferInUse,
278 &weightOffsetParams));
279 }
280 }
281
282 // add AVC Slice state commands
283 CODECHAL_ENCODE_CHK_STATUS_RETURN(AddMfxAvcSlice(cmdBufferInUse, batchBufferInUse, params));
284
285 //insert AU, SPS, PSP headers before first slice header
286 if (params->bInsertBeforeSliceHeaders)
287 {
288 uint8_t *dataBase = (uint8_t *)(params->pBsBuffer->pBase);
289 uint32_t data = ((*dataBase) << 24) + ((*(dataBase + 1)) << 16) + ((*(dataBase + 2)) << 8) + (*(dataBase + 3));
290 // Only apply the WaSuperSliceHeaderPacking for the cases with 00 00 00 01 start code
291 if (data == 0x00000001)
292 {
293 insertZeroByteWA = true;
294 }
295
296 bool isInsert;
297 uint32_t i;
298 for (i = 0; i < CODECHAL_ENCODE_AVC_MAX_NAL_TYPE; i++)
299 {
300 nalunitPosiSize = params->ppNalUnitParams[i]->uiSize;
301 nalunitPosiOffset = params->ppNalUnitParams[i]->uiOffset;
302 while (nalunitPosiSize > 0)
303 {
304 isInsert = params->ppNalUnitParams[i]->bInsertEmulationBytes;
305 bitSize = MOS_MIN(maxBytesInPakInsertObjCmd * 8, nalunitPosiSize * 8);
306 offSet = nalunitPosiOffset;
307
308 MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
309 pakInsertObjectParams.bEmulationByteBitsInsert = isInsert;
310 pakInsertObjectParams.uiSkipEmulationCheckCount = params->ppNalUnitParams[i]->uiSkipEmulationCheckCount;
311 pakInsertObjectParams.pBsBuffer = params->pBsBuffer;
312 pakInsertObjectParams.dwBitSize = bitSize;
313 pakInsertObjectParams.dwOffset = offSet;
314 pakInsertObjectParams.bHeaderLengthExcludeFrmSize = true; // Exclude header length from size calculation for accurate Cabac Zero Word Insertion
315
316 if (pakInsertObjectParams.bEmulationByteBitsInsert)
317 {
318 CODECHAL_ENCODE_VERBOSEMESSAGE("The emulation prevention bytes are not inserted by the app and are requested to be inserted by HW.");
319 }
320
321 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPakInsertObject(
322 cmdBufferInUse, batchBufferInUse, &pakInsertObjectParams));
323
324 if (nalunitPosiSize > maxBytesInPakInsertObjCmd)
325 {
326 nalunitPosiSize -= maxBytesInPakInsertObjCmd;
327 nalunitPosiOffset += maxBytesInPakInsertObjCmd;
328 }
329 else
330 {
331 nalunitPosiSize = 0;
332 }
333
334 insertZeroByteWA = false;
335 }
336 }
337 }
338
339 uint8_t *dataBase = (uint8_t *)(params->pBsBuffer->pBase + params->dwOffset);
340 uint32_t data = ((*dataBase) << 24) + ((*(dataBase + 1)) << 16) + ((*(dataBase + 2)) << 8) + (*(dataBase + 3));
341
342 if (data == 0x00000001)
343 {
344 insertZeroByteWA = true;
345 }
346
347 // Insert 0x00 for super slice case when PPS/AUD is not inserted
348 if (MEDIA_IS_WA(m_hwInterface->GetWaTable(), WaSuperSliceHeaderPacking) && insertZeroByteWA && params->bVdencInUse && m_hwInterface->m_isVdencSuperSliceEnabled)
349 {
350 MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
351 pakInsertObjectParams.pBsBuffer = params->pBsBuffer;
352 pakInsertObjectParams.dwBitSize = 8;
353 pakInsertObjectParams.dwOffset = params->dwOffset;
354
355 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPakInsertObject(
356 cmdBufferInUse, batchBufferInUse, &pakInsertObjectParams));
357 }
358
359 // Insert slice header
360 MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
361 pakInsertObjectParams.bLastHeader = true;
362 pakInsertObjectParams.bEmulationByteBitsInsert = true;
363
364 if (params->bAcceleratorHeaderPackingCaps)
365 {
366 // If driver does slice header packing set the skip count to 4
367 pakInsertObjectParams.uiSkipEmulationCheckCount = 4;
368 }
369 else
370 {
371 // App does the slice header packing, set the skip count passed by the app
372 pakInsertObjectParams.uiSkipEmulationCheckCount = params->uiSkipEmulationCheckCount;
373 }
374 pakInsertObjectParams.pBsBuffer = params->pBsBuffer;
375 // Slice Header Indicator should be set for VDENC for multi-slice case
376 pakInsertObjectParams.bSliceHeaderIndicator = (!params->bVdencInUse) ? false : true;
377
378 // Remove one byte of 00 for super slice case when PPS/AUD is not inserted, so that HW could patch slice header correctly
379 if (MEDIA_IS_WA(m_hwInterface->GetWaTable(), WaSuperSliceHeaderPacking) && insertZeroByteWA && params->bVdencInUse && m_hwInterface->m_isVdencSuperSliceEnabled)
380 {
381 pakInsertObjectParams.dwBitSize = params->dwLength - 8;
382 pakInsertObjectParams.dwOffset = params->dwOffset + 1;
383 }
384 else
385 {
386 pakInsertObjectParams.dwBitSize = params->dwLength;
387 pakInsertObjectParams.dwOffset = params->dwOffset;
388 }
389
390 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPakInsertObject(
391 cmdBufferInUse, batchBufferInUse, &pakInsertObjectParams));
392
393 if (params->bVdencInUse)
394 {
395 //For CNL VDENC Walker command and WeightsOffsets cmds are sent per Super slice
396 if (m_hwInterface->m_isVdencSuperSliceEnabled)
397 {
398 weightOffsetParams.pAvcPicParams = params->pEncodeAvcPicParams;
399 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencAvcWeightsOffsetsStateCmd(cmdBuffer, &weightOffsetParams));
400 CODECHAL_ENCODE_CHK_STATUS_RETURN(AddVdencSliceStateCmd(cmdBuffer, params));
401
402 vdencWalkerStateParams.Mode = CODECHAL_ENCODE_MODE_AVC;
403 vdencWalkerStateParams.slcIdx = params->dwSliceIndex;
404 vdencWalkerStateParams.pAvcSeqParams = params->pEncodeAvcSeqParams;
405 vdencWalkerStateParams.pAvcPicParams = params->pEncodeAvcPicParams;
406 vdencWalkerStateParams.pAvcSlcParams = avcSlcParams;
407 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencWalkerStateCmd(cmdBuffer, &vdencWalkerStateParams));
408 }
409 }
410 else
411 {
412 if (params->bSingleTaskPhaseSupported)
413 {
414 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(nullptr, batchBufferInUse));
415
416 // Insert Batch Buffer Start command to send AVC_PAK_OBJ data for MBs in this slice
417 MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER));
418 CODECHAL_ENCODE_CHK_NULL_RETURN(batchBufferInUse);
419 secondLevelBatchBuffer.OsResource = batchBufferInUse->OsResource;
420 secondLevelBatchBuffer.dwOffset = params->dwBatchBufferForPakSlicesStartOffset;
421 secondLevelBatchBuffer.bSecondLevel = true;
422 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(cmdBuffer, &secondLevelBatchBuffer));
423 }
424
425 // Insert Batch Buffer Start command to send AVC_PAK_OBJ data for MBs in this slice
426 MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER));
427 secondLevelBatchBuffer.OsResource = *params->presDataBuffer;
428 secondLevelBatchBuffer.dwOffset = params->dwDataBufferOffset;
429 secondLevelBatchBuffer.bSecondLevel = true;
430 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(cmdBuffer, &secondLevelBatchBuffer));
431 }
432
433 return MOS_STATUS_SUCCESS;
434 }
GetMaxMBPS(uint8_t levelIdc)435 static int32_t GetMaxMBPS(uint8_t levelIdc)
436 {
437 int maxMBPS = 11880;
438
439 // See JVT Spec Annex A Table A-1 Level limits for below mapping
440 // maxMBPS is in MB/s
441 switch (levelIdc)
442 {
443 case CODEC_AVC_LEVEL_1:
444 case CODEC_AVC_LEVEL_1b:
445 maxMBPS = 1485;
446 break;
447 case CODEC_AVC_LEVEL_11:
448 maxMBPS = 3000;
449 break;
450 case CODEC_AVC_LEVEL_12:
451 maxMBPS = 6000;
452 break;
453 case CODEC_AVC_LEVEL_13:
454 case CODEC_AVC_LEVEL_2:
455 maxMBPS = 11880;
456 break;
457 case CODEC_AVC_LEVEL_21:
458 maxMBPS = 19800;
459 break;
460 case CODEC_AVC_LEVEL_22:
461 maxMBPS = 20250;
462 break;
463 case CODEC_AVC_LEVEL_3:
464 maxMBPS = 40500;
465 break;
466 case CODEC_AVC_LEVEL_31:
467 maxMBPS = 108000;
468 break;
469 case CODEC_AVC_LEVEL_32:
470 maxMBPS = 216000;
471 break;
472 case CODEC_AVC_LEVEL_4:
473 case CODEC_AVC_LEVEL_41:
474 maxMBPS = 245760;
475 break;
476 case CODEC_AVC_LEVEL_42:
477 maxMBPS = 522240;
478 break;
479 case CODEC_AVC_LEVEL_5:
480 maxMBPS = 589824;
481 break;
482 case CODEC_AVC_LEVEL_51:
483 maxMBPS = 983040;
484 break;
485 case CODEC_AVC_LEVEL_52:
486 maxMBPS = 2073600;
487 break;
488 default:
489 maxMBPS = 0;
490 break;
491 }
492
493 return maxMBPS;
494 }
495
CodecHalAvcEncode_GetProfileLevelMaxFrameSize(PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams,CodechalEncoderState * encoder,uint32_t * pdwProfileLevelMaxFrame)496 MOS_STATUS CodecHalAvcEncode_GetProfileLevelMaxFrameSize(
497 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams,
498 CodechalEncoderState * encoder,
499 uint32_t * pdwProfileLevelMaxFrame)
500 {
501 double bitsPerMB, tmpf;
502 int32_t iMaxMBPS, numMBPerFrame, minCR;
503 uint64_t maxBytePerPic, maxBytePerPicNot0;
504 uint32_t profileLevelMaxFrame, userMaxFrameSize;
505 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
506 double frameRateD = 100;
507
508 CODECHAL_ENCODE_CHK_NULL_RETURN(seqParams);
509 CODECHAL_ENCODE_CHK_NULL_RETURN(encoder);
510 CODECHAL_ENCODE_CHK_NULL_RETURN(pdwProfileLevelMaxFrame);
511
512 minCR = 4;
513
514 if (seqParams->Level >= CODEC_AVC_LEVEL_31 && seqParams->Level <= CODEC_AVC_LEVEL_4)
515 {
516 bitsPerMB = 96;
517 }
518 else
519 {
520 bitsPerMB = 192;
521 minCR = 2;
522 }
523
524 iMaxMBPS = GetMaxMBPS(seqParams->Level);
525 if (!iMaxMBPS)
526 {
527 CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported LevelIDC setting.");
528 return MOS_STATUS_UNKNOWN;
529 }
530
531 numMBPerFrame = encoder->m_picWidthInMb * encoder->m_frameFieldHeightInMb;
532
533 tmpf = (double)numMBPerFrame;
534 if (tmpf < iMaxMBPS / 172.)
535 {
536 tmpf = iMaxMBPS / 172.;
537 }
538
539 maxBytePerPic = (uint64_t)(tmpf * bitsPerMB);
540 maxBytePerPicNot0 =
541 (uint64_t)((((double)iMaxMBPS * frameRateD) /
542 (double)seqParams->FramesPer100Sec) *
543 bitsPerMB);
544 userMaxFrameSize = seqParams->UserMaxFrameSize;
545
546 if ((encoder->m_pictureCodingType != I_TYPE) && (seqParams->UserMaxPBFrameSize > 0))
547 {
548 userMaxFrameSize = seqParams->UserMaxPBFrameSize;
549 }
550
551 if (userMaxFrameSize != 0)
552 {
553 profileLevelMaxFrame = (uint32_t)MOS_MIN(userMaxFrameSize, maxBytePerPic);
554 profileLevelMaxFrame = (uint32_t)MOS_MIN(maxBytePerPicNot0, profileLevelMaxFrame);
555 }
556 else
557 {
558 profileLevelMaxFrame = (uint32_t)MOS_MIN(maxBytePerPicNot0, maxBytePerPic);
559 }
560
561 // minCR related changes are added to match hardware behavior
562 if (encoder->m_vdencEnabled)
563 {
564 *pdwProfileLevelMaxFrame = (uint32_t)MOS_MIN((encoder->m_frameHeight * encoder->m_frameHeight), profileLevelMaxFrame);
565 }
566 else
567 {
568 *pdwProfileLevelMaxFrame = (uint32_t)MOS_MIN(encoder->m_frameHeight * encoder->m_frameWidth * 3 / (2 * minCR), profileLevelMaxFrame);
569 }
570
571 return eStatus;
572 }
573
PutVLCCode(BSBuffer * bsbuffer,uint32_t code)574 static void PutVLCCode(BSBuffer *bsbuffer, uint32_t code)
575 {
576 uint8_t leadingZeroBits, bitcount;
577 uint32_t code1, bits;
578
579 code1 = code + 1;
580 bitcount = 0;
581 while (code1)
582 {
583 code1 >>= 1;
584 bitcount++;
585 }
586
587 if (bitcount == 1)
588 {
589 PutBit(bsbuffer, 1);
590 }
591 else
592 {
593 leadingZeroBits = bitcount - 1;
594 bits = code + 1 - (1 << leadingZeroBits);
595 PutBits(bsbuffer, 1, leadingZeroBits + 1);
596 PutBits(bsbuffer, bits, leadingZeroBits);
597 }
598 }
599
600 //!
601 //! \brief Pack HRD data
602 //!
603 //! \param [in] params
604 //! Pointer to codechal encode Avc pack picture header parameter
605 //!
606 //! \return MOS_STATUS
607 //! Return MOS_STATUS_SUCCESS if call success, else fail reason
608 //!
CodecHal_PackPictureHeader_HrdParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)609 MOS_STATUS CodecHal_PackPictureHeader_HrdParams(
610 PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
611 {
612 PCODECHAL_ENCODE_AVC_VUI_PARAMS vuiParams;
613 PBSBuffer bsbuffer;
614 int schedSelIdx;
615 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
616
617 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
618
619 vuiParams = params->pAvcVuiParams;
620 bsbuffer = params->pBsBuffer;
621
622 PutVLCCode(bsbuffer, vuiParams->cpb_cnt_minus1);
623 PutBits(bsbuffer, vuiParams->bit_rate_scale, 4);
624 PutBits(bsbuffer, vuiParams->cpb_size_scale, 4);
625
626 for (schedSelIdx = 0; schedSelIdx <= vuiParams->cpb_cnt_minus1; schedSelIdx++)
627 {
628 PutVLCCode(bsbuffer, vuiParams->bit_rate_value_minus1[schedSelIdx]);
629 PutVLCCode(bsbuffer, vuiParams->cpb_size_value_minus1[schedSelIdx]);
630 PutBit(bsbuffer, ((vuiParams->cbr_flag >> schedSelIdx) & 1));
631 }
632
633 PutBits(bsbuffer, vuiParams->initial_cpb_removal_delay_length_minus1, 5);
634 PutBits(bsbuffer, vuiParams->cpb_removal_delay_length_minus1, 5);
635 PutBits(bsbuffer, vuiParams->dpb_output_delay_length_minus1, 5);
636 PutBits(bsbuffer, vuiParams->time_offset_length, 5);
637
638 return eStatus;
639 }
640
PackScalingList(BSBuffer * bsbuffer,uint8_t * scalingList,uint8_t sizeOfScalingList)641 static void PackScalingList(BSBuffer *bsbuffer, uint8_t *scalingList, uint8_t sizeOfScalingList)
642 {
643 uint8_t lastScale, nextScale, j;
644 char delta_scale;
645
646 lastScale = nextScale = 8;
647
648 for (j = 0; j < sizeOfScalingList; j++)
649 {
650 if (nextScale != 0)
651 {
652 delta_scale = (char)(scalingList[j] - lastScale);
653
654 PutVLCCode(bsbuffer, SIGNED(delta_scale));
655
656 nextScale = scalingList[j];
657 }
658 lastScale = (nextScale == 0) ? lastScale : nextScale;
659 }
660 }
661
662 //!
663 //! \brief Pack VUI data
664 //!
665 //! \param [in] params
666 //! Pointer to codechal encode Avc pack picture header parameter
667 //!
668 //! \return MOS_STATUS
669 //! Return MOS_STATUS_SUCCESS if call success, else fail reason
670 //!
CodecHal_PackPictureHeader_VuiParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)671 MOS_STATUS CodecHal_PackPictureHeader_VuiParams(
672 PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
673 {
674 PCODECHAL_ENCODE_AVC_VUI_PARAMS vuiParams;
675 PBSBuffer bsbuffer;
676 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
677
678 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
679 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcVuiParams);
680
681 vuiParams = params->pAvcVuiParams;
682 bsbuffer = params->pBsBuffer;
683
684 PutBit(bsbuffer, vuiParams->aspect_ratio_info_present_flag);
685 if (vuiParams->aspect_ratio_info_present_flag)
686 {
687 PutBits(bsbuffer, vuiParams->aspect_ratio_idc, 8);
688 if (vuiParams->aspect_ratio_idc == CODECHAL_ENCODE_AVC_EXTENDED_SAR)
689 {
690 PutBits(bsbuffer, vuiParams->sar_width, 16);
691 PutBits(bsbuffer, vuiParams->sar_height, 16);
692 }
693 }
694
695 PutBit(bsbuffer, vuiParams->overscan_info_present_flag);
696 if (vuiParams->overscan_info_present_flag)
697 {
698 PutBit(bsbuffer, vuiParams->overscan_appropriate_flag);
699 }
700
701 PutBit(bsbuffer, vuiParams->video_signal_type_present_flag);
702 if (vuiParams->video_signal_type_present_flag)
703 {
704 PutBits(bsbuffer, vuiParams->video_format, 3);
705 PutBit(bsbuffer, vuiParams->video_full_range_flag);
706 PutBit(bsbuffer, vuiParams->colour_description_present_flag);
707 if (vuiParams->colour_description_present_flag)
708 {
709 PutBits(bsbuffer, vuiParams->colour_primaries, 8);
710 PutBits(bsbuffer, vuiParams->transfer_characteristics, 8);
711 PutBits(bsbuffer, vuiParams->matrix_coefficients, 8);
712 }
713 }
714
715 PutBit(bsbuffer, vuiParams->chroma_loc_info_present_flag);
716 if (vuiParams->chroma_loc_info_present_flag)
717 {
718 PutVLCCode(bsbuffer, vuiParams->chroma_sample_loc_type_top_field);
719 PutVLCCode(bsbuffer, vuiParams->chroma_sample_loc_type_bottom_field);
720 }
721
722 PutBit(bsbuffer, vuiParams->timing_info_present_flag);
723 if (vuiParams->timing_info_present_flag)
724 {
725 PutBits(bsbuffer, vuiParams->num_units_in_tick, 32);
726 PutBits(bsbuffer, vuiParams->time_scale, 32);
727 PutBit(bsbuffer, vuiParams->fixed_frame_rate_flag);
728 }
729
730 PutBit(bsbuffer, vuiParams->nal_hrd_parameters_present_flag);
731 if (vuiParams->nal_hrd_parameters_present_flag)
732 {
733 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackPictureHeader_HrdParams(params));
734 }
735
736 PutBit(bsbuffer, vuiParams->vcl_hrd_parameters_present_flag);
737 if (vuiParams->vcl_hrd_parameters_present_flag)
738 {
739 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackPictureHeader_HrdParams(params));
740 }
741
742 if (vuiParams->nal_hrd_parameters_present_flag || vuiParams->vcl_hrd_parameters_present_flag)
743 {
744 PutBit(bsbuffer, vuiParams->low_delay_hrd_flag);
745 }
746
747 PutBit(bsbuffer, vuiParams->pic_struct_present_flag);
748 PutBit(bsbuffer, vuiParams->bitstream_restriction_flag);
749 if (vuiParams->bitstream_restriction_flag)
750 {
751 PutBit(bsbuffer, vuiParams->motion_vectors_over_pic_boundaries_flag);
752 PutVLCCode(bsbuffer, vuiParams->max_bytes_per_pic_denom);
753 PutVLCCode(bsbuffer, vuiParams->max_bits_per_mb_denom);
754 PutVLCCode(bsbuffer, vuiParams->log2_max_mv_length_horizontal);
755 PutVLCCode(bsbuffer, vuiParams->log2_max_mv_length_vertical);
756 PutVLCCode(bsbuffer, vuiParams->num_reorder_frames);
757 PutVLCCode(bsbuffer, vuiParams->max_dec_frame_buffering);
758 }
759
760 return eStatus;
761 }
762
SetNalUnit(uint8_t ** bsbuffer,uint8_t refIDC,CODECHAL_ENCODE_AVC_NAL_UNIT_TYPE nalType)763 static void SetNalUnit(uint8_t **bsbuffer, uint8_t refIDC, CODECHAL_ENCODE_AVC_NAL_UNIT_TYPE nalType)
764 {
765 uint8_t *byte = *bsbuffer;
766
767 // for SPS and PPS NAL units zero_byte should exist
768 if (nalType == CODECHAL_ENCODE_AVC_NAL_UT_SPS || nalType == CODECHAL_ENCODE_AVC_NAL_UT_PPS || nalType == CODECHAL_ENCODE_AVC_NAL_UT_AUD)
769 {
770 *byte++ = 0;
771 }
772
773 *byte++ = 0;
774 *byte++ = 0;
775 *byte++ = 1;
776 *byte++ = (uint8_t)((refIDC << 5) | nalType);
777 *byte = 0; // Clear the next byte
778 *bsbuffer = byte;
779 }
780
SetTrailingBits(BSBuffer * bsbuffer)781 static void SetTrailingBits(BSBuffer *bsbuffer)
782 {
783 // Write Stop Bit
784 PutBits(bsbuffer, 1, 1);
785 // Make byte aligned
786 while (bsbuffer->BitOffset)
787 {
788 PutBit(bsbuffer, 0);
789 }
790 }
791
CodecHal_PackSliceHeader_SetInitialRefPicList(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)792 static void CodecHal_PackSliceHeader_SetInitialRefPicList(
793 PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
794 {
795 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
796 PCODEC_REF_LIST * refList;
797 CODEC_PIC_REORDER * picOrder, pTempPicOrder[32];
798 CODEC_PICTURE picture;
799 uint8_t i, j, botField;
800 uint32_t picNum, picOC;
801 uint8_t topIdx, botIdx, listSize;
802 uint32_t defaultPicNumOrder[32];
803 bool reorder;
804
805 CODECHAL_ENCODE_FUNCTION_ENTER;
806
807 CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(params);
808 CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(params->pAvcSliceParams);
809 CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(params->ppRefList);
810
811 slcParams = params->pAvcSliceParams;
812 refList = params->ppRefList;
813 reorder = false;
814 topIdx = 0;
815 botIdx = 0;
816 listSize = 0;
817
818 if (params->wPictureCodingType == P_TYPE)
819 {
820 CodecHal_PackSliceHeader_GetPicNum(params, 0); // list 0
821 picOrder = &slcParams->PicOrder[0][0];
822 // Save the default pic order.
823 for (i = 0; i < (slcParams->num_ref_idx_l0_active_minus1 + 1); i++)
824 {
825 defaultPicNumOrder[i] = picOrder[i].PicNum;
826 }
827 for (i = 1; i < (slcParams->num_ref_idx_l0_active_minus1 + 1); i++)
828 {
829 picNum = picOrder[i].PicNum;
830 picture = picOrder[i].Picture;
831 picOC = picOrder[i].POC;
832 j = i;
833 while ((j > 0) && (picOrder[j - 1].PicNum < picNum))
834 {
835 picOrder[j].PicNum = picOrder[j - 1].PicNum;
836 picOrder[j].Picture = picOrder[j - 1].Picture;
837 picOrder[j].POC = picOrder[j - 1].POC;
838 j--;
839 reorder = true;
840 }
841 picOrder[j].PicNum = picNum;
842 picOrder[j].Picture = picture;
843 picOrder[j].POC = picOC;
844 }
845
846 // Sort picOrder[] based on polarity in field case
847 if (CodecHal_PictureIsTopField(params->CurrPic))
848 {
849 while ((topIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1)) ||
850 (botIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1)))
851 {
852 for (; topIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1); topIdx++)
853 {
854 if (CodecHal_PictureIsTopField(picOrder[topIdx].Picture)) //TOP_FIELD
855 {
856 pTempPicOrder[listSize].PicNum = picOrder[topIdx].PicNum;
857 pTempPicOrder[listSize].Picture = picOrder[topIdx].Picture;
858 pTempPicOrder[listSize].POC = picOrder[topIdx].POC;
859 listSize++;
860 topIdx++;
861 break;
862 }
863 }
864 for (; botIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1); botIdx++)
865 {
866 if (CodecHal_PictureIsBottomField(picOrder[botIdx].Picture)) //BOTTOM_FIELD
867 {
868 pTempPicOrder[listSize].PicNum = picOrder[botIdx].PicNum;
869 pTempPicOrder[listSize].Picture = picOrder[botIdx].Picture;
870 pTempPicOrder[listSize].POC = picOrder[botIdx].POC;
871 listSize++;
872 botIdx++;
873 break;
874 }
875 }
876 }
877 }
878 if (CodecHal_PictureIsBottomField(params->CurrPic))
879 {
880 while ((topIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1)) ||
881 (botIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1)))
882 {
883 for (; botIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1); botIdx++)
884 {
885 if (CodecHal_PictureIsBottomField(picOrder[botIdx].Picture)) //BOTTOM_FIELD
886 {
887 pTempPicOrder[listSize].PicNum = picOrder[botIdx].PicNum;
888 pTempPicOrder[listSize].Picture = picOrder[botIdx].Picture;
889 pTempPicOrder[listSize].POC = picOrder[botIdx].POC;
890 listSize++;
891 botIdx++;
892 break;
893 }
894 }
895 for (; topIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1); topIdx++)
896 {
897 if (CodecHal_PictureIsTopField(picOrder[topIdx].Picture)) //TOP_FIELD
898 {
899 pTempPicOrder[listSize].PicNum = picOrder[topIdx].PicNum;
900 pTempPicOrder[listSize].Picture = picOrder[topIdx].Picture;
901 pTempPicOrder[listSize].POC = picOrder[topIdx].POC;
902 listSize++;
903 topIdx++;
904 break;
905 }
906 }
907 }
908 }
909
910 if (!CodecHal_PictureIsFrame(params->CurrPic))
911 {
912 listSize = MOS_MIN(listSize, 32);
913 // Copy temp array back to picOrder[]
914 for (i = 0; i < listSize; i++)
915 {
916 picOrder[i].PicNum = pTempPicOrder[i].PicNum;
917 picOrder[i].Picture = pTempPicOrder[i].Picture;
918 picOrder[i].POC = pTempPicOrder[i].POC;
919 }
920
921 // Check if picOrder[] has been shuffled compared to the original list
922 reorder = false;
923 for (i = 0; i < (slcParams->num_ref_idx_l0_active_minus1 + 1); i++)
924 {
925 if (defaultPicNumOrder[i] != picOrder[i].PicNum)
926 {
927 reorder = true;
928 break;
929 }
930 }
931 }
932
933 if (reorder)
934 {
935 slcParams->ref_pic_list_reordering_flag_l0 = 1;
936 }
937 else
938 {
939 slcParams->ref_pic_list_reordering_flag_l0 = 0;
940 }
941 for (i = 0; i < (slcParams->num_ref_idx_l0_active_minus1 + 1); i++)
942 {
943 botField = (CodecHal_PictureIsBottomField(picOrder[i].Picture)) ? 1 : 0;
944 refList[picOrder[i].Picture.FrameIdx]->ucInitialIdx[0][botField] = i;
945 }
946 }
947 if (params->wPictureCodingType == B_TYPE)
948 {
949 }
950
951 return;
952 }
953
CodecHal_PackSliceHeader_GetPicNum(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params,uint8_t list)954 static void CodecHal_PackSliceHeader_GetPicNum(
955 PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params,
956 uint8_t list)
957 {
958 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
959 PCODEC_REF_LIST * refList;
960 uint32_t frameNum, frameNumWrap, picNum;
961 uint8_t i, botField, size;
962 CODEC_PICTURE picture;
963
964 CODECHAL_ENCODE_FUNCTION_ENTER;
965
966 CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(params);
967 CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(params->pAvcSliceParams);
968 CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(params->ppRefList);
969
970 slcParams = params->pAvcSliceParams;
971 refList = params->ppRefList;
972
973 size = list ? (slcParams->num_ref_idx_l1_active_minus1 + 1) : (slcParams->num_ref_idx_l0_active_minus1 + 1);
974
975 for (i = 0; i < size; i++)
976 {
977 picture = slcParams->PicOrder[list][i].Picture;
978 botField = (CodecHal_PictureIsBottomField(picture)) ? 1 : 0;
979 refList[picture.FrameIdx]->ucFinalIdx[list][botField] = i;
980 frameNum = refList[picture.FrameIdx]->sFrameNumber;
981 if (frameNum > (uint32_t)refList[params->CurrReconPic.FrameIdx]->sFrameNumber)
982 {
983 frameNumWrap = frameNum - slcParams->MaxFrameNum;
984 }
985 else
986 {
987 frameNumWrap = frameNum;
988 }
989
990 if (CodecHal_PictureIsFrame(params->CurrPic))
991 {
992 picNum = frameNumWrap;
993 }
994 else if ((CodecHal_PictureIsTopField(params->CurrPic) &&
995 CodecHal_PictureIsTopField(picture)) ||
996 (CodecHal_PictureIsBottomField(params->CurrPic) &&
997 CodecHal_PictureIsBottomField(picture)))
998 {
999 // Same polarity
1000 picNum = (frameNumWrap << 1) + 1;
1001 }
1002 else
1003 {
1004 picNum = frameNumWrap << 1;
1005 }
1006 slcParams->PicOrder[list][i].PicNum = picNum;
1007 slcParams->PicOrder[list][i].POC =
1008 refList[picture.FrameIdx]->iFieldOrderCnt[botField];
1009 }
1010
1011 return;
1012 }
1013
CodecHal_PackSliceHeader_SetRefPicListParam(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params,uint8_t list)1014 static MOS_STATUS CodecHal_PackSliceHeader_SetRefPicListParam(
1015 PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params,
1016 uint8_t list)
1017 {
1018 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
1019 PCODEC_REF_LIST * refList;
1020 PCODEC_PIC_REORDER picOrder;
1021 uint8_t i, j, idx, picIdx, numReorder, numActiveMinus1, refPolarity;
1022 uint32_t picNumPred, currPicNum, picNumNoWrap, maxPicNum;
1023 int16_t frameNum;
1024 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1025
1026 CODECHAL_ENCODE_FUNCTION_ENTER;
1027
1028 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1029 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
1030 CODECHAL_ENCODE_CHK_NULL_RETURN(params->ppRefList);
1031
1032 slcParams = params->pAvcSliceParams;
1033 refList = params->ppRefList;
1034 frameNum = refList[params->CurrReconPic.FrameIdx]->sFrameNumber;
1035
1036 currPicNum = (CodecHal_PictureIsFrame(params->CurrPic)) ? frameNum : 2 * frameNum + 1;
1037 picNumPred = currPicNum;
1038 maxPicNum = (CodecHal_PictureIsFrame(params->CurrPic)) ? slcParams->MaxFrameNum : (2 * slcParams->MaxFrameNum);
1039
1040 numActiveMinus1 = list ? slcParams->num_ref_idx_l1_active_minus1 : slcParams->num_ref_idx_l0_active_minus1;
1041
1042 picOrder = &slcParams->PicOrder[list][0];
1043
1044 idx = 0;
1045 picIdx = picOrder[idx].Picture.FrameIdx;
1046 refPolarity = (CodecHal_PictureIsBottomField(picOrder[idx].Picture)) ? 1 : 0;
1047 if (refList[picIdx]->ucFinalIdx[list][refPolarity] ==
1048 refList[picIdx]->ucInitialIdx[list][refPolarity])
1049 {
1050 // Should never happen, something must be wrong in CodecHal_PackSliceHeader_SetInitialRefPicList()
1051 CODECHAL_ENCODE_ASSERT(false);
1052 if (list) // L1
1053 {
1054 slcParams->ref_pic_list_reordering_flag_l1 = 0;
1055 }
1056 else // L0
1057 {
1058 slcParams->ref_pic_list_reordering_flag_l0 = 0;
1059 }
1060 eStatus = MOS_STATUS_UNKNOWN;
1061 return eStatus;
1062 }
1063
1064 numReorder = refList[picIdx]->ucFinalIdx[list][refPolarity] - refList[picIdx]->ucInitialIdx[list][refPolarity];
1065 if (numReorder > numActiveMinus1)
1066 {
1067 numReorder = numActiveMinus1;
1068 }
1069 slcParams->NumReorder = numReorder;
1070 do
1071 {
1072 for (i = (idx + 1); i <= numActiveMinus1; i++)
1073 {
1074 picIdx = picOrder[i].Picture.FrameIdx;
1075 refPolarity = (CodecHal_PictureIsBottomField(picOrder[i].Picture)) ? 1 : 0;
1076 if (refList[picIdx]->ucFinalIdx[list][refPolarity] == idx)
1077 {
1078 break;
1079 }
1080 }
1081 if (i == (numActiveMinus1 + 1))
1082 {
1083 // Should never happen, something must be wrong
1084 CODECHAL_ENCODE_ASSERT(false);
1085 if (list) // L1
1086 {
1087 slcParams->ref_pic_list_reordering_flag_l1 = 0;
1088 }
1089 else // L0
1090 {
1091 slcParams->ref_pic_list_reordering_flag_l0 = 0;
1092 }
1093 eStatus = MOS_STATUS_UNKNOWN;
1094 return eStatus;
1095 }
1096
1097 if (picOrder[i].PicNum > picNumPred)
1098 {
1099 picOrder[idx].ReorderPicNumIDC = 1;
1100 }
1101 else
1102 {
1103 picOrder[idx].ReorderPicNumIDC = 0;
1104 }
1105
1106 if (picOrder[i].PicNum > currPicNum)
1107 {
1108 picNumNoWrap = picOrder[i].PicNum + maxPicNum;
1109 }
1110 else
1111 {
1112 picNumNoWrap = picOrder[i].PicNum;
1113 }
1114
1115 if (picOrder[idx].ReorderPicNumIDC == 0)
1116 {
1117 if (picNumPred > picNumNoWrap)
1118 {
1119 picOrder[idx].DiffPicNumMinus1 = picNumPred - picNumNoWrap - 1;
1120 }
1121 else
1122 {
1123 picOrder[idx].DiffPicNumMinus1 = picNumPred + maxPicNum - picNumNoWrap - 1;
1124 }
1125 }
1126 else
1127 {
1128 if (picNumNoWrap > picNumPred)
1129 {
1130 picOrder[idx].DiffPicNumMinus1 = picNumNoWrap - picNumPred - 1;
1131 }
1132 else
1133 {
1134 picOrder[idx].DiffPicNumMinus1 = picNumNoWrap + maxPicNum - picNumPred - 1;
1135 }
1136 }
1137 picNumPred = picNumNoWrap;
1138
1139 for (j = i; j > idx; j--)
1140 {
1141 picOrder[j].Picture = picOrder[j - 1].Picture;
1142 picOrder[j].PicNum = picOrder[j - 1].PicNum;
1143 picOrder[j].POC = picOrder[j - 1].POC;
1144 }
1145
1146 idx++;
1147 } while (--numReorder);
1148 picOrder[idx].ReorderPicNumIDC = 3;
1149
1150 return eStatus;
1151 }
1152
CodecHal_PackSliceHeader_PredWeightTable(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)1153 static MOS_STATUS CodecHal_PackSliceHeader_PredWeightTable(
1154 PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
1155 {
1156 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
1157 PBSBuffer bsbuffer;
1158 int16_t weight, offset, weight2, offset2;
1159 uint8_t i, weight_flag, chromaIDC;
1160 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1161
1162 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1163 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
1164 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
1165 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1166
1167 bsbuffer = params->pBsBuffer;
1168 slcParams = params->pAvcSliceParams;
1169 chromaIDC = params->pSeqParams->chroma_format_idc;
1170
1171 PutVLCCode(bsbuffer, slcParams->luma_log2_weight_denom);
1172
1173 if (chromaIDC)
1174 {
1175 PutVLCCode(bsbuffer, slcParams->chroma_log2_weight_denom);
1176 }
1177
1178 for (i = 0; i <= slcParams->num_ref_idx_l0_active_minus1; i++)
1179 {
1180 // Luma
1181 weight = slcParams->Weights[0][i][0][0];
1182 offset = slcParams->Weights[0][i][0][1];
1183 weight_flag = (weight != (1 << slcParams->luma_log2_weight_denom)) || (offset != 0);
1184 PutBit(bsbuffer, weight_flag);
1185 if (weight_flag)
1186 {
1187 PutVLCCode(bsbuffer, SIGNED(weight));
1188 PutVLCCode(bsbuffer, SIGNED(offset));
1189 }
1190
1191 // Chroma
1192 if (chromaIDC)
1193 {
1194 weight = slcParams->Weights[0][i][1][0];
1195 offset = slcParams->Weights[0][i][1][1];
1196 weight2 = slcParams->Weights[0][i][2][0];
1197 offset2 = slcParams->Weights[0][i][2][1];
1198 weight_flag = (weight != (1 << slcParams->chroma_log2_weight_denom)) ||
1199 (weight2 != (1 << slcParams->chroma_log2_weight_denom)) ||
1200 (offset != 0) || (offset2 != 0);
1201 PutBit(bsbuffer, weight_flag);
1202 if (weight_flag)
1203 {
1204 PutVLCCode(bsbuffer, SIGNED(weight));
1205 PutVLCCode(bsbuffer, SIGNED(offset));
1206 PutVLCCode(bsbuffer, SIGNED(weight2));
1207 PutVLCCode(bsbuffer, SIGNED(offset2));
1208 }
1209 }
1210 }
1211
1212 if (Slice_Type[slcParams->slice_type] == SLICE_B)
1213 {
1214 for (i = 0; i <= slcParams->num_ref_idx_l1_active_minus1; i++)
1215 {
1216 // Luma
1217 weight = slcParams->Weights[1][i][0][0];
1218 offset = slcParams->Weights[1][i][0][1];
1219 weight_flag = (weight != (1 << slcParams->luma_log2_weight_denom)) || (offset != 0);
1220 PutBit(bsbuffer, weight_flag);
1221 if (weight_flag)
1222 {
1223 PutVLCCode(bsbuffer, SIGNED(weight));
1224 PutVLCCode(bsbuffer, SIGNED(offset));
1225 }
1226
1227 // Chroma
1228 if (chromaIDC)
1229 {
1230 weight = slcParams->Weights[1][i][1][0];
1231 offset = slcParams->Weights[1][i][1][1];
1232 weight2 = slcParams->Weights[1][i][2][0];
1233 offset2 = slcParams->Weights[1][i][2][1];
1234 weight_flag = (weight != (1 << slcParams->chroma_log2_weight_denom)) ||
1235 (weight2 != (1 << slcParams->chroma_log2_weight_denom)) ||
1236 (offset != 0) || (offset2 != 0);
1237 PutBit(bsbuffer, weight_flag);
1238 if (weight_flag)
1239 {
1240 PutVLCCode(bsbuffer, SIGNED(weight));
1241 PutVLCCode(bsbuffer, SIGNED(offset));
1242 PutVLCCode(bsbuffer, SIGNED(weight2));
1243 PutVLCCode(bsbuffer, SIGNED(offset2));
1244 }
1245 }
1246 }
1247 }
1248
1249 return eStatus;
1250 }
1251
CodecHal_PackSliceHeader_MMCO(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)1252 static MOS_STATUS CodecHal_PackSliceHeader_MMCO(
1253 PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
1254 {
1255 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
1256 PBSBuffer bsbuffer;
1257 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1258
1259 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1260 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
1261 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1262
1263 bsbuffer = params->pBsBuffer;
1264 slcParams = params->pAvcSliceParams;
1265
1266 PCODEC_SLICE_MMCO mmco = &slcParams->MMCO[0];
1267 do
1268 {
1269 PutVLCCode(bsbuffer, mmco->MmcoIDC);
1270 if (mmco->MmcoIDC == 1 ||
1271 mmco->MmcoIDC == 3)
1272 PutVLCCode(bsbuffer, mmco->DiffPicNumMinus1);
1273 if (mmco->MmcoIDC == 2)
1274 PutVLCCode(bsbuffer, mmco->LongTermPicNum);
1275 if (mmco->MmcoIDC == 3 ||
1276 mmco->MmcoIDC == 6)
1277 PutVLCCode(bsbuffer, mmco->LongTermFrameIdx);
1278 if (mmco->MmcoIDC == 4)
1279 PutVLCCode(bsbuffer, mmco->MaxLongTermFrameIdxPlus1);
1280 } while ((mmco++)->MmcoIDC != 0);
1281
1282 return eStatus;
1283 }
1284
1285 //!
1286 //! \brief Pack AUD parameters
1287 //!
1288 //! \param [in] params
1289 //! Pointer to codechal encode Avc pack picture header parameter
1290 //!
1291 //! \return MOS_STATUS
1292 //! Return MOS_STATUS_SUCCESS if call success, else fail reason
1293 //!
CodecHal_PackPictureHeader_AUDParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)1294 MOS_STATUS CodecHal_PackPictureHeader_AUDParams(
1295 PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
1296 {
1297 uint32_t picType;
1298 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1299
1300 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1301 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1302
1303 // refer table 7-5 in H.264 spec on primary_pic_type
1304 // Here I,P,B types are included
1305 // According BD Spec 9.5.1.1, 0 - I; 1 - P; 2 - B
1306
1307 picType = (uint32_t)(params->wPictureCodingType) - 1;
1308 PutBits(params->pBsBuffer, picType, 3);
1309
1310 return eStatus;
1311 }
1312
1313 // Refer to H264 picture reordering session
CodecHal_PackSliceHeader_RefPicListReordering(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)1314 static MOS_STATUS CodecHal_PackSliceHeader_RefPicListReordering(
1315 PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
1316 {
1317 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
1318 PBSBuffer bsbuffer;
1319 CODEC_PIC_REORDER * picOrder;
1320 uint8_t sliceType;
1321 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1322
1323 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1324 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
1325
1326 slcParams = params->pAvcSliceParams;
1327 bsbuffer = params->pBsBuffer;
1328 sliceType = Slice_Type[slcParams->slice_type];
1329
1330 if (!params->UserFlags.bDisableAcceleratorRefPicListReordering)
1331 {
1332 // Generate the initial reference list (PicOrder)
1333 CodecHal_PackSliceHeader_SetInitialRefPicList(params);
1334 }
1335
1336 if (sliceType != SLICE_I && sliceType != SLICE_SI)
1337 {
1338 if (slcParams->ref_pic_list_reordering_flag_l0)
1339 {
1340 if (!params->UserFlags.bDisableAcceleratorRefPicListReordering)
1341 {
1342 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackSliceHeader_SetRefPicListParam(params, 0));
1343 }
1344
1345 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l0);
1346
1347 if (slcParams->ref_pic_list_reordering_flag_l0)
1348 {
1349 picOrder = &slcParams->PicOrder[0][0];
1350 do
1351 {
1352 PutVLCCode(bsbuffer, picOrder->ReorderPicNumIDC);
1353 if (picOrder->ReorderPicNumIDC == 0 ||
1354 picOrder->ReorderPicNumIDC == 1)
1355 {
1356 PutVLCCode(bsbuffer, picOrder->DiffPicNumMinus1);
1357 } else
1358 if (picOrder->ReorderPicNumIDC == 2)
1359 {
1360 PutVLCCode(bsbuffer, picOrder->LongTermPicNum);
1361 }
1362 } while ((picOrder++)->ReorderPicNumIDC != 3);
1363 }
1364 }
1365 else
1366 {
1367 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l0);
1368 }
1369 }
1370 if (sliceType == SLICE_B)
1371 {
1372 if (slcParams->ref_pic_list_reordering_flag_l1)
1373 {
1374 if (!params->UserFlags.bDisableAcceleratorRefPicListReordering)
1375 {
1376 CodecHal_PackSliceHeader_SetRefPicListParam(params, 1);
1377 }
1378
1379 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l1);
1380
1381 if (slcParams->ref_pic_list_reordering_flag_l1)
1382 {
1383 picOrder = &slcParams->PicOrder[1][0];
1384 do
1385 {
1386 PutVLCCode(bsbuffer, picOrder->ReorderPicNumIDC);
1387 if (picOrder->ReorderPicNumIDC == 0 ||
1388 picOrder->ReorderPicNumIDC == 1)
1389 {
1390 PutVLCCode(bsbuffer, picOrder->DiffPicNumMinus1);
1391 } else
1392 if (picOrder->ReorderPicNumIDC == 2)
1393 {
1394 PutVLCCode(bsbuffer, picOrder->PicNum);
1395 }
1396 } while ((picOrder++)->ReorderPicNumIDC != 3);
1397 }
1398 }
1399 else
1400 {
1401 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l1);
1402 }
1403 }
1404
1405 return eStatus;
1406 }
1407
1408 //!
1409 //! \brief Pack sequence parameters
1410 //!
1411 //! \param [in] params
1412 //! Pointer to codechal encode Avc pack picture header parameter
1413 //!
1414 //! \return MOS_STATUS
1415 //! Return MOS_STATUS_SUCCESS if call success, else fail reason
1416 //!
CodecHal_PackPictureHeader_SeqParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)1417 MOS_STATUS CodecHal_PackPictureHeader_SeqParams(
1418 PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
1419 {
1420 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams;
1421 BSBuffer * bsbuffer;
1422 uint8_t i;
1423 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1424
1425 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1426 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1427 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
1428
1429 seqParams = params->pSeqParams;
1430 bsbuffer = params->pBsBuffer;
1431
1432 PutBits(bsbuffer, seqParams->Profile, 8);
1433
1434 PutBit(bsbuffer, seqParams->constraint_set0_flag);
1435 PutBit(bsbuffer, seqParams->constraint_set1_flag);
1436 PutBit(bsbuffer, seqParams->constraint_set2_flag);
1437 PutBit(bsbuffer, seqParams->constraint_set3_flag);
1438
1439 PutBits(bsbuffer, 0, 4);
1440 PutBits(bsbuffer, seqParams->Level, 8);
1441 PutVLCCode(bsbuffer, seqParams->seq_parameter_set_id);
1442
1443 if (seqParams->Profile == CODEC_AVC_HIGH_PROFILE ||
1444 seqParams->Profile == CODEC_AVC_HIGH10_PROFILE ||
1445 seqParams->Profile == CODEC_AVC_HIGH422_PROFILE ||
1446 seqParams->Profile == CODEC_AVC_HIGH444_PROFILE ||
1447 seqParams->Profile == CODEC_AVC_CAVLC444_INTRA_PROFILE ||
1448 seqParams->Profile == CODEC_AVC_SCALABLE_BASE_PROFILE ||
1449 seqParams->Profile == CODEC_AVC_SCALABLE_HIGH_PROFILE)
1450 {
1451 PutVLCCode(bsbuffer, seqParams->chroma_format_idc);
1452 if (seqParams->chroma_format_idc == 3)
1453 {
1454 PutBit(bsbuffer, seqParams->separate_colour_plane_flag);
1455 }
1456 PutVLCCode(bsbuffer, seqParams->bit_depth_luma_minus8);
1457 PutVLCCode(bsbuffer, seqParams->bit_depth_chroma_minus8);
1458 PutBit(bsbuffer, seqParams->qpprime_y_zero_transform_bypass_flag);
1459 PutBit(bsbuffer, seqParams->seq_scaling_matrix_present_flag);
1460 if (seqParams->seq_scaling_matrix_present_flag)
1461 {
1462 //Iterate thro' the scaling lists. Refer to ITU-T H.264 std. section 7.3.2.1
1463 for (i = 0; i < 8; i++)
1464 {
1465 // scaling list present flag
1466 PutBit(bsbuffer, seqParams->seq_scaling_list_present_flag[i]);
1467 if (seqParams->seq_scaling_list_present_flag[i])
1468 {
1469 if (i < 6)
1470 {
1471 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList4x4[i][0], 16);
1472 }
1473 else
1474 {
1475 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList8x8[i - 6][0], 64);
1476 }
1477 }
1478 }
1479 }
1480 }
1481
1482 PutVLCCode(bsbuffer, seqParams->log2_max_frame_num_minus4);
1483 PutVLCCode(bsbuffer, seqParams->pic_order_cnt_type);
1484 if (seqParams->pic_order_cnt_type == 0)
1485 {
1486 PutVLCCode(bsbuffer, seqParams->log2_max_pic_order_cnt_lsb_minus4);
1487 }
1488 else if (seqParams->pic_order_cnt_type == 1)
1489 {
1490 PutBit(bsbuffer, seqParams->delta_pic_order_always_zero_flag);
1491 PutVLCCode(bsbuffer, SIGNED(seqParams->offset_for_non_ref_pic));
1492 PutVLCCode(bsbuffer, SIGNED(seqParams->offset_for_top_to_bottom_field));
1493 PutVLCCode(bsbuffer, seqParams->num_ref_frames_in_pic_order_cnt_cycle);
1494 for (i = 0; i < seqParams->num_ref_frames_in_pic_order_cnt_cycle; i++)
1495 {
1496 PutVLCCode(bsbuffer, SIGNED(seqParams->offset_for_ref_frame[i]));
1497 }
1498 }
1499
1500 PutVLCCode(bsbuffer, seqParams->NumRefFrames);
1501 PutBit(bsbuffer, seqParams->gaps_in_frame_num_value_allowed_flag);
1502 PutVLCCode(bsbuffer, seqParams->pic_width_in_mbs_minus1);
1503 PutVLCCode(bsbuffer, seqParams->pic_height_in_map_units_minus1);
1504 PutBit(bsbuffer, seqParams->frame_mbs_only_flag);
1505
1506 if (!seqParams->frame_mbs_only_flag)
1507 {
1508 PutBit(bsbuffer, seqParams->mb_adaptive_frame_field_flag);
1509 }
1510
1511 PutBit(bsbuffer, seqParams->direct_8x8_inference_flag);
1512
1513 if ((!seqParams->frame_cropping_flag) &&
1514 (params->dwFrameHeight != params->dwOriFrameHeight))
1515 {
1516 seqParams->frame_cropping_flag = 1;
1517 seqParams->frame_crop_bottom_offset =
1518 (int16_t)((params->dwFrameHeight - params->dwOriFrameHeight) >>
1519 (2 - seqParams->frame_mbs_only_flag)); // 4:2:0
1520 }
1521
1522 PutBit(bsbuffer, seqParams->frame_cropping_flag);
1523
1524 if (seqParams->frame_cropping_flag)
1525 {
1526 PutVLCCode(bsbuffer, seqParams->frame_crop_left_offset);
1527 PutVLCCode(bsbuffer, seqParams->frame_crop_right_offset);
1528 PutVLCCode(bsbuffer, seqParams->frame_crop_top_offset);
1529 PutVLCCode(bsbuffer, seqParams->frame_crop_bottom_offset);
1530 }
1531
1532 PutBit(bsbuffer, seqParams->vui_parameters_present_flag);
1533
1534 if (seqParams->vui_parameters_present_flag)
1535 {
1536 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackPictureHeader_VuiParams(params));
1537 }
1538
1539 *params->pbNewSeqHeader = 1;
1540
1541 return eStatus;
1542 }
1543
1544 //!
1545 //! \brief Pack picture parameters
1546 //!
1547 //! \param [in] params
1548 //! Pointer to codechal encode Avc pack picture header parameter
1549 //!
1550 //! \return MOS_STATUS
1551 //! Return MOS_STATUS_SUCCESS if call success, else fail reason
1552 //!
CodecHal_PackPictureHeader_PicParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)1553 MOS_STATUS CodecHal_PackPictureHeader_PicParams(
1554 PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
1555 {
1556 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams;
1557 PCODEC_AVC_ENCODE_PIC_PARAMS picParams;
1558 PBSBuffer bsbuffer;
1559 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1560
1561 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1562 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
1563 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pPicParams);
1564 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1565
1566 seqParams = params->pSeqParams;
1567 picParams = params->pPicParams;
1568 bsbuffer = params->pBsBuffer;
1569
1570 PutVLCCode(bsbuffer, picParams->pic_parameter_set_id);
1571 PutVLCCode(bsbuffer, picParams->seq_parameter_set_id);
1572
1573 PutBit(bsbuffer, picParams->entropy_coding_mode_flag);
1574 PutBit(bsbuffer, picParams->pic_order_present_flag);
1575
1576 PutVLCCode(bsbuffer, picParams->num_slice_groups_minus1);
1577
1578 PutVLCCode(bsbuffer, picParams->num_ref_idx_l0_active_minus1);
1579 PutVLCCode(bsbuffer, picParams->num_ref_idx_l1_active_minus1);
1580
1581 PutBit(bsbuffer, picParams->weighted_pred_flag);
1582 PutBits(bsbuffer, picParams->weighted_bipred_idc, 2);
1583
1584 PutVLCCode(bsbuffer, SIGNED(picParams->pic_init_qp_minus26));
1585 PutVLCCode(bsbuffer, SIGNED(picParams->pic_init_qs_minus26));
1586 PutVLCCode(bsbuffer, SIGNED(picParams->chroma_qp_index_offset));
1587
1588 PutBit(bsbuffer, picParams->deblocking_filter_control_present_flag);
1589 PutBit(bsbuffer, picParams->constrained_intra_pred_flag);
1590 PutBit(bsbuffer, picParams->redundant_pic_cnt_present_flag);
1591
1592 // The syntax elements transform_8x8_mode_flag, pic_scaling_matrix_present_flag, and second_chroma_qp_index_offset
1593 // shall not be present for main profile
1594 if (seqParams->Profile == CODEC_AVC_MAIN_PROFILE || seqParams->Profile == CODEC_AVC_BASE_PROFILE)
1595 {
1596 return eStatus;
1597 }
1598
1599 PutBit(bsbuffer, picParams->transform_8x8_mode_flag);
1600 PutBit(bsbuffer, picParams->pic_scaling_matrix_present_flag);
1601 if (picParams->pic_scaling_matrix_present_flag)
1602 {
1603 uint8_t i;
1604
1605 //Iterate thro' the scaling lists. Refer to ITU-T H.264 std. section 7.3.2.2
1606 for (i = 0; i < 6 + 2 * picParams->transform_8x8_mode_flag; i++)
1607 {
1608 //Put scaling list present flag
1609 PutBit(bsbuffer, picParams->pic_scaling_list_present_flag[i]);
1610 if (picParams->pic_scaling_list_present_flag[i])
1611 {
1612 if (i < 6)
1613 {
1614 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList4x4[i][0], 16);
1615 }
1616 else
1617 {
1618 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList8x8[i - 6][0], 64);
1619 }
1620 }
1621 }
1622 }
1623
1624 PutVLCCode(bsbuffer, SIGNED(picParams->second_chroma_qp_index_offset));
1625
1626 *params->pbNewPPSHeader = 1;
1627
1628 return eStatus;
1629 }
1630
CodecHalAvcEncode_PackPictureHeader(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)1631 MOS_STATUS CodecHalAvcEncode_PackPictureHeader(
1632 PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
1633 {
1634 PBSBuffer bsbuffer;
1635 uint32_t indexNALUnit;
1636 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1637
1638 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1639 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1640 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
1641 CODECHAL_ENCODE_CHK_NULL_RETURN(params->ppNALUnitParams);
1642
1643 bsbuffer = params->pBsBuffer;
1644 *(bsbuffer->pBase) = 0; // init first byte to 0
1645 bsbuffer->pCurrent = bsbuffer->pBase;
1646 bsbuffer->SliceOffset = 0;
1647 bsbuffer->BitOffset = 0;
1648 bsbuffer->BitSize = 0;
1649
1650 MOS_ZeroMemory(params->ppNALUnitParams[0], sizeof(CODECHAL_NAL_UNIT_PARAMS) * CODECHAL_ENCODE_AVC_MAX_NAL_TYPE);
1651 indexNALUnit = 0;
1652
1653 // AU_Delimiter
1654 // nal_ref_idc to be 0 for all nal_unit_type equal to 6, 9, 10, 11 or12
1655 params->ppNALUnitParams[indexNALUnit]->uiOffset = 0;
1656 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_AUD;
1657 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = true;
1658 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
1659 SetNalUnit(&bsbuffer->pCurrent, 0, CODECHAL_ENCODE_AVC_NAL_UT_AUD);
1660 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackPictureHeader_AUDParams(params));
1661 SetTrailingBits(bsbuffer);
1662 //NAL unit are byte aligned, bsbuffer->BitOffset should be 0
1663 params->ppNALUnitParams[indexNALUnit]->uiSize =
1664 (uint32_t)(bsbuffer->pCurrent -
1665 bsbuffer->pBase -
1666 params->ppNALUnitParams[indexNALUnit]->uiOffset);
1667 indexNALUnit++;
1668
1669 // If this is a new sequence, write the seq set
1670 if (params->bNewSeq && !params->pSeqParams->bNoAcceleratorSPSInsertion)
1671 {
1672 // Pack SPS
1673 params->ppNALUnitParams[indexNALUnit]->uiOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
1674 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_SPS;
1675 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = true;
1676 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
1677 SetNalUnit(&bsbuffer->pCurrent, 1, CODECHAL_ENCODE_AVC_NAL_UT_SPS);
1678 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackPictureHeader_SeqParams(params));
1679 SetTrailingBits(bsbuffer);
1680 params->ppNALUnitParams[indexNALUnit]->uiSize =
1681 (uint32_t)(bsbuffer->pCurrent -
1682 bsbuffer->pBase -
1683 params->ppNALUnitParams[indexNALUnit]->uiOffset);
1684 indexNALUnit++;
1685 }
1686
1687 // Pack PPS
1688 params->ppNALUnitParams[indexNALUnit]->uiOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
1689 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_PPS;
1690 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = true;
1691 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
1692 SetNalUnit(&bsbuffer->pCurrent, 1, CODECHAL_ENCODE_AVC_NAL_UT_PPS);
1693 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackPictureHeader_PicParams(params));
1694 SetTrailingBits(bsbuffer);
1695 params->ppNALUnitParams[indexNALUnit]->uiSize =
1696 (uint32_t)(bsbuffer->pCurrent -
1697 bsbuffer->pBase -
1698 params->ppNALUnitParams[indexNALUnit]->uiOffset);
1699 indexNALUnit++;
1700
1701 // Pack SEI
1702 if (params->pSeiData->newSEIData)
1703 {
1704 params->ppNALUnitParams[indexNALUnit]->uiOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
1705 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_SEI;
1706 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = false;
1707 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
1708 eStatus = MOS_SecureMemcpy(bsbuffer->pCurrent,
1709 params->pSeiData->dwSEIBufSize,
1710 params->pSeiData->pSEIBuffer,
1711 params->pSeiData->dwSEIBufSize);
1712 if (eStatus != MOS_STATUS_SUCCESS)
1713 {
1714 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
1715 return eStatus;
1716 }
1717 bsbuffer->pCurrent += params->pSeiData->dwSEIDataSize;
1718 params->pSeiData->newSEIData = false;
1719 params->ppNALUnitParams[indexNALUnit]->uiSize =
1720 (uint32_t)(bsbuffer->pCurrent -
1721 bsbuffer->pBase -
1722 params->ppNALUnitParams[indexNALUnit]->uiOffset);
1723 indexNALUnit++;
1724 }
1725
1726 bsbuffer->SliceOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
1727
1728 return eStatus;
1729 }
1730
CodecHalAvcEncode_GetMaxNumSlicesAllowed(CODEC_AVC_PROFILE_IDC profileIdc,CODEC_AVC_LEVEL_IDC levelIdc,uint32_t framesPer100Sec)1731 uint16_t CodecHalAvcEncode_GetMaxNumSlicesAllowed(
1732 CODEC_AVC_PROFILE_IDC profileIdc,
1733 CODEC_AVC_LEVEL_IDC levelIdc,
1734 uint32_t framesPer100Sec)
1735 {
1736 uint16_t maxAllowedNumSlices = 0;
1737
1738 if ((profileIdc == CODEC_AVC_MAIN_PROFILE) ||
1739 (profileIdc == CODEC_AVC_HIGH_PROFILE) ||
1740 (profileIdc == CODEC_AVC_HIGH10_PROFILE) ||
1741 (profileIdc == CODEC_AVC_HIGH422_PROFILE) ||
1742 (profileIdc == CODEC_AVC_HIGH444_PROFILE) ||
1743 (profileIdc == CODEC_AVC_CAVLC444_INTRA_PROFILE))
1744 {
1745 switch (levelIdc)
1746 {
1747 case CODEC_AVC_LEVEL_3:
1748 maxAllowedNumSlices = (uint16_t)(40500.0 * 100 / 22.0 / framesPer100Sec);
1749 break;
1750 case CODEC_AVC_LEVEL_31:
1751 maxAllowedNumSlices = (uint16_t)(108000.0 * 100 / 60.0 / framesPer100Sec);
1752 break;
1753 case CODEC_AVC_LEVEL_32:
1754 maxAllowedNumSlices = (uint16_t)(216000.0 * 100 / 60.0 / framesPer100Sec);
1755 break;
1756 case CODEC_AVC_LEVEL_4:
1757 case CODEC_AVC_LEVEL_41:
1758 maxAllowedNumSlices = (uint16_t)(245760.0 * 100 / 24.0 / framesPer100Sec);
1759 break;
1760 case CODEC_AVC_LEVEL_42:
1761 maxAllowedNumSlices = (uint16_t)(522240.0 * 100 / 24.0 / framesPer100Sec);
1762 break;
1763 case CODEC_AVC_LEVEL_5:
1764 maxAllowedNumSlices = (uint16_t)(589824.0 * 100 / 24.0 / framesPer100Sec);
1765 break;
1766 case CODEC_AVC_LEVEL_51:
1767 maxAllowedNumSlices = (uint16_t)(983040.0 * 100 / 24.0 / framesPer100Sec);
1768 break;
1769 case CODEC_AVC_LEVEL_52:
1770 maxAllowedNumSlices = (uint16_t)(2073600.0 * 100 / 24.0 / framesPer100Sec);
1771 break;
1772 default:
1773 maxAllowedNumSlices = 0;
1774 }
1775 }
1776
1777 return maxAllowedNumSlices;
1778 }
1779
1780 //Pack Slice Header
CodecHalAvcEncode_PackSliceHeader(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)1781 MOS_STATUS CodecHalAvcEncode_PackSliceHeader(
1782 PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
1783 {
1784 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams;
1785 PCODEC_AVC_ENCODE_PIC_PARAMS picParams;
1786 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
1787 PBSBuffer bsbuffer;
1788 uint8_t sliceType;
1789 CODECHAL_ENCODE_AVC_NAL_UNIT_TYPE nalType;
1790 bool ref;
1791 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1792
1793 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1794 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
1795 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pPicParams);
1796 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
1797 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1798
1799 slcParams = params->pAvcSliceParams;
1800 picParams = params->pPicParams;
1801 seqParams = params->pSeqParams;
1802 bsbuffer = params->pBsBuffer;
1803 sliceType = Slice_Type[slcParams->slice_type];
1804 nalType = params->NalUnitType;
1805 ref = params->ppRefList[params->CurrReconPic.FrameIdx]->bUsedAsRef;
1806
1807 // Make slice header uint8_t aligned
1808 while (bsbuffer->BitOffset)
1809 {
1810 PutBit(bsbuffer, 0);
1811 }
1812
1813 // zero byte shall exist when the byte stream NAL unit syntax structure contains the first
1814 // NAL unit of an access unit in decoding order, as specified by subclause 7.4.1.2.3.
1815 // VDEnc Slice header packing handled by PAK does not need the 0 byte inserted
1816 if (params->UserFlags.bDisableAcceleratorHeaderPacking && (!params->bVdencEnabled))
1817 {
1818 *bsbuffer->pCurrent = 0;
1819 bsbuffer->pCurrent++;
1820 }
1821
1822 SetNalUnit(&bsbuffer->pCurrent, (uint8_t)ref, nalType);
1823
1824 // In the VDEnc mode, PAK only gets this command at the beginning of the frame for slice position X=0, Y=0
1825 PutVLCCode(bsbuffer, params->bVdencEnabled ? 0 : slcParams->first_mb_in_slice);
1826 PutVLCCode(bsbuffer, slcParams->slice_type);
1827 PutVLCCode(bsbuffer, slcParams->pic_parameter_set_id);
1828
1829 if (seqParams->separate_colour_plane_flag)
1830 {
1831 PutBits(bsbuffer, slcParams->colour_plane_id, 2);
1832 }
1833
1834 PutBits(bsbuffer, slcParams->frame_num, seqParams->log2_max_frame_num_minus4 + 4);
1835
1836 if (!seqParams->frame_mbs_only_flag)
1837 {
1838 PutBit(bsbuffer, slcParams->field_pic_flag);
1839 if (slcParams->field_pic_flag)
1840 {
1841 PutBit(bsbuffer, slcParams->bottom_field_flag);
1842 }
1843 }
1844
1845 if (nalType == CODECHAL_ENCODE_AVC_NAL_UT_IDR_SLICE)
1846 {
1847 PutVLCCode(bsbuffer, slcParams->idr_pic_id);
1848 }
1849
1850 if (seqParams->pic_order_cnt_type == 0)
1851 {
1852 PutBits(bsbuffer, slcParams->pic_order_cnt_lsb, seqParams->log2_max_pic_order_cnt_lsb_minus4 + 4);
1853 if (picParams->pic_order_present_flag && !slcParams->field_pic_flag)
1854 {
1855 PutVLCCode(bsbuffer, SIGNED(slcParams->delta_pic_order_cnt_bottom));
1856 }
1857 }
1858
1859 if (seqParams->pic_order_cnt_type == 1 && !seqParams->delta_pic_order_always_zero_flag)
1860 {
1861 PutVLCCode(bsbuffer, SIGNED(slcParams->delta_pic_order_cnt[0]));
1862 if (picParams->pic_order_present_flag && !slcParams->field_pic_flag)
1863 {
1864 PutVLCCode(bsbuffer, SIGNED(slcParams->delta_pic_order_cnt[1]));
1865 }
1866 }
1867
1868 if (picParams->redundant_pic_cnt_present_flag)
1869 {
1870 PutVLCCode(bsbuffer, slcParams->redundant_pic_cnt);
1871 }
1872
1873 if (sliceType == SLICE_B)
1874 {
1875 PutBit(bsbuffer, slcParams->direct_spatial_mv_pred_flag);
1876 }
1877
1878 if (sliceType == SLICE_P || sliceType == SLICE_SP || sliceType == SLICE_B)
1879 {
1880 PutBit(bsbuffer, slcParams->num_ref_idx_active_override_flag);
1881 if (slcParams->num_ref_idx_active_override_flag)
1882 {
1883 PutVLCCode(bsbuffer, slcParams->num_ref_idx_l0_active_minus1);
1884 if (sliceType == SLICE_B)
1885 {
1886 PutVLCCode(bsbuffer, slcParams->num_ref_idx_l1_active_minus1);
1887 }
1888 }
1889 }
1890
1891 // ref_pic_list_reordering()
1892 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackSliceHeader_RefPicListReordering(params));
1893
1894 if ((picParams->weighted_pred_flag &&
1895 (sliceType == SLICE_P || sliceType == SLICE_SP)) ||
1896 (picParams->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE &&
1897 sliceType == SLICE_B))
1898 {
1899 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackSliceHeader_PredWeightTable(params));
1900 }
1901
1902 if (ref)
1903 {
1904 // dec_ref_pic_marking()
1905 if (nalType == CODECHAL_ENCODE_AVC_NAL_UT_IDR_SLICE)
1906 {
1907 PutBit(bsbuffer, slcParams->no_output_of_prior_pics_flag);
1908 PutBit(bsbuffer, slcParams->long_term_reference_flag);
1909 }
1910 else
1911 {
1912 PutBit(bsbuffer, slcParams->adaptive_ref_pic_marking_mode_flag);
1913 if (slcParams->adaptive_ref_pic_marking_mode_flag)
1914 {
1915 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackSliceHeader_MMCO(params));
1916 }
1917 }
1918 }
1919
1920 if (picParams->entropy_coding_mode_flag && sliceType != SLICE_I && sliceType != SLICE_SI)
1921 {
1922 PutVLCCode(bsbuffer, slcParams->cabac_init_idc);
1923 }
1924
1925 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_qp_delta));
1926
1927 if (sliceType == SLICE_SP || sliceType == SLICE_SI)
1928 {
1929 if (sliceType == SLICE_SP)
1930 {
1931 PutBit(bsbuffer, slcParams->sp_for_switch_flag);
1932 }
1933 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_qs_delta));
1934 }
1935
1936 if (picParams->deblocking_filter_control_present_flag)
1937 {
1938 PutVLCCode(bsbuffer, slcParams->disable_deblocking_filter_idc);
1939 if (slcParams->disable_deblocking_filter_idc != 1)
1940 {
1941 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_alpha_c0_offset_div2));
1942 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_beta_offset_div2));
1943 }
1944 }
1945
1946 bsbuffer->BitSize =
1947 (uint32_t)((bsbuffer->pCurrent - bsbuffer->SliceOffset - bsbuffer->pBase) * 8 + bsbuffer->BitOffset);
1948 bsbuffer->SliceOffset =
1949 (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase + (bsbuffer->BitOffset != 0));
1950
1951 return eStatus;
1952 }
1953
InitMmcState()1954 MOS_STATUS CodechalEncodeAvcBase::InitMmcState()
1955 {
1956 #ifdef _MMC_SUPPORTED
1957 m_mmcState = MOS_New(CodechalMmcEncodeAvc, m_hwInterface, this);
1958 CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
1959 #endif
1960 return MOS_STATUS_SUCCESS;
1961 }
1962
CodechalEncodeAvcBase(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)1963 CodechalEncodeAvcBase::CodechalEncodeAvcBase(
1964 CodechalHwInterface * hwInterface,
1965 CodechalDebugInterface *debugInterface,
1966 PCODECHAL_STANDARD_INFO standardInfo) : CodechalEncoderState(hwInterface, debugInterface, standardInfo)
1967 {
1968 CODECHAL_ENCODE_FUNCTION_ENTER;
1969
1970 MOS_ZeroMemory(m_avcPicParams, CODEC_AVC_MAX_PPS_NUM * sizeof(PCODEC_AVC_ENCODE_PIC_PARAMS));
1971 MOS_ZeroMemory(m_avcSeqParams, CODEC_AVC_MAX_SPS_NUM * sizeof(PCODEC_AVC_ENCODE_SEQUENCE_PARAMS));
1972 MOS_ZeroMemory(&m_userFlags, sizeof(CODEC_AVC_ENCODE_USER_FLAGS));
1973 MOS_ZeroMemory(m_picIdx, CODEC_AVC_MAX_NUM_REF_FRAME * sizeof(CODEC_PIC_ID));
1974 MOS_ZeroMemory(m_refList, CODEC_AVC_NUM_UNCOMPRESSED_SURFACE * sizeof(PCODEC_REF_LIST));
1975 MOS_ZeroMemory(m_avcFrameStoreID, CODEC_AVC_MAX_NUM_REF_FRAME * sizeof(CODEC_AVC_FRAME_STORE_ID));
1976 MOS_ZeroMemory(&m_nalUnitType, sizeof(CODECHAL_ENCODE_AVC_NAL_UNIT_TYPE));
1977 MOS_ZeroMemory(&m_trellisQuantParams, sizeof(CODECHAL_ENCODE_AVC_TQ_PARAMS));
1978 MOS_ZeroMemory(m_distScaleFactorList0, 2 * CODEC_AVC_MAX_NUM_REF_FRAME * sizeof(uint32_t));
1979 MOS_ZeroMemory(m_batchBufferForVdencImgStat, CODECHAL_ENCODE_RECYCLED_BUFFER_NUM * sizeof(MHW_BATCH_BUFFER));
1980 MOS_ZeroMemory(&m_4xMeMvDataBuffer, sizeof(MOS_SURFACE));
1981 MOS_ZeroMemory(&m_16xMeMvDataBuffer, sizeof(MOS_SURFACE));
1982 MOS_ZeroMemory(&m_32xMeMvDataBuffer, sizeof(MOS_SURFACE));
1983 MOS_ZeroMemory(&m_4xMeDistortionBuffer, sizeof(MOS_SURFACE));
1984 MOS_ZeroMemory(&m_intraRowStoreScratchBuffer, sizeof(MOS_RESOURCE));
1985 MOS_ZeroMemory(m_batchBufferForPakSlices, CODECHAL_ENCODE_RECYCLED_BUFFER_NUM * sizeof(MHW_BATCH_BUFFER));
1986 MOS_ZeroMemory(&m_pakSliceSizeStreamoutBuffer, sizeof(MOS_RESOURCE));
1987
1988 m_hwInterface->GetStateHeapSettings()->dwNumSyncTags = CODECHAL_ENCODE_AVC_NUM_SYNC_TAGS;
1989 m_hwInterface->GetStateHeapSettings()->dwDshSize = CODECHAL_ENCODE_AVC_INIT_DSH_SIZE;
1990 }
1991
~CodechalEncodeAvcBase()1992 CodechalEncodeAvcBase::~CodechalEncodeAvcBase()
1993 {
1994 CODECHAL_ENCODE_FUNCTION_ENTER;
1995
1996 // Release Ref Lists
1997 CodecHalFreeDataList(m_refList, CODEC_AVC_NUM_UNCOMPRESSED_SURFACE);
1998
1999 for (uint8_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
2000 {
2001 ReleaseBatchBufferForPakSlices(i);
2002 }
2003
2004 m_osInterface->pfnFreeResource(m_osInterface, &m_intraRowStoreScratchBuffer);
2005
2006 if (m_encEnabled)
2007 {
2008 if (m_hmeSupported)
2009 {
2010 if (m_hmeKernel)
2011 {
2012 MOS_Delete(m_hmeKernel);
2013 }
2014 else
2015 {
2016 HmeParams hmeParams;
2017
2018 MOS_ZeroMemory(&hmeParams, sizeof(hmeParams));
2019 hmeParams.b4xMeDistortionBufferSupported = true;
2020 hmeParams.ps16xMeMvDataBuffer = &m_16xMeMvDataBuffer;
2021 hmeParams.ps32xMeMvDataBuffer = &m_32xMeMvDataBuffer;
2022 hmeParams.ps4xMeDistortionBuffer = &m_4xMeDistortionBuffer;
2023 hmeParams.ps4xMeMvDataBuffer = &m_4xMeMvDataBuffer;
2024 DestroyMeResources(&hmeParams);
2025 }
2026 }
2027 }
2028
2029 if (m_sliceSizeStreamoutSupported)
2030 {
2031 m_osInterface->pfnFreeResource(m_osInterface, &m_pakSliceSizeStreamoutBuffer);
2032 }
2033 }
2034
Initialize(CodechalSetting * settings)2035 MOS_STATUS CodechalEncodeAvcBase::Initialize(CodechalSetting *settings)
2036 {
2037 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitMmcState());
2038 return CodechalEncoderState::Initialize(settings);
2039 }
2040
UserFeatureKeyReport()2041 MOS_STATUS CodechalEncodeAvcBase::UserFeatureKeyReport()
2042 {
2043 return CodechalEncoderState::UserFeatureKeyReport();
2044 }
2045
Initialize()2046 MOS_STATUS CodechalEncodeAvcBase::Initialize()
2047 {
2048 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2049
2050 m_hwInterface->GetMfxPrimitiveCommandsDataSize(
2051 m_mode,
2052 &m_pakSliceSize,
2053 &m_pakSlicePatchListSize,
2054 false);
2055
2056 // overwrite, must be zero, no patching into second level batch buffer allowed
2057 m_pakSlicePatchListSize = 0;
2058
2059 return eStatus;
2060 }
2061
ScalingListFlat()2062 void CodechalEncodeAvcBase::ScalingListFlat()
2063 {
2064 // 4x4 block
2065 for (uint8_t idx2 = 0; idx2 < 6; idx2++)
2066 {
2067 for (uint8_t idx1 = 0; idx1 < 16; idx1++)
2068 {
2069 m_avcIQWeightScaleLists->WeightScale4x4[idx2][idx1] = 16;
2070 }
2071 }
2072 // 8x8 block
2073 for (uint8_t idx2 = 0; idx2 < 2; idx2++)
2074 {
2075 for (uint8_t idx1 = 0; idx1 < 64; idx1++)
2076 {
2077 m_avcIQWeightScaleLists->WeightScale8x8[idx2][idx1] = 16;
2078 }
2079 }
2080 }
2081
ScalingListFallbackRuleA()2082 void CodechalEncodeAvcBase::ScalingListFallbackRuleA()
2083 {
2084 for (uint8_t idx1 = 0; idx1 < 16; idx1++)
2085 {
2086 for (uint8_t idx2 = 0; idx2 < 3; idx2++)
2087 {
2088 m_avcIQWeightScaleLists->WeightScale4x4[idx2][CODEC_AVC_Qmatrix_scan_4x4[idx1]] =
2089 CODEC_AVC_Default_4x4_Intra[idx1];
2090 }
2091 for (uint8_t idx2 = 3; idx2 < 6; idx2++)
2092 {
2093 m_avcIQWeightScaleLists->WeightScale4x4[idx2][CODEC_AVC_Qmatrix_scan_4x4[idx1]] =
2094 CODEC_AVC_Default_4x4_Inter[idx1];
2095 }
2096 }
2097 // 8x8 block
2098 for (uint8_t idx1 = 0; idx1 < 64; idx1++)
2099 {
2100 m_avcIQWeightScaleLists->WeightScale8x8[0][CODEC_AVC_Qmatrix_scan_8x8[idx1]] =
2101 CODEC_AVC_Default_8x8_Intra[idx1];
2102 m_avcIQWeightScaleLists->WeightScale8x8[1][CODEC_AVC_Qmatrix_scan_8x8[idx1]] =
2103 CODEC_AVC_Default_8x8_Inter[idx1];
2104 }
2105 }
2106
GetDistScaleFactor()2107 void CodechalEncodeAvcBase::GetDistScaleFactor()
2108 {
2109 auto picParams = m_avcPicParam;
2110 auto refList = &(m_refList[0]);
2111 auto picIdx = &(m_picIdx[0]);
2112
2113 bool bottom = CodecHal_PictureIsBottomField(picParams->CurrOriginalPic);
2114 int pocCurr = picParams->CurrFieldOrderCnt[bottom];
2115
2116 MOS_ZeroMemory(m_distScaleFactorList0, sizeof(uint32_t) * CODEC_AVC_MAX_NUM_REF_FRAME * 2);
2117 for (unsigned int index = 0; index <= m_avcSliceParams->num_ref_idx_l0_active_minus1; index++)
2118 {
2119 auto picture = m_avcSliceParams->RefPicList[LIST_0][index];
2120 if (!CodecHal_PictureIsInvalid(picture))
2121 {
2122 auto pictureIdx = picIdx[picture.FrameIdx].ucPicIdx;
2123 int pocPic0 = CodecHal_PictureIsBottomField(picture) ? refList[pictureIdx]->iFieldOrderCnt[1] : refList[pictureIdx]->iFieldOrderCnt[0];
2124 picture = m_avcSliceParams->RefPicList[LIST_1][0];
2125 pictureIdx = picIdx[picture.FrameIdx].ucPicIdx;
2126 int pocPic1 = CodecHal_PictureIsBottomField(picture) ? refList[pictureIdx]->iFieldOrderCnt[1] : refList[pictureIdx]->iFieldOrderCnt[0];
2127 int tb = CodecHal_Clip3(-128, 127, (pocCurr - pocPic0));
2128 int td = CodecHal_Clip3(-128, 127, (pocPic1 - pocPic0));
2129 if (td == 0)
2130 {
2131 td = 1;
2132 }
2133 int tx = (16384 + ABS(td / 2)) / td;
2134
2135 m_distScaleFactorList0[index] = CodecHal_Clip3(-1024, 1023, (tb * tx + 32) >> 6);
2136 }
2137 }
2138 }
2139
AllocateBatchBufferForPakSlices(uint32_t numSlices,uint8_t numPakPasses,uint8_t currRecycledBufIdx)2140 MOS_STATUS CodechalEncodeAvcBase::AllocateBatchBufferForPakSlices(
2141 uint32_t numSlices,
2142 uint8_t numPakPasses,
2143 uint8_t currRecycledBufIdx)
2144 {
2145 CODECHAL_ENCODE_FUNCTION_ENTER;
2146 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2147
2148 MOS_ZeroMemory(
2149 &m_batchBufferForPakSlices[currRecycledBufIdx],
2150 sizeof(MHW_BATCH_BUFFER));
2151
2152 // Get the slice size
2153 uint32_t size = (numPakPasses + 1) * numSlices * m_pakSliceSize;
2154
2155 m_batchBufferForPakSlices[currRecycledBufIdx].bSecondLevel = true;
2156 CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
2157 m_osInterface,
2158 &m_batchBufferForPakSlices[currRecycledBufIdx],
2159 nullptr,
2160 size));
2161
2162 MOS_LOCK_PARAMS lockFlags;
2163 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
2164 lockFlags.WriteOnly = 1;
2165 uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
2166 m_osInterface,
2167 &m_batchBufferForPakSlices[currRecycledBufIdx].OsResource,
2168 &lockFlags);
2169
2170 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
2171
2172 MOS_ZeroMemory(data, size);
2173 m_osInterface->pfnUnlockResource(
2174 m_osInterface,
2175 &m_batchBufferForPakSlices[currRecycledBufIdx].OsResource);
2176
2177 return eStatus;
2178 }
2179
ReleaseBatchBufferForPakSlices(uint8_t currRecycledBufIdx)2180 MOS_STATUS CodechalEncodeAvcBase::ReleaseBatchBufferForPakSlices(
2181 uint8_t currRecycledBufIdx)
2182 {
2183 CODECHAL_ENCODE_FUNCTION_ENTER;
2184 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2185
2186 if (m_batchBufferForPakSlices[currRecycledBufIdx].iSize)
2187 {
2188 Mhw_FreeBb(m_osInterface, &m_batchBufferForPakSlices[currRecycledBufIdx], nullptr);
2189 }
2190
2191 return eStatus;
2192 }
2193
2194 //==<Functions>=======================================================
2195
2196 // Calculate BiWeight for AVC B frame
2197 // for AVC, we cannot use the CodecHal_GetBiWeight function since AVC can use B as reference and
2198 // also supports PAFF
GetBiWeight(uint32_t distScaleFactorRefID0List0,uint16_t weightedBiPredIdc)2199 int32_t CodechalEncodeAvcBase::GetBiWeight(
2200 uint32_t distScaleFactorRefID0List0,
2201 uint16_t weightedBiPredIdc)
2202 {
2203 int32_t biWeight = 32; // default value
2204 if (weightedBiPredIdc != IMPLICIT_WEIGHTED_INTER_PRED_MODE)
2205 {
2206 biWeight = 32;
2207 }
2208 else
2209 {
2210 biWeight = (distScaleFactorRefID0List0 + 2) >> 2;
2211
2212 if (biWeight != 16 && biWeight != 21 &&
2213 biWeight != 32 && biWeight != 43 && biWeight != 48)
2214 {
2215 biWeight = 32; // If # of B-pics between two refs is more than 3. VME does not support it.
2216 }
2217 }
2218
2219 return biWeight;
2220 }
2221
AllocateEncResources()2222 MOS_STATUS CodechalEncodeAvcBase::AllocateEncResources()
2223 {
2224 CODECHAL_ENCODE_FUNCTION_ENTER;
2225 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2226
2227 uint32_t fieldNumMBs = m_picWidthInMb * ((m_picHeightInMb + 1) >> 1);
2228
2229 // to be used in CodecHalEncode_TrackedBuffer_AllocateMbCodeMvDataResources() later
2230 m_mbCodeSize = MOS_ALIGN_CEIL(fieldNumMBs * 16 * 4, CODECHAL_PAGE_SIZE) + fieldNumMBs * 16 * 4;
2231 m_mvDataSize = MOS_ALIGN_CEIL(fieldNumMBs * (32 * 4), CODECHAL_PAGE_SIZE) * 2; // top field MV + bottom field MV (both page aligned)
2232
2233 // allocate 3 + 2 buffers initially
2234 if ((m_codecFunction == CODECHAL_FUNCTION_ENC_PAK) && (!m_vdencEnabled))
2235 {
2236 for (uint8_t j = 0; j < 3; j++)
2237 {
2238 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_trackedBuf->AllocateMbCodeResources(j));
2239 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_trackedBuf->AllocateMvDataResources(j));
2240 }
2241
2242 for (uint8_t k = 0; k < 2; k++)
2243 {
2244 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_trackedBuf->AllocateMbCodeResources(CODEC_NUM_REF_BUFFERS + k));
2245 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_trackedBuf->AllocateMvDataResources(CODEC_NUM_REF_BUFFERS + k));
2246 }
2247 }
2248
2249 if (m_encEnabled && m_hmeSupported)
2250 {
2251 if (m_hmeKernel)
2252 {
2253 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->AllocateResources());
2254 }
2255 else
2256 {
2257 HmeParams hmeParams;
2258 MOS_ZeroMemory(&hmeParams, sizeof(hmeParams));
2259 hmeParams.b4xMeDistortionBufferSupported = true;
2260 hmeParams.ps4xMeDistortionBuffer = &m_4xMeDistortionBuffer;
2261 hmeParams.ps4xMeMvDataBuffer = &m_4xMeMvDataBuffer;
2262 hmeParams.ps16xMeMvDataBuffer = &m_16xMeMvDataBuffer;
2263 hmeParams.ps32xMeMvDataBuffer = &m_32xMeMvDataBuffer;
2264
2265 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResources4xMe(&hmeParams));
2266 if (m_16xMeSupported)
2267 {
2268 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResources16xMe(&hmeParams));
2269 }
2270 if (m_32xMeSupported)
2271 {
2272 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResources32xMe(&hmeParams));
2273 }
2274 }
2275 }
2276
2277 return eStatus;
2278 }
2279
AllocateResources()2280 MOS_STATUS CodechalEncodeAvcBase::AllocateResources()
2281 {
2282 CODECHAL_ENCODE_FUNCTION_ENTER;
2283 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2284
2285 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::AllocateResources());
2286
2287 // initiate allocation parameters and lock flags
2288 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
2289 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
2290 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
2291 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
2292 allocParamsForBufferLinear.Format = Format_Buffer;
2293
2294 AllocateEncResources();
2295
2296 // Allocate Ref Lists
2297 CodecHalAllocateDataList(
2298 m_refList,
2299 CODEC_AVC_NUM_UNCOMPRESSED_SURFACE);
2300
2301 if (m_pakEnabled && m_mfxInterface->IsIntraRowstoreCacheEnabled() == false)
2302 {
2303 // Intra Row Store Scratch buffer
2304 // 1 cacheline per MB
2305 allocParamsForBufferLinear.dwBytes = m_picWidthInMb * CODECHAL_CACHELINE_SIZE;
2306 allocParamsForBufferLinear.pBufName = "Intra Row Store Scratch Buffer";
2307
2308 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
2309 m_osInterface,
2310 &allocParamsForBufferLinear,
2311 &m_intraRowStoreScratchBuffer);
2312
2313 if (eStatus != MOS_STATUS_SUCCESS)
2314 {
2315 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate Intra Row Store Scratch Buffer.");
2316 return eStatus;
2317 }
2318 }
2319
2320 if (m_sliceSizeStreamoutSupported)
2321 {
2322 // PAK Slice Size Streamout Buffer
2323 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(CODECHAL_ENCODE_SLICESIZE_BUF_SIZE, CODECHAL_PAGE_SIZE);
2324 allocParamsForBufferLinear.pBufName = "PAK Slice Size Streamout Buffer";
2325
2326 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
2327 m_osInterface,
2328 &allocParamsForBufferLinear,
2329 &m_pakSliceSizeStreamoutBuffer);
2330
2331 if (eStatus != MOS_STATUS_SUCCESS)
2332 {
2333 CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate Slice Size Streamout Buffer\n", __FUNCTION__);
2334 return eStatus;
2335 }
2336 }
2337
2338 return eStatus;
2339 }
2340
SetSequenceStructs()2341 MOS_STATUS CodechalEncodeAvcBase::SetSequenceStructs()
2342 {
2343 CODECHAL_ENCODE_FUNCTION_ENTER;
2344 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2345
2346 auto seqParams = m_avcSeqParam;
2347
2348 // seq_scaling_matrix_present_flag and chroma_format_idc
2349 // shall not be present for main profile
2350 if (seqParams->Profile == CODEC_AVC_MAIN_PROFILE)
2351 {
2352 seqParams->seq_scaling_matrix_present_flag = 0;
2353 for (uint8_t i = 0; i < 12; i++)
2354 {
2355 seqParams->seq_scaling_list_present_flag[i] = 0;
2356 }
2357 seqParams->chroma_format_idc = 1;
2358 }
2359 // high profile chroma_format_idc in the range of 0 to 1 inclusive
2360 if (seqParams->chroma_format_idc > 1)
2361 {
2362 seqParams->chroma_format_idc = 1;
2363 }
2364
2365 // main & high profile support only 8bpp
2366 seqParams->bit_depth_luma_minus8 = 0;
2367 seqParams->bit_depth_chroma_minus8 = 0;
2368
2369 // setup parameters corresponding to H264 bit stream definition
2370 seqParams->pic_height_in_map_units_minus1 = seqParams->frame_mbs_only_flag ? CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(seqParams->FrameHeight) - 1 : (CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(seqParams->FrameHeight) + 1) / 2 - 1;
2371 seqParams->pic_width_in_mbs_minus1 = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(seqParams->FrameWidth) - 1;
2372 seqParams->constraint_set0_flag = 0;
2373 seqParams->constraint_set1_flag = (seqParams->Profile == CODEC_AVC_BASE_PROFILE) ? 1 : 0;
2374 seqParams->constraint_set2_flag = 0;
2375 seqParams->constraint_set3_flag = 0;
2376 seqParams->gaps_in_frame_num_value_allowed_flag = 0;
2377 seqParams->qpprime_y_zero_transform_bypass_flag = 0;
2378 seqParams->separate_colour_plane_flag = 0;
2379
2380 // setup internal parameters
2381 m_picWidthInMb = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(seqParams->FrameWidth);
2382 m_picHeightInMb = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(seqParams->FrameHeight);
2383 m_frameWidth = m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH;
2384 m_frameHeight = m_picHeightInMb * CODECHAL_MACROBLOCK_HEIGHT;
2385
2386 // HME Scaling WxH
2387 m_downscaledWidthInMb4x =
2388 CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_4x);
2389 m_downscaledHeightInMb4x =
2390 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_4x);
2391 m_downscaledWidth4x =
2392 m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
2393 m_downscaledHeight4x =
2394 m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT;
2395
2396 // SuperHME Scaling WxH
2397 m_downscaledWidthInMb16x =
2398 CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_16x);
2399 m_downscaledHeightInMb16x =
2400 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_16x);
2401 m_downscaledWidth16x =
2402 m_downscaledWidthInMb16x * CODECHAL_MACROBLOCK_WIDTH;
2403 m_downscaledHeight16x =
2404 m_downscaledHeightInMb16x * CODECHAL_MACROBLOCK_HEIGHT;
2405
2406 // UltraHME Scaling WxH
2407 m_downscaledWidthInMb32x =
2408 CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_32x);
2409 m_downscaledHeightInMb32x =
2410 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_32x);
2411 m_downscaledWidth32x =
2412 m_downscaledWidthInMb32x * CODECHAL_MACROBLOCK_WIDTH;
2413 m_downscaledHeight32x =
2414 m_downscaledHeightInMb32x * CODECHAL_MACROBLOCK_HEIGHT;
2415
2416 MotionEstimationDisableCheck();
2417
2418 m_kernelMode =
2419 CodecHal_TargetUsageToMode_AVC[seqParams->TargetUsage & 0x7];
2420 m_targetUsage = seqParams->TargetUsage & 0x7;
2421
2422 if (!seqParams->frame_cropping_flag)
2423 {
2424 // do cropping only when the picture dimension is not MB aligned...
2425 seqParams->frame_crop_left_offset = 0;
2426 seqParams->frame_crop_top_offset = 0;
2427
2428 if (m_frameWidth != seqParams->FrameWidth ||
2429 m_frameHeight != seqParams->FrameHeight)
2430 {
2431 seqParams->frame_cropping_flag = 1;
2432 seqParams->frame_crop_right_offset = (uint16_t)((m_frameWidth - seqParams->FrameWidth) >> 1); // 4:2:0
2433 seqParams->frame_crop_bottom_offset = (uint16_t)((m_frameHeight - seqParams->FrameHeight) >> (2 - seqParams->frame_mbs_only_flag)); // 4:2:0
2434 }
2435 else
2436 {
2437 seqParams->frame_cropping_flag = 0;
2438 seqParams->frame_crop_right_offset = 0;
2439 seqParams->frame_crop_bottom_offset = 0;
2440 }
2441 }
2442
2443 if (m_mfxInterface->IsRowStoreCachingSupported())
2444 {
2445 MHW_VDBOX_ROWSTORE_PARAMS rowstoreParams;
2446 MOS_ZeroMemory(&rowstoreParams, sizeof(rowstoreParams));
2447 rowstoreParams.Mode = CODECHAL_ENCODE_MODE_AVC;
2448 rowstoreParams.dwPicWidth = m_frameWidth;
2449 rowstoreParams.bIsFrame = (seqParams->frame_mbs_only_flag == 1);
2450 m_hwInterface->SetRowstoreCachingOffsets(&rowstoreParams);
2451 }
2452
2453 return eStatus;
2454 }
2455
SetPictureStructs()2456 MOS_STATUS CodechalEncodeAvcBase::SetPictureStructs()
2457 {
2458 CODECHAL_ENCODE_FUNCTION_ENTER;
2459 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2460
2461 auto picParams = m_avcPicParam;
2462 auto seqParams = m_avcSeqParam;
2463 auto avcRefList = &m_refList[0];
2464 auto avcPicIdx = &m_picIdx[0];
2465 auto slcParams = m_avcSliceParams;
2466
2467 if (seqParams->Profile == CODEC_AVC_MAIN_PROFILE || seqParams->Profile == CODEC_AVC_BASE_PROFILE)
2468 {
2469 picParams->transform_8x8_mode_flag = 0;
2470 picParams->pic_scaling_matrix_present_flag = 0;
2471 for (uint8_t i = 0; i < 12; i++)
2472 {
2473 picParams->pic_scaling_list_present_flag[i] = 0;
2474 }
2475 picParams->second_chroma_qp_index_offset = picParams->chroma_qp_index_offset;
2476 }
2477 if (picParams->QpY < 0)
2478 {
2479 picParams->QpY = 25; // Set to default, recommended value used in simulation.
2480 }
2481 else if (picParams->QpY > CODECHAL_ENCODE_AVC_MAX_SLICE_QP)
2482 {
2483 picParams->QpY = CODECHAL_ENCODE_AVC_MAX_SLICE_QP; // Crop to 51 if larger
2484 }
2485 picParams->pic_init_qp_minus26 = picParams->QpY - 26;
2486
2487 if (!seqParams->seq_scaling_matrix_present_flag)
2488 {
2489 if (!picParams->pic_scaling_matrix_present_flag)
2490 ScalingListFlat();
2491 else if (!picParams->pic_scaling_list_present_flag[0])
2492 ScalingListFallbackRuleA();
2493 }
2494 else if (!seqParams->seq_scaling_list_present_flag[0] &&
2495 !picParams->pic_scaling_list_present_flag[0])
2496 { // fall-back rule A
2497 ScalingListFallbackRuleA();
2498 }
2499
2500 picParams->num_slice_groups_minus1 = 0; // do not support flexible MB ordering
2501 picParams->deblocking_filter_control_present_flag = 1; // always set to 1
2502 picParams->redundant_pic_cnt_present_flag = 0;
2503 picParams->pic_init_qs_minus26 = 0; // not used
2504
2505 m_userFlags = picParams->UserFlags;
2506 m_nalUnitType = picParams->bIdrPic ? CODECHAL_ENCODE_AVC_NAL_UT_IDR_SLICE : CODECHAL_ENCODE_AVC_NAL_UT_SLICE;
2507 m_frameNum = picParams->frame_num;
2508 m_lastPicInSeq = picParams->bLastPicInSeq;
2509 m_lastPicInStream = picParams->bLastPicInStream;
2510 // App handles tail insertion for VDEnc dynamic slice in non-cp case
2511 if (m_vdencNoTailInsertion)
2512 {
2513 m_lastPicInSeq = m_lastPicInStream = 0;
2514 }
2515 m_statusReportFeedbackNumber = picParams->StatusReportFeedbackNumber;
2516
2517 auto prevPic = m_currOriginalPic;
2518 auto prevIdx = prevPic.FrameIdx;
2519 auto currPic = picParams->CurrOriginalPic;
2520 auto currIdx = currPic.FrameIdx;
2521 auto prevRefIdx = m_currReconstructedPic.FrameIdx;
2522 auto currRefIdx = picParams->CurrReconstructedPic.FrameIdx;
2523
2524 m_prevReconFrameIdx = m_currReconFrameIdx;
2525 m_currReconFrameIdx = picParams->CurrReconstructedPic.FrameIdx;
2526
2527 avcRefList[currRefIdx]->sRefReconBuffer = m_reconSurface;
2528 avcRefList[currRefIdx]->sRefRawBuffer = m_rawSurface;
2529 avcRefList[currRefIdx]->sFrameNumber = picParams->frame_num;
2530 avcRefList[currRefIdx]->RefPic = currPic;
2531 m_currOriginalPic = currPic;
2532 m_currReconstructedPic = picParams->CurrReconstructedPic;
2533
2534 if (picParams->FieldCodingFlag)
2535 {
2536 m_frameFieldHeight = ((m_frameHeight + 1) >> 1);
2537 m_frameFieldHeightInMb = ((m_picHeightInMb + 1) >> 1);
2538 m_downscaledFrameFieldHeightInMb4x = ((m_downscaledHeightInMb4x + 1) >> 1);
2539 m_downscaledFrameFieldHeightInMb16x = ((m_downscaledHeightInMb16x + 1) >> 1);
2540 m_downscaledFrameFieldHeightInMb32x = ((m_downscaledHeightInMb32x + 1) >> 1);
2541 m_currEncBbSet = MB_ENC_Field_BB;
2542 if (CodecHal_PictureIsFrame(prevPic) || prevIdx != currIdx ||
2543 ((prevPic.PicFlags != currPic.PicFlags) && !(slcParams->pic_order_cnt_lsb & 1)))
2544 {
2545 m_firstField = 1;
2546 // Enable self referencing for both IDR and I pics
2547 m_firstFieldIdrPic = (picParams->CodingType == I_TYPE) ? 1 : 0;
2548 }
2549 else
2550 {
2551 m_firstField = 0;
2552 }
2553 }
2554 else
2555 {
2556 m_frameFieldHeight = m_frameHeight;
2557 m_frameFieldHeightInMb = m_picHeightInMb;
2558 m_downscaledFrameFieldHeightInMb4x = m_downscaledHeightInMb4x;
2559 m_downscaledFrameFieldHeightInMb16x = m_downscaledHeightInMb16x;
2560 m_downscaledFrameFieldHeightInMb32x = m_downscaledHeightInMb32x;
2561 m_firstField = 1;
2562 m_currEncBbSet = MB_ENC_Frame_BB;
2563 }
2564
2565 if (picParams->FieldFrameCodingFlag)
2566 { // Mbaff
2567 seqParams->mb_adaptive_frame_field_flag = 1;
2568 m_mbaffEnabled = 1;
2569 }
2570 else
2571 {
2572 seqParams->mb_adaptive_frame_field_flag = 0;
2573 m_mbaffEnabled = 0;
2574 }
2575
2576 // P/B frames with empty ref lists are internally encoded as I frames,
2577 // while picture header packing remains the original value
2578 m_pictureCodingType = picParams->CodingType;
2579
2580 bool emptyRefFrmList = true;
2581 for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
2582 {
2583 if (picParams->RefFrameList[i].PicFlags != PICTURE_INVALID)
2584 {
2585 emptyRefFrmList = false;
2586 break;
2587 }
2588 }
2589
2590 if (emptyRefFrmList && m_pictureCodingType != I_TYPE)
2591 {
2592 m_pictureCodingType = I_TYPE;
2593 }
2594
2595 avcRefList[currRefIdx]->bUsedAsRef = picParams->RefPicFlag;
2596 avcRefList[currRefIdx]->resBitstreamBuffer = m_resBitstreamBuffer;
2597
2598 for (uint8_t i = 0; i < 16; i++)
2599 {
2600 m_avcFrameStoreID[i].inUse = false;
2601 }
2602
2603 for (uint8_t i = 0; i < 16; i++)
2604 {
2605 avcPicIdx[i].bValid = false;
2606 if (picParams->RefFrameList[i].PicFlags != PICTURE_INVALID)
2607 {
2608 auto index = picParams->RefFrameList[i].FrameIdx;
2609 uint8_t duplicatedIdx = 0;
2610 for (uint8_t ii = 0; ii < i; ii++)
2611 {
2612 if (avcPicIdx[ii].bValid && index == picParams->RefFrameList[ii].FrameIdx)
2613 {
2614 duplicatedIdx = 1;
2615 break;
2616 }
2617 }
2618 if (duplicatedIdx)
2619 {
2620 continue;
2621 }
2622
2623 avcRefList[index]->RefPic.PicFlags =
2624 CodecHal_CombinePictureFlags(avcRefList[index]->RefPic, picParams->RefFrameList[i]);
2625 avcRefList[index]->iFieldOrderCnt[0] = picParams->FieldOrderCntList[i][0];
2626 avcRefList[index]->iFieldOrderCnt[1] = picParams->FieldOrderCntList[i][1];
2627 avcPicIdx[i].bValid = true;
2628 avcPicIdx[i].ucPicIdx = index;
2629 if (prevPic.PicFlags != PICTURE_INVALID)
2630 {
2631 uint8_t ii;
2632 for (ii = 0; ii < avcRefList[prevRefIdx]->ucNumRef; ii++)
2633 {
2634 if (index == avcRefList[prevRefIdx]->RefList[ii].FrameIdx)
2635 {
2636 if (avcRefList[index]->ucFrameId == 0x1f)
2637 {
2638 // Should never happen, something must be wrong
2639 CODECHAL_ENCODE_ASSERT(false);
2640 avcRefList[index]->ucFrameId = 0;
2641 }
2642 m_avcFrameStoreID[avcRefList[index]->ucFrameId].inUse = true;
2643 break;
2644 }
2645 }
2646 if (ii == avcRefList[prevRefIdx]->ucNumRef)
2647 {
2648 avcRefList[index]->ucFrameId = 0x1f;
2649 }
2650 }
2651 }
2652 }
2653
2654 // Save the current RefList
2655 uint8_t ii = 0;
2656 for (uint8_t i = 0; i < 16; i++)
2657 {
2658 if (avcPicIdx[i].bValid)
2659 {
2660 avcRefList[currRefIdx]->RefList[ii] = picParams->RefFrameList[i];
2661 ii++;
2662 }
2663 }
2664 avcRefList[currRefIdx]->ucNumRef = ii;
2665 m_currRefList = avcRefList[currRefIdx];
2666
2667 if (m_codecFunction == CODECHAL_FUNCTION_ENC)
2668 {
2669 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encodeParams.presMbCodeSurface);
2670 m_resMbCodeSurface = *(m_encodeParams.presMbCodeSurface);
2671 }
2672 else if (m_codecFunction == CODECHAL_FUNCTION_ENC_PAK)
2673 {
2674 if (m_encodeParams.presMbCodeSurface == nullptr ||
2675 Mos_ResourceIsNull(m_encodeParams.presMbCodeSurface))
2676 {
2677 // the actual MbCode/MvData surface to be allocated later
2678 m_trackedBuf->SetAllocationFlag(true);
2679 }
2680 else
2681 {
2682 m_resMbCodeSurface = *(m_encodeParams.presMbCodeSurface);
2683 m_resMvDataSurface = *(m_encodeParams.presMbCodeSurface);
2684 }
2685 }
2686 else if (CodecHalIsFeiEncode(m_codecFunction))
2687 {
2688 CodecEncodeAvcFeiPicParams *feiPicParams;
2689
2690 feiPicParams = (CodecEncodeAvcFeiPicParams *)m_encodeParams.pFeiPicParams;
2691 CODECHAL_ENCODE_CHK_NULL_RETURN(feiPicParams);
2692
2693 // Use app provided buffer if available. For FEI_ENC and FEI_PAK, MBCodeMvEnable needs to be set to true
2694 if (feiPicParams->MbCodeMvEnable)
2695 {
2696 m_resMbCodeSurface = feiPicParams->resMBCode;
2697 m_resMvDataSurface = feiPicParams->resMVData;
2698
2699 // Inside the AvcRefList, mbCodesurface and mvdatasurface are stored at frame basis,
2700 // For FEI, mbcode and mv data buffer are provided separately for each field picture and we need to store them separately.
2701 if (CodecHal_PictureIsTopField(picParams->CurrOriginalPic))
2702 {
2703 avcRefList[currRefIdx]->resRefTopFieldMbCodeBuffer = m_resMbCodeSurface;
2704 avcRefList[currRefIdx]->resRefTopFieldMvDataBuffer = m_resMvDataSurface;
2705 }
2706 else if (CodecHal_PictureIsBottomField(picParams->CurrOriginalPic))
2707 {
2708 avcRefList[currRefIdx]->resRefBotFieldMbCodeBuffer = m_resMbCodeSurface;
2709 avcRefList[currRefIdx]->resRefBotFieldMvDataBuffer = m_resMvDataSurface;
2710 }
2711
2712 avcRefList[currRefIdx]->resRefMbCodeBuffer = m_resMbCodeSurface;
2713 avcRefList[currRefIdx]->resRefMvDataBuffer = m_resMvDataSurface;
2714 }
2715 else
2716 {
2717 // the actual MbCode/MvData surface to be allocated later
2718 m_trackedBuf->SetAllocationFlag(true);
2719 }
2720
2721 if (feiPicParams->DistortionEnable)
2722 {
2723 m_resDistortionBuffer = feiPicParams->resDistortion;
2724 }
2725 }
2726
2727 SetFrameStoreIds(currRefIdx);
2728
2729 avcRefList[currRefIdx]->iFieldOrderCnt[0] = picParams->CurrFieldOrderCnt[0];
2730 avcRefList[currRefIdx]->iFieldOrderCnt[1] = picParams->CurrFieldOrderCnt[1];
2731 m_refList[currRefIdx]->ucAvcPictureCodingType = (CodecHal_PictureIsFrame(picParams->CurrOriginalPic)) ? CODEC_AVC_PIC_CODING_TYPE_FRAME : ((picParams->CurrFieldOrderCnt[0] < picParams->CurrFieldOrderCnt[1]) ? CODEC_AVC_PIC_CODING_TYPE_TFF_FIELD : CODEC_AVC_PIC_CODING_TYPE_BFF_FIELD);
2732
2733 m_hmeEnabled = m_hmeSupported && m_pictureCodingType != I_TYPE;
2734 m_16xMeEnabled = m_16xMeSupported && m_pictureCodingType != I_TYPE;
2735 m_32xMeEnabled = m_32xMeSupported && m_pictureCodingType != I_TYPE;
2736
2737 if (m_pictureCodingType == B_TYPE)
2738 {
2739 GetDistScaleFactor();
2740 m_biWeight = GetBiWeight(
2741 m_distScaleFactorList0[0],
2742 m_avcPicParam->weighted_bipred_idc);
2743 }
2744
2745 m_verticalLineStride = CODECHAL_VLINESTRIDE_FRAME;
2746 m_verticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_TOP_FIELD;
2747 m_mbcodeBottomFieldOffset = 0;
2748 m_mvBottomFieldOffset = 0;
2749 m_meDistortionBottomFieldOffset = 0;
2750 m_meMvBottomFieldOffset = 0;
2751 m_meMv16xBottomFieldOffset = 0;
2752 m_meMv32xBottomFieldOffset = 0;
2753 m_sliceMapBottomFieldOffset = 0;
2754 if (m_hmeKernel)
2755 {
2756 m_hmeKernel->Set4xMeMvBottomFieldOffset(0);
2757 m_hmeKernel->Set16xMeMvBottomFieldOffset(0);
2758 m_hmeKernel->Set32xMeMvBottomFieldOffset(0);
2759 m_hmeKernel->SetDistortionBottomFieldOffset(0);
2760 }
2761
2762 if (CodecHal_PictureIsField(m_currOriginalPic))
2763 {
2764 m_verticalLineStride = CODECHAL_VLINESTRIDE_FIELD;
2765 m_frameHeight = m_frameFieldHeightInMb * 2 * 16;
2766 m_picHeightInMb = (uint16_t)(m_frameHeight / 16);
2767 if (CodecHal_PictureIsBottomField(m_currOriginalPic))
2768 {
2769 m_sliceMapBottomFieldOffset = MOS_ALIGN_CEIL((m_picWidthInMb + 1) * sizeof(uint32_t), 64) * m_frameFieldHeightInMb;
2770 m_verticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_BOT_FIELD;
2771
2772 if (CodecHalIsFeiEncode(m_codecFunction))
2773 {
2774 CodecEncodeAvcFeiPicParams *feiPicParams;
2775
2776 feiPicParams = (CodecEncodeAvcFeiPicParams *)m_encodeParams.pFeiPicParams;
2777 CODECHAL_ENCODE_CHK_NULL_RETURN(feiPicParams);
2778
2779 // for user provided MbCode and Mv data buffer, set BottomFieldOffset to 0
2780 if (feiPicParams->MbCodeMvEnable)
2781 {
2782 m_mbcodeBottomFieldOffset = 0;
2783 m_mvBottomFieldOffset = 0;
2784 }
2785 else
2786 {
2787 m_mbcodeBottomFieldOffset = m_frameFieldHeightInMb * m_picWidthInMb * 64;
2788 m_mvBottomFieldOffset =
2789 MOS_ALIGN_CEIL(m_frameFieldHeightInMb * m_picWidthInMb * (32 * 4), CODECHAL_PAGE_SIZE);
2790 }
2791 }
2792 else
2793 {
2794 m_mbcodeBottomFieldOffset = m_frameFieldHeightInMb * m_picWidthInMb * 64;
2795 m_mvBottomFieldOffset =
2796 MOS_ALIGN_CEIL(m_frameFieldHeightInMb * m_picWidthInMb * (32 * 4), CODECHAL_PAGE_SIZE);
2797 }
2798
2799 m_meDistortionBottomFieldOffset =
2800 MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64) *
2801 MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4 * 10), 8);
2802 m_meMvBottomFieldOffset =
2803 MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64) *
2804 (m_downscaledFrameFieldHeightInMb4x * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
2805 if (m_16xMeEnabled)
2806 {
2807 m_meMv16xBottomFieldOffset =
2808 MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64) *
2809 (m_downscaledFrameFieldHeightInMb16x * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
2810 if (m_32xMeEnabled)
2811 {
2812 m_meMv32xBottomFieldOffset =
2813 MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64) *
2814 (m_downscaledFrameFieldHeightInMb32x * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
2815 }
2816 }
2817
2818 if (m_hmeKernel)
2819 {
2820 m_hmeKernel->SetDistortionBottomFieldOffset(
2821 MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64) *
2822 MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4 * 10), 8));
2823 m_hmeKernel->Set4xMeMvBottomFieldOffset(
2824 MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64) *
2825 (m_downscaledFrameFieldHeightInMb4x * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER));
2826 if (m_hmeKernel->Is16xMeEnabled())
2827 {
2828 m_hmeKernel->Set16xMeMvBottomFieldOffset(
2829 MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64) *
2830 (m_downscaledFrameFieldHeightInMb16x * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER));
2831 if (m_hmeKernel->Is32xMeEnabled())
2832 {
2833 m_hmeKernel->Set32xMeMvBottomFieldOffset(
2834 MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64) *
2835 (m_downscaledFrameFieldHeightInMb32x * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER));
2836 }
2837 }
2838 }
2839 }
2840 }
2841
2842 return eStatus;
2843 }
2844
EncodeMeKernel(EncodeBrcBuffers * brcBuffers,HmeLevel hmeLevel)2845 MOS_STATUS CodechalEncodeAvcBase::EncodeMeKernel(
2846 EncodeBrcBuffers *brcBuffers,
2847 HmeLevel hmeLevel)
2848 {
2849 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2850
2851 CODECHAL_ENCODE_FUNCTION_ENTER;
2852
2853 PerfTagSetting perfTag;
2854 perfTag.Value = 0;
2855 perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
2856 perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_ME_KERNEL;
2857 perfTag.PictureCodingType = m_pictureCodingType;
2858 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
2859 // Each ME kernel buffer counts as a separate perf task
2860 m_osInterface->pfnResetPerfBufferID(m_osInterface);
2861
2862 CODECHAL_MEDIA_STATE_TYPE encFunctionType = (hmeLevel == HME_LEVEL_32x) ? CODECHAL_MEDIA_STATE_32X_ME : (hmeLevel == HME_LEVEL_16x) ? CODECHAL_MEDIA_STATE_16X_ME : CODECHAL_MEDIA_STATE_4X_ME;
2863
2864 bool vdencMeInUse = false;
2865 if (m_vdencEnabled && (encFunctionType == CODECHAL_MEDIA_STATE_4X_ME))
2866 {
2867 vdencMeInUse = true;
2868 encFunctionType = CODECHAL_MEDIA_STATE_ME_VDENC_STREAMIN;
2869 }
2870
2871 uint32_t krnStateIdx = vdencMeInUse ? CODECHAL_ENCODE_ME_IDX_VDENC : ((m_pictureCodingType == P_TYPE) ? CODECHAL_ENCODE_ME_IDX_P : CODECHAL_ENCODE_ME_IDX_B);
2872 auto kernelState = &m_meKernelStates[krnStateIdx];
2873
2874 // If Single Task Phase is not enabled, use BT count for the kernel state.
2875 if (m_firstTaskInPhase || !m_singleTaskPhaseSupported)
2876 {
2877 uint32_t maxBtCount = m_singleTaskPhaseSupported ? m_maxBtCount : kernelState->KernelParams.iBTCount;
2878 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
2879 m_stateHeapInterface,
2880 maxBtCount));
2881 m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount);
2882 CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
2883 }
2884
2885 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
2886 m_stateHeapInterface,
2887 kernelState,
2888 false,
2889 0,
2890 false,
2891 m_storeData));
2892
2893 MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
2894 MOS_ZeroMemory(&idParams, sizeof(idParams));
2895 idParams.pKernelState = kernelState;
2896 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
2897 m_stateHeapInterface,
2898 1,
2899 &idParams));
2900
2901 // Setup AVC Curbe
2902 MeCurbeParams meParams;
2903 MOS_ZeroMemory(&meParams, sizeof(meParams));
2904 meParams.hmeLvl = hmeLevel;
2905 meParams.pKernelState = kernelState;
2906
2907 if (!m_useCommonKernel)
2908 {
2909 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeMe(&meParams));
2910 }
2911
2912 CODECHAL_DEBUG_TOOL(
2913 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2914 encFunctionType,
2915 MHW_DSH_TYPE,
2916 kernelState));
2917 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
2918 encFunctionType,
2919 kernelState));
2920 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2921 encFunctionType,
2922 MHW_ISH_TYPE,
2923 kernelState));)
2924
2925 MOS_COMMAND_BUFFER cmdBuffer;
2926 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
2927
2928 SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
2929 sendKernelCmdsParams.EncFunctionType = encFunctionType;
2930 sendKernelCmdsParams.pKernelState = kernelState;
2931
2932 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
2933
2934 // Add binding table
2935 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
2936 m_stateHeapInterface,
2937 kernelState));
2938
2939 //Add surface states
2940 MeSurfaceParams meSurfaceParams;
2941 MOS_ZeroMemory(&meSurfaceParams, sizeof(meSurfaceParams));
2942 meSurfaceParams.dwNumRefIdxL0ActiveMinus1 = m_avcSliceParams->num_ref_idx_l0_active_minus1;
2943 meSurfaceParams.dwNumRefIdxL1ActiveMinus1 = m_avcSliceParams->num_ref_idx_l1_active_minus1;
2944 meSurfaceParams.pL0RefFrameList = &(m_avcSliceParams->RefPicList[LIST_0][0]);
2945 meSurfaceParams.pL1RefFrameList = &(m_avcSliceParams->RefPicList[LIST_1][0]);
2946 meSurfaceParams.ppRefList = &m_refList[0];
2947 meSurfaceParams.pPicIdx = &m_picIdx[0];
2948 meSurfaceParams.pCurrOriginalPic = &m_currOriginalPic;
2949 meSurfaceParams.ps4xMeMvDataBuffer = &m_4xMeMvDataBuffer;
2950 meSurfaceParams.dw4xMeMvBottomFieldOffset = (uint32_t)m_meMvBottomFieldOffset;
2951 meSurfaceParams.ps16xMeMvDataBuffer = &m_16xMeMvDataBuffer;
2952 meSurfaceParams.dw16xMeMvBottomFieldOffset = (uint32_t)m_meMv16xBottomFieldOffset;
2953 meSurfaceParams.ps32xMeMvDataBuffer = &m_32xMeMvDataBuffer;
2954 meSurfaceParams.dw32xMeMvBottomFieldOffset = (uint32_t)m_meMv32xBottomFieldOffset;
2955 meSurfaceParams.dw4xScaledBottomFieldOffset = (uint32_t)m_scaledBottomFieldOffset;
2956 meSurfaceParams.dw16xScaledBottomFieldOffset = (uint32_t)m_scaled16xBottomFieldOffset;
2957 meSurfaceParams.dw32xScaledBottomFieldOffset = (uint32_t)m_scaled32xBottomFieldOffset;
2958 meSurfaceParams.psMeDistortionBuffer = &m_4xMeDistortionBuffer;
2959 meSurfaceParams.dwMeDistortionBottomFieldOffset = (uint32_t)m_meDistortionBottomFieldOffset;
2960 if (nullptr != brcBuffers)
2961 {
2962 meSurfaceParams.psMeBrcDistortionBuffer = &brcBuffers->sMeBrcDistortionBuffer;
2963 meSurfaceParams.dwMeBrcDistortionBottomFieldOffset = brcBuffers->dwMeBrcDistortionBottomFieldOffset;
2964 }
2965 meSurfaceParams.psMeVdencStreamInBuffer = &m_resVdencStreamInBuffer[m_currRecycledBufIdx];
2966 meSurfaceParams.dwDownscaledWidthInMb = (hmeLevel == HME_LEVEL_32x) ? m_downscaledWidthInMb32x : (hmeLevel == HME_LEVEL_16x) ? m_downscaledWidthInMb16x : m_downscaledWidthInMb4x;
2967 meSurfaceParams.dwDownscaledHeightInMb = (hmeLevel == HME_LEVEL_32x) ? m_downscaledFrameFieldHeightInMb32x : (hmeLevel == HME_LEVEL_16x) ? m_downscaledFrameFieldHeightInMb16x : m_downscaledFrameFieldHeightInMb4x;
2968 meSurfaceParams.dwVerticalLineStride = m_verticalLineStride;
2969 meSurfaceParams.dwVerticalLineStrideOffset = m_verticalLineStrideOffset;
2970 meSurfaceParams.b32xMeInUse = (hmeLevel == HME_LEVEL_32x) ? true : false;
2971 meSurfaceParams.b16xMeInUse = (hmeLevel == HME_LEVEL_16x) ? true : false;
2972 meSurfaceParams.b32xMeEnabled = m_32xMeEnabled;
2973 meSurfaceParams.b16xMeEnabled = m_16xMeEnabled;
2974 meSurfaceParams.bVdencStreamInEnabled = m_vdencEnabled && (m_16xMeSupported || m_staticFrameDetectionInUse);
2975 meSurfaceParams.pMeBindingTable = &m_meBindingTable;
2976 meSurfaceParams.pKernelState = kernelState;
2977 meSurfaceParams.dwVDEncStreamInSurfaceSize = MOS_BYTES_TO_DWORDS(m_picHeightInMb * m_picWidthInMb * 64);
2978
2979 if (!m_useCommonKernel)
2980 {
2981 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendMeSurfaces(&cmdBuffer, &meSurfaceParams));
2982 }
2983
2984 // Dump SSH for ME kernel
2985 CODECHAL_DEBUG_TOOL(
2986 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2987 encFunctionType,
2988 MHW_SSH_TYPE,
2989 kernelState)));
2990
2991 /* zero out the mv data memory and me distortion buffer for the driver ULT
2992 kernel only writes out this data used for current frame, in some cases the the data used for
2993 previous frames would be left in the buffer (for example, the L1 mv for B frame would still show
2994 in the P frame mv data buffer */
2995
2996 /* Zeroing out the buffers has perf impact, so zero it out only when dumps are actually enabled */
2997
2998 CODECHAL_DEBUG_TOOL(
2999 CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface);
3000 uint8_t * data;
3001 uint32_t size;
3002 bool driverMeDumpEnabled;
3003
3004 driverMeDumpEnabled = m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel4xMe) ||
3005 m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel16xMe) ||
3006 m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel32xMe);
3007
3008 if (driverMeDumpEnabled) {
3009 MOS_LOCK_PARAMS lockFlags;
3010 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
3011 lockFlags.WriteOnly = 1;
3012
3013 switch (hmeLevel)
3014 {
3015 case HME_LEVEL_32x:
3016 data = (uint8_t *)m_osInterface->pfnLockResource(
3017 m_osInterface,
3018 &m_32xMeMvDataBuffer.OsResource,
3019 &lockFlags);
3020 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3021 size = MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64) *
3022 (m_downscaledHeightInMb32x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
3023 MOS_ZeroMemory(data, size);
3024 m_osInterface->pfnUnlockResource(
3025 m_osInterface,
3026 &m_32xMeMvDataBuffer.OsResource);
3027 break;
3028 case HME_LEVEL_16x:
3029 data = (uint8_t *)m_osInterface->pfnLockResource(
3030 m_osInterface,
3031 &m_16xMeMvDataBuffer.OsResource,
3032 &lockFlags);
3033 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3034 size = MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64) *
3035 (m_downscaledHeightInMb16x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
3036 MOS_ZeroMemory(data, size);
3037 m_osInterface->pfnUnlockResource(
3038 m_osInterface,
3039 &m_16xMeMvDataBuffer.OsResource);
3040 break;
3041 case HME_LEVEL_4x:
3042 if (!m_vdencEnabled)
3043 {
3044 data = (uint8_t *)m_osInterface->pfnLockResource(
3045 m_osInterface,
3046 &m_4xMeMvDataBuffer.OsResource,
3047 &lockFlags);
3048 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3049 size = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64) *
3050 (m_downscaledHeightInMb4x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
3051 MOS_ZeroMemory(data, size);
3052 m_osInterface->pfnUnlockResource(
3053 m_osInterface,
3054 &m_4xMeMvDataBuffer.OsResource);
3055 }
3056 break;
3057 default:
3058 return MOS_STATUS_INVALID_PARAMETER;
3059 }
3060
3061 // zeroing out ME dist buffer
3062 if (m_4xMeDistortionBufferSupported)
3063 {
3064 data = (uint8_t *)m_osInterface->pfnLockResource(
3065 m_osInterface, &m_4xMeDistortionBuffer.OsResource, &lockFlags);
3066 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3067 size = m_4xMeDistortionBuffer.dwHeight * m_4xMeDistortionBuffer.dwPitch;
3068 MOS_ZeroMemory(data, size);
3069 m_osInterface->pfnUnlockResource(
3070 m_osInterface,
3071 &m_4xMeDistortionBuffer.OsResource);
3072 }
3073 });
3074
3075 uint32_t scalingFactor = (hmeLevel == HME_LEVEL_32x) ? SCALE_FACTOR_32x : (hmeLevel == HME_LEVEL_16x) ? SCALE_FACTOR_16x : SCALE_FACTOR_4x;
3076
3077 uint32_t resolutionX = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / scalingFactor);
3078 uint32_t resolutionY = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scalingFactor);
3079
3080 CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
3081 MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
3082 walkerCodecParams.WalkerMode = m_walkerMode;
3083 walkerCodecParams.dwResolutionX = resolutionX;
3084 walkerCodecParams.dwResolutionY = resolutionY;
3085 walkerCodecParams.bNoDependency = true;
3086 walkerCodecParams.bMbaff = m_mbaffEnabled;
3087 walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported;
3088 walkerCodecParams.ucGroupId = m_groupId;
3089
3090 MHW_WALKER_PARAMS walkerParams;
3091 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
3092 m_hwInterface,
3093 &walkerParams,
3094 &walkerCodecParams));
3095
3096 HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
3097 HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters());
3098
3099 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd(
3100 &cmdBuffer,
3101 &walkerParams));
3102
3103 CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));
3104
3105 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks(
3106 m_stateHeapInterface,
3107 kernelState));
3108 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
3109 {
3110 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
3111 m_stateHeapInterface));
3112 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
3113 }
3114
3115 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
3116 &cmdBuffer,
3117 encFunctionType,
3118 nullptr)));
3119
3120 m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase);
3121
3122 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
3123
3124 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
3125 {
3126 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
3127 m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
3128 m_lastTaskInPhase = false;
3129 }
3130
3131 return eStatus;
3132 }
3133
SetSliceStructs()3134 MOS_STATUS CodechalEncodeAvcBase::SetSliceStructs()
3135 {
3136 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3137 CODECHAL_ENCODE_FUNCTION_ENTER;
3138
3139 auto slcParams = m_avcSliceParams;
3140 auto seqParams = m_avcSeqParam;
3141 auto picParams = m_avcPicParam;
3142
3143 // Save the QP value
3144 if (CodecHal_PictureIsBottomField(picParams->CurrOriginalPic))
3145 {
3146 m_refList[m_currReconstructedPic.FrameIdx]->ucQPValue[1] =
3147 picParams->pic_init_qp_minus26 + 26 + slcParams->slice_qp_delta;
3148 }
3149 else
3150 {
3151 m_refList[m_currReconstructedPic.FrameIdx]->ucQPValue[0] =
3152 picParams->pic_init_qp_minus26 + 26 + slcParams->slice_qp_delta;
3153 }
3154
3155 uint32_t numMbsInPrevSlice = slcParams->NumMbsForSlice; // Initiailize to num mbs in first slice
3156 uint32_t numMbsForFirstSlice;
3157 uint32_t numMbs = 0;
3158
3159 for (uint32_t sliceCount = 0; sliceCount < m_numSlices; sliceCount++)
3160 {
3161 if (m_sliceStructCaps != CODECHAL_SLICE_STRUCT_ARBITRARYMBSLICE)
3162 {
3163 if (sliceCount == 0)
3164 {
3165 numMbsForFirstSlice = slcParams->NumMbsForSlice;
3166 // In current kernel, the same MB number in the slice must be number of MB rows.
3167 if (numMbsForFirstSlice % m_picWidthInMb)
3168 {
3169 eStatus = MOS_STATUS_INVALID_PARAMETER;
3170 return eStatus;
3171 }
3172 m_sliceHeight = numMbsForFirstSlice / m_picWidthInMb;
3173 // Slice height should be in power of 2
3174 if (m_sliceStructCaps == CODECHAL_SLICE_STRUCT_POW2ROWS && (m_sliceHeight & (m_sliceHeight - 1)))
3175 {
3176 // app can only pass orig numMBs in picture for single slice, set slice height to the nearest pow2
3177 if (m_numSlices == 1)
3178 {
3179 uint16_t sliceHeightPow2 = 1;
3180 while (sliceHeightPow2 < m_sliceHeight)
3181 {
3182 sliceHeightPow2 <<= 1;
3183 }
3184 m_sliceHeight = sliceHeightPow2;
3185 }
3186 else
3187 {
3188 eStatus = MOS_STATUS_INVALID_PARAMETER;
3189 return eStatus;
3190 }
3191 }
3192 }
3193 // VME: In current kernel, all slices should have the same MBs except the last one, the last one should have no more MBs than the previous
3194 else if (!m_vdencEnabled || (m_vdencEnabled && m_sliceStructCaps == CODECHAL_SLICE_STRUCT_ROWSLICE))
3195 {
3196 if ((sliceCount < m_numSlices - 1 && numMbsForFirstSlice != slcParams->NumMbsForSlice) ||
3197 (sliceCount == m_numSlices - 1 && numMbsForFirstSlice < slcParams->NumMbsForSlice))
3198 {
3199 eStatus = MOS_STATUS_INVALID_PARAMETER;
3200 return eStatus;
3201 }
3202 }
3203
3204 // Gaps between slices are not allowed
3205 if (slcParams->first_mb_in_slice != numMbs)
3206 {
3207 eStatus = MOS_STATUS_INVALID_PARAMETER;
3208 return eStatus;
3209 }
3210 numMbs += slcParams->NumMbsForSlice;
3211 }
3212 else // SLICE_STRUCT_ARBITRARYMBSLICE
3213 {
3214 uint8_t ppsIdx = m_avcSliceParams->pic_parameter_set_id;
3215 uint8_t refPicListIdx = m_avcSliceParams[ppsIdx].RefPicList[0][0].FrameIdx;
3216 uint8_t refFrameListIdx = m_avcPicParam[ppsIdx].RefFrameList[refPicListIdx].FrameIdx;
3217
3218 bool dirtyRoiEnabled = (m_pictureCodingType == P_TYPE && m_avcPicParams[ppsIdx]->NumDirtyROI > 0 && m_prevReconFrameIdx == refFrameListIdx);
3219
3220 if (m_mfeEnabled && m_numSlices > 1)
3221 {
3222 m_arbitraryNumMbsInSlice = 1;
3223 if (sliceCount == 0)
3224 {
3225 m_sliceHeight = slcParams->NumMbsForSlice / m_picWidthInMb;
3226 }
3227 }
3228 else if ((slcParams->NumMbsForSlice % m_picWidthInMb) || // If slice is partial MB row,
3229 ((sliceCount < m_numSlices - 1) && (numMbsInPrevSlice != slcParams->NumMbsForSlice)) || // OR not the last slice and num mbs is not same as prev slice
3230 ((sliceCount == m_numSlices - 1) && ((numMbsInPrevSlice < slcParams->NumMbsForSlice) || // OR it is the last slice and num mbs is not less than prev slice
3231 (MEDIA_IS_WA(m_waTable, WaArbitraryNumMbsInSlice) && (m_numSlices > 16) &&
3232 (!m_vdencEnabled) && (!dirtyRoiEnabled)))))
3233 {
3234 m_arbitraryNumMbsInSlice = 1; // then set flag to use sliceMapSurface
3235 m_sliceHeight = 1; // Slice height doesn't matter if using slicemap just set to any non-zero value.
3236 }
3237 else if ((m_numSlices == 1) || (sliceCount == 0))
3238 {
3239 m_sliceHeight = slcParams->NumMbsForSlice / m_picWidthInMb;
3240 m_arbitraryNumMbsInSlice = 0;
3241 }
3242 numMbsInPrevSlice = slcParams->NumMbsForSlice;
3243 }
3244
3245 if ((picParams->pic_init_qp_minus26 + 26 + slcParams->slice_qp_delta) > CODECHAL_ENCODE_AVC_MAX_SLICE_QP)
3246 {
3247 slcParams->slice_qp_delta = CODECHAL_ENCODE_AVC_MAX_SLICE_QP - (picParams->pic_init_qp_minus26 + 26);
3248 }
3249 slcParams->redundant_pic_cnt = 0;
3250 slcParams->sp_for_switch_flag = 0;
3251 slcParams->slice_qs_delta = 0;
3252 slcParams->redundant_pic_cnt = 0;
3253
3254 slcParams->MaxFrameNum =
3255 1 << (seqParams[picParams->seq_parameter_set_id].log2_max_frame_num_minus4 + 4);
3256 slcParams->frame_num = m_frameNum;
3257 slcParams->field_pic_flag = picParams->FieldCodingFlag;
3258 slcParams->bottom_field_flag =
3259 (CodecHal_PictureIsBottomField(picParams->CurrOriginalPic)) ? 1 : 0;
3260
3261 if (m_pictureCodingType != I_TYPE)
3262 {
3263 for (uint8_t i = 0; i < (slcParams->num_ref_idx_l0_active_minus1 + 1); i++)
3264 {
3265 slcParams->PicOrder[0][i].Picture.FrameIdx =
3266 m_picIdx[slcParams->RefPicList[0][i].FrameIdx].ucPicIdx;
3267 slcParams->PicOrder[0][i].Picture.PicFlags =
3268 slcParams->RefPicList[0][i].PicFlags;
3269 }
3270 }
3271 if (m_pictureCodingType == B_TYPE)
3272 {
3273 for (uint8_t i = 0; i < (slcParams->num_ref_idx_l1_active_minus1 + 1); i++)
3274 {
3275 slcParams->PicOrder[1][i].Picture.FrameIdx =
3276 m_picIdx[slcParams->RefPicList[1][i].FrameIdx].ucPicIdx;
3277 slcParams->PicOrder[1][i].Picture.PicFlags =
3278 slcParams->RefPicList[1][i].PicFlags;
3279 }
3280 }
3281 slcParams++;
3282 }
3283
3284 if (eStatus == MOS_STATUS_INVALID_PARAMETER)
3285 {
3286 CODECHAL_ENCODE_ASSERTMESSAGE("Invalid slice parameters.");
3287 }
3288 return eStatus;
3289 }
3290
SetMfxPipeModeSelectParams(const CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS & genericParam,MHW_VDBOX_PIPE_MODE_SELECT_PARAMS & param)3291 void CodechalEncodeAvcBase::SetMfxPipeModeSelectParams(
3292 const CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS &genericParam,
3293 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS & param)
3294 {
3295 // set MFX_PIPE_MODE_SELECT values
3296 param = {};
3297 param.Mode = m_mode;
3298 param.bStreamOutEnabled = (m_currPass != m_numPasses); // Disable Stream Out for final pass; its important for multiple passes, because , next pass will take the qp from stream out
3299 param.bVdencEnabled = m_vdencEnabled;
3300 param.bDeblockerStreamOutEnable = genericParam.bDeblockerStreamOutEnable;
3301 param.bStreamOutEnabledExtEnabled = genericParam.bPerMBStreamOutEnable;
3302 param.bPostDeblockOutEnable = genericParam.bPostDeblockOutEnable;
3303 param.bPreDeblockOutEnable = genericParam.bPreDeblockOutEnable;
3304 param.bDynamicSliceEnable = m_avcSeqParam->EnableSliceLevelRateCtrl;
3305 param.bVdencStreamInEnable = m_vdencStreamInEnabled;
3306 param.bTlbPrefetchEnable = m_tlbPrefetchEnable;
3307 param.ChromaType = m_avcSeqParam->chroma_format_idc;
3308 param.Format = m_rawSurfaceToPak->Format;
3309 }
3310
SetMfxPipeBufAddrStateParams(CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS genericParam,MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & param)3311 MOS_STATUS CodechalEncodeAvcBase::SetMfxPipeBufAddrStateParams(
3312 CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS genericParam,
3313 MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & param)
3314 {
3315 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3316
3317 param.Mode = m_mode;
3318 param.psPreDeblockSurface = genericParam.psPreDeblockSurface;
3319 param.psPostDeblockSurface = genericParam.psPostDeblockSurface;
3320
3321 param.psRawSurface = m_rawSurfaceToPak;
3322 param.presStreamOutBuffer = &m_resStreamOutBuffer[m_currRecycledBufIdx];
3323 param.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resDeblockingFilterRowStoreScratchBuffer;
3324 param.presMfdIntraRowStoreScratchBuffer = &m_intraRowStoreScratchBuffer;
3325 param.bVdencEnabled = m_vdencEnabled;
3326 param.presMacroblockIldbStreamOutBuffer1 = genericParam.presMacroblockIldbStreamOutBuffer1;
3327 param.presMacroblockIldbStreamOutBuffer2 = genericParam.presMacroblockIldbStreamOutBuffer2;
3328
3329 CODECHAL_DEBUG_TOOL(
3330 // PAK Input Raw Surface
3331 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
3332 m_rawSurfaceToPak,
3333 CodechalDbgAttr::attrEncodeRawInputSurface,
3334 "PAK_Input_SrcSurf")););
3335
3336 auto firstValidFrame = &m_reconSurface.OsResource;
3337
3338 // Setting invalid entries to nullptr
3339 for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
3340 param.presReferences[i] = nullptr;
3341
3342 uint8_t firstValidFrameId = CODEC_AVC_MAX_NUM_REF_FRAME;
3343 uint8_t numrefL0 = m_avcSliceParams->num_ref_idx_l0_active_minus1 + 1;
3344 uint8_t numrefL1 = m_avcSliceParams->num_ref_idx_l1_active_minus1 + 1;
3345
3346 for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
3347 {
3348 if (m_picIdx[i].bValid)
3349 {
3350 auto picIdx = m_picIdx[i].ucPicIdx;
3351 auto frameStoreId = m_refList[picIdx]->ucFrameId;
3352
3353 CodecHalGetResourceInfo(m_osInterface, &(m_refList[picIdx]->sRefReconBuffer));
3354 param.presReferences[frameStoreId] = &(m_refList[picIdx]->sRefReconBuffer.OsResource);
3355
3356 if (picIdx < firstValidFrameId)
3357 {
3358 firstValidFrameId = picIdx;
3359 firstValidFrame = param.presReferences[picIdx];
3360 }
3361
3362 }
3363 }
3364 CODECHAL_DEBUG_TOOL(
3365 MOS_SURFACE refSurface;
3366 for (uint8_t i = 0; i < numrefL0; i++)
3367 {
3368 if (m_pictureCodingType != I_TYPE && m_avcSliceParams->RefPicList[0][i].PicFlags != PICTURE_INVALID)
3369 {
3370 auto refPic = m_avcSliceParams->RefPicList[0][i];
3371 auto picIdx = m_picIdx[refPic.FrameIdx].ucPicIdx;
3372 auto frameStoreId = m_refList[picIdx]->ucFrameId;
3373 CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface);
3374
3375 MOS_ZeroMemory(&refSurface, sizeof(refSurface));
3376 refSurface.Format = Format_NV12;
3377 refSurface.OsResource = *(param.presReferences[frameStoreId]);
3378 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
3379 m_osInterface,
3380 &refSurface));
3381 m_debugInterface->m_refIndex = frameStoreId;
3382 std::string refSurfName = "RefSurfL0[" + std::to_string(static_cast<uint32_t>(i)) + "]";
3383 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
3384 &refSurface,
3385 CodechalDbgAttr::attrReferenceSurfaces,
3386 refSurfName.c_str()));
3387 }
3388 }
3389 for (uint8_t i = 0; i < numrefL1; i++)
3390 {
3391 if (m_pictureCodingType == B_TYPE && m_avcSliceParams->RefPicList[1][i].PicFlags != PICTURE_INVALID)
3392 {
3393 auto refPic = m_avcSliceParams->RefPicList[1][i];
3394 auto picIdx = m_picIdx[refPic.FrameIdx].ucPicIdx;
3395 auto frameStoreId = m_refList[picIdx]->ucFrameId;
3396 CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface);
3397 //MOS_SURFACE refSurface;
3398 MOS_ZeroMemory(&refSurface, sizeof(refSurface));
3399 refSurface.Format = Format_NV12;
3400 refSurface.OsResource = *(param.presReferences[frameStoreId]);
3401 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
3402 m_osInterface,
3403 &refSurface));
3404 m_debugInterface->m_refIndex = frameStoreId;
3405 std::string refSurfName = "RefSurfL1[" + std::to_string(static_cast<uint32_t>(i)) + "]";
3406 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
3407 &refSurface,
3408 CodechalDbgAttr::attrReferenceSurfaces,
3409 refSurfName.c_str()));
3410 }
3411 }
3412
3413 );
3414
3415 for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
3416 {
3417 // error concealment for the unset reference addresses
3418 if (!param.presReferences[i])
3419 {
3420 param.presReferences[i] = firstValidFrame;
3421 }
3422 }
3423
3424 if (m_sliceSizeStreamoutSupported)
3425 {
3426 param.presSliceSizeStreamOutBuffer = &m_pakSliceSizeStreamoutBuffer;
3427 }
3428 return eStatus;
3429 }
3430
SetMfxIndObjBaseAddrStateParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS & param)3431 void CodechalEncodeAvcBase::SetMfxIndObjBaseAddrStateParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS ¶m)
3432 {
3433 MOS_ZeroMemory(¶m, sizeof(param));
3434 param.Mode = CODECHAL_ENCODE_MODE_AVC;
3435 param.presPakBaseObjectBuffer = &m_resBitstreamBuffer;
3436 param.dwPakBaseObjectSize = m_bitstreamUpperBound;
3437 }
3438
SetMfxBspBufBaseAddrStateParams(MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS & param)3439 void CodechalEncodeAvcBase::SetMfxBspBufBaseAddrStateParams(MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS ¶m)
3440 {
3441 MOS_ZeroMemory(¶m, sizeof(param));
3442 param.presBsdMpcRowStoreScratchBuffer = &m_resMPCRowStoreScratchBuffer;
3443 }
3444
SetMfxQmStateParams(MHW_VDBOX_QM_PARAMS & qmParams,MHW_VDBOX_QM_PARAMS & fqmParams)3445 void CodechalEncodeAvcBase::SetMfxQmStateParams(MHW_VDBOX_QM_PARAMS &qmParams, MHW_VDBOX_QM_PARAMS &fqmParams)
3446 {
3447 MOS_ZeroMemory(&qmParams, sizeof(qmParams));
3448 MOS_ZeroMemory(&fqmParams, sizeof(fqmParams));
3449
3450 qmParams.Standard = CODECHAL_AVC;
3451 qmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists;
3452
3453 fqmParams.Standard = CODECHAL_AVC;
3454 fqmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists;
3455 }
3456
SetMfxAvcImgStateParams(MHW_VDBOX_AVC_IMG_PARAMS & param)3457 void CodechalEncodeAvcBase::SetMfxAvcImgStateParams(MHW_VDBOX_AVC_IMG_PARAMS ¶m)
3458 {
3459 param = {};
3460 param.currPass = m_currPass;
3461 param.pEncodeAvcPicParams = m_avcPicParam;
3462 param.pEncodeAvcSeqParams = m_avcSeqParam;
3463 param.pEncodeAvcSliceParams = m_avcSliceParams;
3464 param.wPicWidthInMb = m_picWidthInMb;
3465 param.wPicHeightInMb = m_picHeightInMb;
3466 param.ppRefList = &(m_refList[0]);
3467 param.pPicIdx = &(m_picIdx[0]);
3468 param.dwTqEnabled = m_trellisQuantParams.dwTqEnabled;
3469 param.dwTqRounding = m_trellisQuantParams.dwTqRounding;
3470 param.ucKernelMode = m_kernelMode;
3471 param.wSlcHeightInMb = m_sliceHeight;
3472 param.dwMaxVmvR = CodecHalAvcEncode_GetMaxVmvR(m_avcSeqParam->Level);
3473 param.bVdencStreamInEnabled = m_vdencStreamInEnabled;
3474 param.bSliceSizeStreamOutEnabled = m_sliceSizeStreamoutSupported;
3475 param.bCrePrefetchEnable = m_crePrefetchEnable;
3476
3477 if (m_currPass && (m_currPass == m_numPasses) && (!m_vdencBrcEnabled))
3478 {
3479 // Enable IPCM pass, excluding VDENC BRC case
3480 param.bIPCMPass = true;
3481 }
3482 }
3483
UpdateSSDSliceCount()3484 void CodechalEncodeAvcBase::UpdateSSDSliceCount()
3485 {
3486 m_setRequestedEUSlices = ((m_frameHeight * m_frameWidth) >= m_ssdResolutionThreshold &&
3487 m_targetUsage <= m_ssdTargetUsageThreshold)
3488 ? true
3489 : false;
3490
3491 m_hwInterface->m_numRequestedEuSlices = (m_setRequestedEUSlices) ? m_sliceShutdownRequestState : m_sliceShutdownDefaultState;
3492 }
3493
AddIshSize(uint32_t kuid,uint8_t * kernelBase)3494 MOS_STATUS CodechalEncodeAvcBase::AddIshSize(uint32_t kuid, uint8_t *kernelBase)
3495 {
3496 uint8_t *kernelBinary;
3497 uint32_t kernelSize;
3498
3499 MOS_STATUS status = CodecHalGetKernelBinaryAndSize(kernelBase, kuid, &kernelBinary, &kernelSize);
3500 CODECHAL_ENCODE_CHK_STATUS_RETURN(status);
3501 m_hwInterface->GetStateHeapSettings()->dwIshSize += MOS_ALIGN_CEIL(kernelSize, (1 << MHW_KERNEL_OFFSET_SHIFT));
3502 return status;
3503 }
3504
StoreNumPasses(EncodeStatusBuffer * encodeStatusBuf,MhwMiInterface * miInterface,PMOS_COMMAND_BUFFER cmdBuffer,uint32_t currPass)3505 MOS_STATUS CodechalEncodeAvcBase::StoreNumPasses(
3506 EncodeStatusBuffer *encodeStatusBuf,
3507 MhwMiInterface * miInterface,
3508 PMOS_COMMAND_BUFFER cmdBuffer,
3509 uint32_t currPass)
3510 {
3511 MHW_MI_STORE_DATA_PARAMS storeDataParams;
3512 uint32_t offset;
3513 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3514
3515 CODECHAL_ENCODE_FUNCTION_ENTER;
3516
3517 CODECHAL_ENCODE_CHK_NULL_RETURN(encodeStatusBuf);
3518 CODECHAL_ENCODE_CHK_NULL_RETURN(miInterface);
3519 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
3520
3521 offset =
3522 (encodeStatusBuf->wCurrIndex * encodeStatusBuf->dwReportSize) +
3523 encodeStatusBuf->dwNumPassesOffset + // Num passes offset
3524 sizeof(uint32_t) * 2; // pEncodeStatus is offset by 2 DWs in the resource
3525
3526 storeDataParams.pOsResource = &encodeStatusBuf->resStatusBuffer;
3527 storeDataParams.dwResourceOffset = offset;
3528 storeDataParams.dwValue = currPass + 1;
3529 CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
3530
3531 return MOS_STATUS_SUCCESS;
3532 }
3533
fill_pad_with_value(PMOS_SURFACE psSurface,uint32_t real_height,uint32_t aligned_height)3534 void CodechalEncodeAvcBase::fill_pad_with_value(PMOS_SURFACE psSurface, uint32_t real_height, uint32_t aligned_height)
3535 {
3536 CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(psSurface);
3537
3538 // unaligned surfaces only
3539 if (aligned_height <= real_height || aligned_height > psSurface->dwHeight)
3540 {
3541 return;
3542 }
3543
3544 if (psSurface->OsResource.TileType == MOS_TILE_INVALID)
3545 {
3546 return;
3547 }
3548
3549 if (psSurface->Format == Format_NV12 || psSurface->Format == Format_P010)
3550 {
3551 uint32_t pitch = psSurface->dwPitch;
3552 uint32_t UVPlaneOffset = psSurface->UPlaneOffset.iSurfaceOffset;
3553 uint32_t YPlaneOffset = psSurface->dwOffset;
3554 uint32_t pad_rows = aligned_height - real_height;
3555 uint32_t y_plane_size = pitch * real_height;
3556 uint32_t uv_plane_size = pitch * real_height / 2;
3557
3558 MOS_LOCK_PARAMS lockFlags;
3559 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
3560 lockFlags.WriteOnly = 1;
3561
3562 // padding for the linear format buffer.
3563 if (psSurface->OsResource.TileType == MOS_TILE_LINEAR)
3564 {
3565 uint8_t *src_data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags);
3566 CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(src_data);
3567
3568 uint8_t *src_data_y = src_data + YPlaneOffset;
3569 uint8_t *src_data_y_end = src_data_y + y_plane_size;
3570 for (uint32_t i = 0; i < pad_rows; i++)
3571 {
3572 MOS_SecureMemcpy(src_data_y_end + i * pitch, pitch, src_data_y_end - pitch, pitch);
3573 }
3574
3575 uint8_t *src_data_uv = src_data + UVPlaneOffset;
3576 uint8_t *src_data_uv_end = src_data_uv + uv_plane_size;
3577 for (uint32_t i = 0; i < pad_rows / 2; i++)
3578 {
3579 MOS_SecureMemcpy(src_data_uv_end + i * pitch, pitch, src_data_uv_end - pitch, pitch);
3580 }
3581
3582 m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource));
3583 }
3584 else
3585 {
3586 // we don't copy out the whole tiled buffer to linear and padding on the tiled buffer directly.
3587 lockFlags.TiledAsTiled = 1;
3588
3589 uint8_t *src_data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags);
3590 CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(src_data);
3591
3592 uint8_t *padding_data = (uint8_t *)MOS_AllocMemory(pitch * pad_rows);
3593 CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(padding_data);
3594
3595 // Copy last Y row data to linear padding data.
3596 GMM_RES_COPY_BLT gmmResCopyBlt = {0};
3597 gmmResCopyBlt.Gpu.pData = src_data;
3598 gmmResCopyBlt.Gpu.OffsetX = 0;
3599 gmmResCopyBlt.Gpu.OffsetY = (YPlaneOffset + y_plane_size - pitch) / pitch;
3600 gmmResCopyBlt.Sys.pData = padding_data;
3601 gmmResCopyBlt.Sys.RowPitch = pitch;
3602 gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows;
3603 gmmResCopyBlt.Sys.SlicePitch = pitch;
3604 gmmResCopyBlt.Blt.Slices = 1;
3605 gmmResCopyBlt.Blt.Upload = false;
3606 gmmResCopyBlt.Blt.Width = psSurface->dwWidth;
3607 gmmResCopyBlt.Blt.Height = 1;
3608 psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
3609 // Fill the remain padding lines with last Y row data.
3610 for (uint32_t i = 1; i < pad_rows; i++)
3611 {
3612 MOS_SecureMemcpy(padding_data + i * pitch, pitch, padding_data, pitch);
3613 }
3614 // Filling the padding for Y.
3615 gmmResCopyBlt.Gpu.pData = src_data;
3616 gmmResCopyBlt.Gpu.OffsetX = 0;
3617 gmmResCopyBlt.Gpu.OffsetY = (YPlaneOffset + y_plane_size) / pitch;
3618 gmmResCopyBlt.Sys.pData = padding_data;
3619 gmmResCopyBlt.Sys.RowPitch = pitch;
3620 gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows;
3621 gmmResCopyBlt.Sys.SlicePitch = pitch;
3622 gmmResCopyBlt.Blt.Slices = 1;
3623 gmmResCopyBlt.Blt.Upload = true;
3624 gmmResCopyBlt.Blt.Width = psSurface->dwWidth;
3625 gmmResCopyBlt.Blt.Height = pad_rows;
3626 psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
3627
3628 // Copy last UV row data to linear padding data.
3629 gmmResCopyBlt.Gpu.pData = src_data;
3630 gmmResCopyBlt.Gpu.OffsetX = 0;
3631 gmmResCopyBlt.Gpu.OffsetY = (UVPlaneOffset + uv_plane_size - pitch) / pitch;
3632 gmmResCopyBlt.Sys.pData = padding_data;
3633 gmmResCopyBlt.Sys.RowPitch = pitch;
3634 gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows / 2;
3635 gmmResCopyBlt.Sys.SlicePitch = pitch;
3636 gmmResCopyBlt.Blt.Slices = 1;
3637 gmmResCopyBlt.Blt.Upload = false;
3638 gmmResCopyBlt.Blt.Width = psSurface->dwWidth;
3639 gmmResCopyBlt.Blt.Height = 1;
3640 psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
3641 // Fill the remain padding lines with last UV row data.
3642 for (uint32_t i = 1; i < pad_rows / 2; i++)
3643 {
3644 MOS_SecureMemcpy(padding_data + i * pitch, pitch, padding_data, pitch);
3645 }
3646 // Filling the padding for UV.
3647 gmmResCopyBlt.Gpu.pData = src_data;
3648 gmmResCopyBlt.Gpu.OffsetX = 0;
3649 gmmResCopyBlt.Gpu.OffsetY = (UVPlaneOffset + uv_plane_size) / pitch;
3650 gmmResCopyBlt.Sys.pData = padding_data;
3651 gmmResCopyBlt.Sys.RowPitch = pitch;
3652 gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows / 2;
3653 gmmResCopyBlt.Sys.SlicePitch = pitch;
3654 gmmResCopyBlt.Blt.Slices = 1;
3655 gmmResCopyBlt.Blt.Upload = true;
3656 gmmResCopyBlt.Blt.Width = psSurface->dwWidth;
3657 gmmResCopyBlt.Blt.Height = pad_rows / 2;
3658 psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
3659
3660 MOS_FreeMemory(padding_data);
3661 padding_data = nullptr;
3662 m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource));
3663 }
3664 }
3665 }
3666
3667 #if USE_CODECHAL_DEBUG_TOOL
DumpEncodePicReorder(std::ostringstream & oss,uint32_t x,uint32_t y,CODEC_PIC_REORDER * picReorder)3668 static MOS_STATUS DumpEncodePicReorder(
3669 std::ostringstream &oss,
3670 uint32_t x,
3671 uint32_t y,
3672 CODEC_PIC_REORDER * picReorder)
3673 {
3674 uint8_t botField;
3675
3676 CODECHAL_DEBUG_CHK_NULL(picReorder);
3677
3678 botField = CodecHal_PictureIsBottomField(picReorder->Picture) ? 1 : 0;
3679
3680 oss << "# PicOrder[" << std::dec << +x << "][" << std::dec << +y << "] =" << std::endl;
3681 oss << "# \tPicNum = " << std::dec << +picReorder->PicNum << std::endl;
3682 oss << "# \tPOC = " << std::dec << +picReorder->POC << std::endl;
3683 oss << "# \tReorderPicNumIDC = " << std::dec << +picReorder->ReorderPicNumIDC << std::endl;
3684 oss << "# \tDiffPicNumMinus1 = " << std::dec << +picReorder->DiffPicNumMinus1 << std::endl;
3685 oss << "# \tFrameIdx = " << std::dec << +picReorder->Picture.FrameIdx << std::endl;
3686 oss << "# \tBotField = " << std::dec << +botField << std::endl;
3687
3688 return MOS_STATUS_SUCCESS;
3689 }
3690
DumpSeqParams(PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams,PCODEC_AVC_IQ_MATRIX_PARAMS matrixParams)3691 MOS_STATUS CodechalEncodeAvcBase::DumpSeqParams(
3692 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams,
3693 PCODEC_AVC_IQ_MATRIX_PARAMS matrixParams)
3694 {
3695 CODECHAL_DEBUG_FUNCTION_ENTER;
3696
3697 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSeqParams))
3698 {
3699 return MOS_STATUS_SUCCESS;
3700 }
3701
3702 CODECHAL_DEBUG_CHK_NULL(seqParams);
3703
3704 std::ostringstream oss;
3705 oss.setf(std::ios::showbase | std::ios::uppercase);
3706
3707 oss << "# DDI Parameters:" << std::endl;
3708 oss << "FrameWidth = " << +seqParams->FrameWidth << std::endl;
3709 oss << "FrameHeight = " << +seqParams->FrameHeight << std::endl;
3710 oss << "Profile = " << +seqParams->Profile << std::endl;
3711 oss << "Level = " << +seqParams->Level << std::endl;
3712 oss << "GopPicSize = " << +seqParams->GopPicSize << std::endl;
3713 oss << "GopRefDist = " << +seqParams->GopRefDist << std::endl;
3714 oss << "GopOptFlag = " << +seqParams->GopOptFlag << std::endl;
3715 oss << "TargetUsage = " << +seqParams->TargetUsage << std::endl;
3716 oss << "RateControlMethod = " << +seqParams->RateControlMethod << std::endl;
3717 oss << "TargetBitRate = " << +seqParams->TargetBitRate << std::endl;
3718 oss << "MaxBitRate = " << +seqParams->MaxBitRate << std::endl;
3719 oss << "MinBitRate = " << +seqParams->MinBitRate << std::endl;
3720 oss << "FramesPer100Sec = " << +seqParams->FramesPer100Sec << std::endl;
3721 oss << "InitVBVBufferFullnessInBit = " << +seqParams->InitVBVBufferFullnessInBit << std::endl;
3722 oss << "VBVBufferSizeInBit = " << +seqParams->VBVBufferSizeInBit << std::endl;
3723 oss << "NumRefFrames = " << +seqParams->NumRefFrames / 2 << std::endl; // this prints the value passed from DDI
3724 oss << "# NumRefFrames (Actual Value in CodecHal is twice the value passed from DDI) = "
3725 << +seqParams->NumRefFrames << std::endl; // this prints the actual value in CodecHal seq param structure
3726 oss << "seq_parameter_set_id = " << +seqParams->seq_parameter_set_id << std::endl;
3727 oss << "chroma_format_idc = " << +seqParams->chroma_format_idc << std::endl;
3728 oss << "bit_depth_luma_minus8 = " << +seqParams->bit_depth_luma_minus8 << std::endl;
3729 oss << "bit_depth_chroma_minus8 = " << +seqParams->bit_depth_chroma_minus8 << std::endl;
3730 oss << "log2_max_frame_num_minus4 = " << +seqParams->log2_max_frame_num_minus4 << std::endl;
3731 oss << "pic_order_cnt_type = " << +seqParams->pic_order_cnt_type << std::endl;
3732 oss << "log2_max_pic_order_cnt_lsb_minus4 = " << +seqParams->log2_max_pic_order_cnt_lsb_minus4 << std::endl;
3733 oss << "num_ref_frames_in_pic_order_cnt_cycle = " << +seqParams->num_ref_frames_in_pic_order_cnt_cycle << std::endl;
3734 oss << "offset_for_non_ref_pic = " << +seqParams->offset_for_non_ref_pic << std::endl;
3735 oss << "offset_for_top_to_bottom_field = " << +seqParams->offset_for_top_to_bottom_field << std::endl;
3736
3737 // Conditionally printed (only when pic_order_cnt_type = 1). Contains 256 elements.
3738 if (seqParams->pic_order_cnt_type == 1)
3739 {
3740 for (uint16_t i = 0; i < 256; ++i)
3741 {
3742 oss << "offset_for_ref_frame[" << +i << "] = " << +seqParams->offset_for_ref_frame[i] << std::endl;
3743 }
3744 }
3745
3746 oss << "frame_crop_left_offset = " << +seqParams->frame_crop_left_offset << std::endl;
3747 oss << "frame_crop_right_offset = " << +seqParams->frame_crop_right_offset << std::endl;
3748 oss << "frame_crop_top_offset = " << +seqParams->frame_crop_top_offset << std::endl;
3749 oss << "frame_crop_bottom_offset = " << +seqParams->frame_crop_bottom_offset << std::endl;
3750 oss << "seq_scaling_matrix_present_flag = " << +seqParams->seq_scaling_matrix_present_flag << std::endl;
3751 oss << "seq_scaling_list_present_flag = " << +seqParams->seq_scaling_list_present_flag[0] << std::endl;
3752
3753 // seq_scaling_list_present_flag with 12 elements (only 1 element acknowledged in DDI doc)
3754 oss << "# seq_scaling_list_present_flag[1-11]:";
3755 for (uint8_t i = 1; i < 12; i++)
3756 oss << +seqParams->seq_scaling_list_present_flag[i] << " ";
3757 oss << std::endl;
3758
3759 oss << "delta_pic_order_always_zero_flag = " << +seqParams->delta_pic_order_always_zero_flag << std::endl;
3760 oss << "frame_mbs_only_flag = " << +seqParams->frame_mbs_only_flag << std::endl;
3761 oss << "direct_8x8_inference_flag = " << +seqParams->direct_8x8_inference_flag << std::endl;
3762 oss << "vui_parameters_present_flag = " << +seqParams->vui_parameters_present_flag << std::endl;
3763 oss << "frame_cropping_flag = " << +seqParams->frame_cropping_flag << std::endl;
3764 oss << "EnableSliceLevelRateCtrl = " << +seqParams->EnableSliceLevelRateCtrl << std::endl;
3765 oss << "ICQQualityFactor = " << +seqParams->ICQQualityFactor << std::endl;
3766 oss << "InputColorSpace = " << +seqParams->InputColorSpace << std::endl;
3767
3768 // begining of union/struct
3769 oss << "# bResetBRC = " << +seqParams->bResetBRC << std::endl;
3770 oss << "# bNoAcceleratorSPSInsertion = " << +seqParams->bNoAcceleratorSPSInsertion << std::endl;
3771 oss << "# GlobalSearch = " << +seqParams->GlobalSearch << std::endl;
3772 oss << "# LocalSearch = " << +seqParams->LocalSearch << std::endl;
3773 oss << "# EarlySkip = " << +seqParams->EarlySkip << std::endl;
3774 oss << "# Trellis = " << +seqParams->Trellis << std::endl;
3775 oss << "# MBBRC = " << +seqParams->MBBRC << std::endl;
3776 oss << "# bTemporalScalability = " << +seqParams->bTemporalScalability << std::endl;
3777 oss << "# ROIValueInDeltaQP = " << +seqParams->ROIValueInDeltaQP << std::endl;
3778 oss << "# bAutoMaxPBFrameSizeForSceneChange = " << +seqParams->bAutoMaxPBFrameSizeForSceneChange << std::endl;
3779 oss << "sFlags = " << +seqParams->sFlags << std::endl;
3780
3781 // end of union/struct
3782 oss << "UserMaxIFrameSize = " << +seqParams->UserMaxFrameSize << std::endl;
3783 oss << "UserMaxPBFrameSize = " << +seqParams->UserMaxPBFrameSize << std::endl;
3784
3785 // Parameters not defined in DDI (Any non-DDI parameters printed should be preceeded by #)
3786 oss << "# Non-DDI Parameters:" << std::endl;
3787 oss << "# constraint_set0_flag = " << std::hex << +seqParams->constraint_set0_flag << std::endl;
3788 oss << "# constraint_set1_flag = " << std::hex << +seqParams->constraint_set1_flag << std::endl;
3789 oss << "# constraint_set2_flag = " << std::hex << +seqParams->constraint_set2_flag << std::endl;
3790 oss << "# constraint_set3_flag = " << std::hex << +seqParams->constraint_set3_flag << std::endl;
3791
3792 oss << "# separate_colour_plane_flag = " << std::hex << +seqParams->separate_colour_plane_flag << std::endl;
3793 oss << "# qpprime_y_zero_transform_bypass_flag = " << std::hex << +seqParams->qpprime_y_zero_transform_bypass_flag << std::endl;
3794 oss << "# gaps_in_frame_num_value_allowed_flag = " << std::hex << +seqParams->gaps_in_frame_num_value_allowed_flag << std::endl;
3795 oss << "# pic_width_in_mbs_minus1 = " << std::hex << +seqParams->pic_width_in_mbs_minus1 << std::endl;
3796 oss << "# pic_height_in_map_units_minus1 = " << std::hex << +seqParams->pic_height_in_map_units_minus1 << std::endl;
3797 oss << "# mb_adaptive_frame_field_flag = " << std::hex << +seqParams->mb_adaptive_frame_field_flag << std::endl;
3798
3799 // Dump ScalingList4x4 (6 x 16)
3800 for (uint8_t i = 0; i < 16; ++i)
3801 {
3802 oss << "# ScalingList4x4[" << std::dec << +i * 6 << "-" << (+i * 6) + 5 << "][" << +i << "]";
3803 for (uint8_t j = 0; j < 6; j++)
3804 oss << std::hex << +matrixParams->ScalingList4x4[j][i] << " ";
3805 oss << std::endl;
3806 }
3807
3808 // ScalingList8x8 (2 x 64)
3809 for (uint8_t i = 0; i < 64; ++i)
3810 {
3811 oss << "# ScalingList8x8[0 / 1][ " << std::dec << +i << "] = ";
3812 oss << +matrixParams->ScalingList8x8[0][i] << " / " << +matrixParams->ScalingList8x8[1][i];
3813 oss << std::endl;
3814 }
3815
3816 const char *fileName = m_debugInterface->CreateFileName(
3817 "_DDIEnc",
3818 CodechalDbgBufferType::bufSeqParams,
3819 CodechalDbgExtType::txt);
3820
3821 std::ofstream ofs(fileName, std::ios::out);
3822 ofs << oss.str();
3823 ofs.close();
3824
3825 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
3826 {
3827 if (!m_debugInterface->m_ddiFileName.empty())
3828 {
3829 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
3830 ofs << "SeqParamFile"
3831 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
3832 ofs.close();
3833 }
3834 }
3835
3836 return MOS_STATUS_SUCCESS;
3837 }
3838
DumpPicParams(PCODEC_AVC_ENCODE_PIC_PARAMS picParams,PCODEC_AVC_IQ_MATRIX_PARAMS matrixParams)3839 MOS_STATUS CodechalEncodeAvcBase::DumpPicParams(
3840 PCODEC_AVC_ENCODE_PIC_PARAMS picParams,
3841 PCODEC_AVC_IQ_MATRIX_PARAMS matrixParams)
3842 {
3843 CODECHAL_DEBUG_FUNCTION_ENTER;
3844
3845 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
3846 {
3847 return MOS_STATUS_SUCCESS;
3848 }
3849
3850 CODECHAL_DEBUG_CHK_NULL(picParams);
3851
3852 std::ostringstream oss;
3853 oss.setf(std::ios::showbase | std::ios::uppercase);
3854
3855 oss << "# DDI Parameters:" << std::endl;
3856 oss << "TargetFrameSize = " << +picParams->TargetFrameSize << std::endl;
3857 oss << "CurrOriginalPic = " << +picParams->CurrOriginalPic.PicEntry << std::endl;
3858 oss << "CurrReconstructedPic = " << +picParams->CurrReconstructedPic.PicEntry << std::endl;
3859 oss << "CodingType = " << +picParams->CodingType << std::endl;
3860 oss << "FieldCodingFlag = " << +picParams->FieldCodingFlag << std::endl;
3861 oss << "FieldFrameCodingFlag = " << +picParams->FieldFrameCodingFlag << std::endl;
3862 oss << "NumSlice = " << +picParams->NumSlice << std::endl;
3863 oss << "QpY = " << +picParams->QpY << std::endl;
3864
3865 for (uint8_t i = 0; i < 16; ++i)
3866 {
3867 oss << "RefFrameList[" << +i << "] = " << +picParams->RefFrameList[i].PicEntry << std::endl;
3868 }
3869
3870 oss << "UsedForReferenceFlags = " << +picParams->UsedForReferenceFlags << std::endl;
3871 oss << "CurrFieldOrderCnt[0] = " << +picParams->CurrFieldOrderCnt[0] << std::endl;
3872 oss << "CurrFieldOrderCnt[1] = " << +picParams->CurrFieldOrderCnt[1] << std::endl;
3873
3874 for (uint8_t i = 0; i < 16; ++i)
3875 {
3876 for (uint8_t j = 0; j < 2; ++j)
3877 {
3878 oss << "FieldOrderCntList[" << +i << "]"
3879 << "[" << +j << "] = " << +picParams->FieldOrderCntList[i][j] << std::endl;
3880 }
3881 }
3882
3883 oss << "frame_num = " << +picParams->frame_num << std::endl;
3884 oss << "bLastPicInSeq = " << +picParams->bLastPicInSeq << std::endl;
3885 oss << "bLastPicInStream = " << +picParams->bLastPicInStream << std::endl;
3886
3887 // User Flags parameters
3888 oss << "# bUseRawPicForRef = " << +picParams->UserFlags.bUseRawPicForRef << std::endl;
3889 oss << "# bDisableAcceleratorHeaderPacking = " << +picParams->UserFlags.bDisableAcceleratorHeaderPacking << std::endl;
3890 oss << "# bDisableSubMBPartition = " << +picParams->UserFlags.bDisableSubMBPartition << std::endl;
3891 oss << "# bEmulationByteInsertion = " << +picParams->UserFlags.bEmulationByteInsertion << std::endl;
3892 oss << "# bEnableRollingIntraRefresh = " << +picParams->UserFlags.bEnableRollingIntraRefresh << std::endl;
3893 oss << "ForceRepartitionCheck = " << +picParams->UserFlags.ForceRepartitionCheck << std::endl;
3894 oss << "UserFlags = " << +picParams->UserFlags.Value << std::endl;
3895 oss << "StatusReportFeedbackNumber = " << +picParams->StatusReportFeedbackNumber << std::endl;
3896 oss << "bIdrPic = " << +picParams->bIdrPic << std::endl;
3897 oss << "pic_parameter_set_id = " << +picParams->pic_parameter_set_id << std::endl;
3898 oss << "seq_parameter_set_id = " << +picParams->seq_parameter_set_id << std::endl;
3899 oss << "num_ref_idx_l0_active_minus1 = " << +picParams->num_ref_idx_l0_active_minus1 << std::endl;
3900 oss << "num_ref_idx_l1_active_minus1 = " << +picParams->num_ref_idx_l1_active_minus1 << std::endl;
3901 oss << "chroma_qp_index_offset = " << +picParams->chroma_qp_index_offset << std::endl;
3902 oss << "second_chroma_qp_index_offset = " << +picParams->second_chroma_qp_index_offset << std::endl;
3903 oss << "entropy_coding_mode_flag = " << +picParams->entropy_coding_mode_flag << std::endl;
3904 oss << "pic_order_present_flag = " << +picParams->pic_order_present_flag << std::endl;
3905 oss << "weighted_pred_flag = " << +picParams->weighted_pred_flag << std::endl;
3906 oss << "weighted_bipred_idc = " << +picParams->weighted_bipred_idc << std::endl;
3907 oss << "constrained_intra_pred_flag = " << +picParams->constrained_intra_pred_flag << std::endl;
3908 oss << "transform_8x8_mode_flag = " << +picParams->transform_8x8_mode_flag << std::endl;
3909 oss << "pic_scaling_matrix_present_flag = " << +picParams->pic_scaling_matrix_present_flag << std::endl;
3910 oss << "pic_scaling_list_present_flag = " << +picParams->pic_scaling_list_present_flag[0] << std::endl;
3911
3912 // pic_scaling_list_present_flag buffer contains 12 elements (only 1 acknowledged DDI document)
3913 oss << "# pic_scaling_list_present_flag[1-11]:";
3914 oss << +picParams->pic_scaling_list_present_flag[1] << " ";
3915 oss << +picParams->pic_scaling_list_present_flag[2] << " ";
3916 oss << +picParams->pic_scaling_list_present_flag[3] << " ";
3917 oss << +picParams->pic_scaling_list_present_flag[4] << " ";
3918 oss << +picParams->pic_scaling_list_present_flag[5] << " ";
3919 oss << +picParams->pic_scaling_list_present_flag[6] << " ";
3920 oss << +picParams->pic_scaling_list_present_flag[7] << " ";
3921 oss << +picParams->pic_scaling_list_present_flag[8] << " ";
3922 oss << +picParams->pic_scaling_list_present_flag[9] << " ";
3923 oss << +picParams->pic_scaling_list_present_flag[10] << " ";
3924 oss << +picParams->pic_scaling_list_present_flag[11] << std::endl;
3925
3926 oss << "RefPicFlag = " << +picParams->RefPicFlag << std::endl;
3927 oss << "BRCPrecision = " << +picParams->BRCPrecision << std::endl;
3928 oss << "bDisplayFormatSwizzle = " << +picParams->bDisplayFormatSwizzle << std::endl;
3929 oss << "IntraInsertionLocation = " << +picParams->IntraRefreshMBNum << std::endl;
3930 oss << "IntraInsertionSize = " << +picParams->IntraRefreshUnitinMB << std::endl;
3931 oss << "QpDeltaForInsertedIntra = " << +picParams->IntraRefreshQPDelta << std::endl;
3932 oss << "SliceSizeInBytes = " << +picParams->SliceSizeInBytes << std::endl;
3933 oss << "bDisableRollingIntraRefreshOverlap = " << +picParams->bDisableRollingIntraRefreshOverlap << std::endl;
3934 oss << "NumROI = " << +picParams->NumROI << std::endl;
3935 oss << "MinDeltaQp = " << +picParams->MinDeltaQp << std::endl;
3936 oss << "MaxDeltaQp = " << +picParams->MaxDeltaQp << std::endl;
3937
3938 // Dump ROI coordinates and PriorityLevelOrDQp
3939 for (uint16_t i = 0; i < picParams->NumROI; ++i)
3940 {
3941 oss << "ROI[" << +i << "] = [";
3942 oss << +picParams->ROI[i].Top << ",";
3943 oss << +picParams->ROI[i].Bottom << ",";
3944 oss << +picParams->ROI[i].Left << ",";
3945 oss << +picParams->ROI[i].Right << "], ";
3946 oss << "PriorityLevelOrDQp = " << +picParams->ROI[i].PriorityLevelOrDQp << std::endl;
3947 }
3948
3949 oss << "NumDirtyROI = " << +picParams->NumDirtyROI << std::endl;
3950
3951 // Dump Dirty ROI coordinates and PriorityLevelOrDQp
3952 for (uint16_t i = 0; i < picParams->NumDirtyROI; ++i)
3953 {
3954 oss << "DirtyROI[" << +i << "] = [";
3955 oss << +picParams->DirtyROI[i].Top << ",";
3956 oss << +picParams->DirtyROI[i].Bottom << ",";
3957 oss << +picParams->DirtyROI[i].Left << ",";
3958 oss << +picParams->DirtyROI[i].Right << "], ";
3959 oss << "PriorityLevelOrDQp = " << +picParams->DirtyROI[i].PriorityLevelOrDQp << std::endl;
3960 }
3961
3962 oss << "SkipFrameFlag = " << +picParams->SkipFrameFlag << std::endl;
3963 oss << "NumSkipFrames = " << +picParams->NumSkipFrames << std::endl;
3964 oss << "SizeSkipFrames = " << +picParams->SizeSkipFrames << std::endl;
3965
3966 // Dump Min/Max QP params
3967 oss << "BRCMinQp = " << +picParams->ucMinimumQP << std::endl;
3968 oss << "BRCMaxQp = " << +picParams->ucMaximumQP << std::endl;
3969
3970 // Dump SFD threshold
3971 oss << "dwZMvThreshold = " << +picParams->dwZMvThreshold << std::endl;
3972
3973 // Dump HME offset
3974 oss << "bEnableHMEOffset = " << +picParams->bEnableHMEOffset << std::endl;
3975
3976 for (uint8_t i = 0; i < 16; ++i)
3977 {
3978 for (uint8_t j = 0; j < 2; ++j)
3979 {
3980 for (uint8_t k = 0; k < 2; ++k)
3981 {
3982 oss << "HMEOffset[" << +i << "][" << +j << "][" << +k << "] = " << +picParams->HMEOffset[i][j][k] << std::endl;
3983 }
3984 }
3985 }
3986
3987 oss << "bDisableFrameSkip = " << +picParams->bDisableFrameSkip << std::endl;
3988 oss << "bEnableSync = " << +picParams->bEnableSync << std::endl;
3989 oss << "bRepeatFrame = " << +picParams->bRepeatFrame << std::endl;
3990 oss << "bEnableQpAdjustment = " << +picParams->bEnableQpAdjustment << std::endl;
3991
3992 oss << "NumDeltaQpForNonRectROI = " << +picParams->NumDeltaQpForNonRectROI << std::endl;
3993 for (uint16_t i = 0; i < picParams->NumDeltaQpForNonRectROI; ++i)
3994 {
3995 oss << "NonRectROIDeltaQpList[" << +i << "] = " << +picParams->NonRectROIDeltaQpList[i] << std::endl;
3996 }
3997
3998 oss << "SyncMarkerX = " << +picParams->SyncMarkerX << std::endl;
3999 oss << "SyncMarkerY = " << +picParams->SyncMarkerY << std::endl;
4000 oss << "SyncMarkerSize = " << +picParams->SyncMarkerSize << std::endl;
4001 oss << "HierarchLevelPlus1 = " << +picParams->HierarchLevelPlus1 << std::endl;
4002 oss << "QpModulationStrength = " << +picParams->QpModulationStrength << std::endl;
4003
4004 // Parameters not defined in DDI (Any non-DDI parameters printed should be preceeded by #)
4005 oss << "# Non-DDI Parameters:" << std::endl;
4006 oss << "# num_slice_groups_minus1 = " << +picParams->num_slice_groups_minus1 << std::endl;
4007 oss << "# pic_init_qp_minus26 = " << +picParams->pic_init_qp_minus26 << std::endl;
4008 oss << "# pic_init_qs_minus26 = " << +picParams->pic_init_qs_minus26 << std::endl;
4009 oss << "# deblocking_filter_control_present_flag = " << +picParams->deblocking_filter_control_present_flag << std::endl;
4010 oss << "# redundant_pic_cnt_present_flag = " << +picParams->redundant_pic_cnt_present_flag << std::endl;
4011 oss << "# EnableRollingIntraRefresh = " << +picParams->EnableRollingIntraRefresh << std::endl;
4012 oss << "# IntraRefreshMBx = " << +picParams->IntraRefreshMBx << std::endl;
4013 oss << "# IntraRefreshMBy = " << +picParams->IntraRefreshMBy << std::endl;
4014 oss << "# IntraRefreshUnitinMB = " << +picParams->IntraRefreshUnitinMB << std::endl;
4015 oss << "# IntraRefreshQPDelta = " << +picParams->IntraRefreshQPDelta << std::endl;
4016
4017 // Dump ScalingList4x4 (6 x 16)
4018 for (uint8_t i = 0; i < 16; ++i)
4019 {
4020 oss << "# ScalingList4x4[" << +i << "] = ";
4021 oss << +matrixParams->ScalingList4x4[0][i] << " ";
4022 oss << +matrixParams->ScalingList4x4[1][i] << " ";
4023 oss << +matrixParams->ScalingList4x4[2][i] << " ";
4024 oss << +matrixParams->ScalingList4x4[3][i] << " ";
4025 oss << +matrixParams->ScalingList4x4[4][i] << " ";
4026 oss << +matrixParams->ScalingList4x4[5][i] << std::endl;
4027 }
4028
4029 // ScalingList8x8 (2 x 64)
4030 for (uint8_t i = 0; i < 64; ++i)
4031 {
4032 oss << "# ScalingList8x8[0/1][" << +i << "] = " << +matrixParams->ScalingList8x8[0][i] << " / " << +matrixParams->ScalingList8x8[1][i] << std::endl;
4033 }
4034
4035 const char *fileName = m_debugInterface->CreateFileName(
4036 "_DDIEnc",
4037 CodechalDbgBufferType::bufPicParams,
4038 CodechalDbgExtType::txt);
4039
4040 std::ofstream ofs(fileName, std::ios::out);
4041 ofs << oss.str();
4042 ofs.close();
4043
4044 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
4045 {
4046 if (!m_debugInterface->m_ddiFileName.empty())
4047 {
4048 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
4049 ofs << "PicNum"
4050 << " = \"" << m_debugInterface->m_bufferDumpFrameNum << "\"" << std::endl;
4051 ofs << "PicParamFile"
4052 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
4053 ofs.close();
4054 }
4055 }
4056
4057 return MOS_STATUS_SUCCESS;
4058 }
4059
4060
DumpFeiPicParams(CodecEncodeAvcFeiPicParams * feiPicParams)4061 MOS_STATUS CodechalEncodeAvcBase::DumpFeiPicParams(
4062 CodecEncodeAvcFeiPicParams *feiPicParams)
4063 {
4064 CODECHAL_DEBUG_FUNCTION_ENTER;
4065
4066 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrFeiPicParams))
4067 {
4068 return MOS_STATUS_SUCCESS;
4069 }
4070
4071 CODECHAL_DEBUG_CHK_NULL(feiPicParams);
4072
4073 std::ostringstream oss;
4074 oss.setf(std::ios::showbase | std::ios::uppercase);
4075
4076 oss << "# DDI Parameters:" << std::endl;
4077 oss << "SearchPath = " << +feiPicParams->SearchPath << std::endl;
4078 oss << "LenSP = " << +feiPicParams->LenSP << std::endl;
4079 oss << "SubMBPartMask = " << +feiPicParams->SubMBPartMask << std::endl;
4080 oss << "IntraPartMask = " << +feiPicParams->IntraPartMask << std::endl;
4081 oss << "MultiPredL0 = " << +feiPicParams->MultiPredL0 << std::endl;
4082 oss << "MultiPredL1 = " << +feiPicParams->MultiPredL1 << std::endl;
4083 oss << "SubPelMode = " << +feiPicParams->SubPelMode << std::endl;
4084 oss << "InterSAD = " << +feiPicParams->InterSAD << std::endl;
4085 oss << "IntraSAD = " << +feiPicParams->IntraSAD << std::endl;
4086 oss << "NumMVPredictors = " << +feiPicParams->NumMVPredictorsL0 << std::endl;
4087 oss << "NumMVPredictorsL1 = " << +feiPicParams->NumMVPredictorsL1 << std::endl;
4088 oss << "DistortionType = " << +feiPicParams->DistortionType << std::endl;
4089 oss << "DistortionEnable = " << +feiPicParams->DistortionEnable << std::endl;
4090 oss << "RepartitionCheckEnable = " << +feiPicParams->RepartitionCheckEnable << std::endl;
4091 oss << "AdaptiveSearch = " << +feiPicParams->AdaptiveSearch << std::endl;
4092 oss << "MVPredictorEnable = " << +feiPicParams->MVPredictorEnable << std::endl;
4093 oss << "bMBQp = " << +feiPicParams->bMBQp << std::endl;
4094 oss << "bPerMBInput = " << +feiPicParams->bPerMBInput << std::endl;
4095 oss << "bMBSizeCtrl = " << +feiPicParams->bMBSizeCtrl << std::endl;
4096 oss << "RefWidth = " << +feiPicParams->RefWidth << std::endl;
4097 oss << "RefHeight = " << +feiPicParams->RefHeight << std::endl;
4098 oss << "SearchWindow = " << +feiPicParams->SearchWindow << std::endl;
4099
4100 const char *fileName = m_debugInterface->CreateFileName(
4101 "_DDIEnc",
4102 CodechalDbgBufferType::bufFeiPicParams,
4103 CodechalDbgExtType::txt);
4104
4105 std::ofstream ofs(fileName, std::ios::out);
4106 ofs << oss.str();
4107 ofs.close();
4108
4109 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
4110 {
4111 if (!m_debugInterface->m_ddiFileName.empty())
4112 {
4113 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
4114 ofs << "PicNum"
4115 << " = \"" << m_debugInterface->m_bufferDumpFrameNum << "\"" << std::endl;
4116 ofs << "FeiPicParamFile"
4117 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
4118 ofs.close();
4119 }
4120 }
4121
4122 return MOS_STATUS_SUCCESS;
4123 }
4124
DumpSliceParams(PCODEC_AVC_ENCODE_SLICE_PARAMS sliceParams,PCODEC_AVC_ENCODE_PIC_PARAMS picParams)4125 MOS_STATUS CodechalEncodeAvcBase::DumpSliceParams(
4126 PCODEC_AVC_ENCODE_SLICE_PARAMS sliceParams,
4127 PCODEC_AVC_ENCODE_PIC_PARAMS picParams)
4128 {
4129 CODECHAL_DEBUG_FUNCTION_ENTER;
4130
4131 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
4132 {
4133 return MOS_STATUS_SUCCESS;
4134 }
4135
4136 CODECHAL_DEBUG_CHK_NULL(sliceParams);
4137
4138 m_debugInterface->m_sliceId = sliceParams->slice_id; // set here for constructing debug file name
4139
4140 std::ostringstream oss;
4141 oss.setf(std::ios::showbase | std::ios::uppercase);
4142
4143 oss << "# DDI Parameters:" << std::endl;
4144 oss << "NumMbsForSlice = " << +sliceParams->NumMbsForSlice << std::endl;
4145
4146 // RefPicList (2 x 32)
4147 for (uint8_t i = 0; i < 2; ++i)
4148 {
4149 for (uint8_t j = 0; j < 32; ++j)
4150 {
4151 oss << "RefPicList[" << +i << "][" << +j << "] = " << +sliceParams->RefPicList[i][j].PicEntry << std::endl;
4152 }
4153 }
4154
4155 // Conditionally printed (only when picture parameters weighted_pred_flag or weighted_bipred_idc are set).
4156 // Weights contains 192 elements (2 x 32 x 3 x 2).
4157 if (picParams->weighted_pred_flag || picParams->weighted_bipred_idc)
4158 {
4159 for (uint8_t i = 0; i < 2; ++i)
4160 {
4161 for (uint8_t j = 0; j < 32; ++j)
4162 {
4163 for (uint8_t k = 0; k < 3; ++k)
4164 {
4165 for (uint8_t l = 0; l < 2; ++l)
4166 {
4167 oss << "Weights[" << +i << "][" << +j << "][" << +k << "][" << +l << "]: " << +sliceParams->Weights[i][j][k][l] << std::endl;
4168 }
4169 }
4170 }
4171 }
4172 }
4173
4174 oss << "first_mb_in_slice = " << +sliceParams->first_mb_in_slice << std::endl;
4175 oss << "slice_type = " << +sliceParams->slice_type << std::endl;
4176 oss << "pic_parameter_set_id = " << +sliceParams->pic_parameter_set_id << std::endl;
4177 oss << "direct_spatial_mv_pred_flag = " << +sliceParams->direct_spatial_mv_pred_flag << std::endl;
4178 oss << "num_ref_idx_active_override_flag = " << +sliceParams->num_ref_idx_active_override_flag << std::endl;
4179 oss << "long_term_reference_flag = " << +sliceParams->long_term_reference_flag << std::endl;
4180 oss << "idr_pic_id = " << +sliceParams->idr_pic_id << std::endl;
4181 oss << "pic_order_cnt_lsb = " << +sliceParams->pic_order_cnt_lsb << std::endl;
4182 oss << "delta_pic_order_cnt_bottom = " << +sliceParams->delta_pic_order_cnt_bottom << std::endl;
4183 oss << "delta_pic_order_cnt[0] = " << +sliceParams->delta_pic_order_cnt[0] << std::endl;
4184 oss << "delta_pic_order_cnt[1] = " << +sliceParams->delta_pic_order_cnt[1] << std::endl;
4185 oss << "num_ref_idx_l0_active_minus1 = " << +sliceParams->num_ref_idx_l0_active_minus1 << std::endl;
4186 oss << "num_ref_idx_l1_active_minus1 = " << +sliceParams->num_ref_idx_l1_active_minus1 << std::endl;
4187 oss << "luma_log2_weight_denom = " << +sliceParams->luma_log2_weight_denom << std::endl;
4188 oss << "chroma_log2_weight_denom = " << +sliceParams->chroma_log2_weight_denom << std::endl;
4189 oss << "cabac_init_idc = " << +sliceParams->cabac_init_idc << std::endl;
4190 oss << "slice_qp_delta = " << +sliceParams->slice_qp_delta << std::endl;
4191 oss << "disable_deblocking_filter_idc = " << +sliceParams->disable_deblocking_filter_idc << std::endl;
4192 oss << "slice_alpha_c0_offset_div2 = " << +sliceParams->slice_alpha_c0_offset_div2 << std::endl;
4193 oss << "slice_beta_offset_div2 = " << +sliceParams->slice_beta_offset_div2 << std::endl;
4194 oss << "slice_id = " << +sliceParams->slice_id << std::endl;
4195 oss << "luma_weight_flag[0] = " << +sliceParams->luma_weight_flag[0] << std::endl;
4196 oss << "luma_weight_flag[1] = " << +sliceParams->luma_weight_flag[1] << std::endl;
4197 oss << "chroma_weight_flag[0] = " << +sliceParams->chroma_weight_flag[0] << std::endl;
4198 oss << "chroma_weight_flag[1] = " << +sliceParams->chroma_weight_flag[1] << std::endl;
4199
4200 // Parameters not in DDI (Any non-DDI parameters printed should be preceeded by #)
4201 oss << "# Non-DDI Parameters:" << std::endl;
4202
4203 // PicOrder (2 x 32) - Dump in 32 blocks of 2 chunks per line
4204 for (uint16_t i = 0; i < 32; ++i)
4205 {
4206 CODECHAL_DEBUG_CHK_STATUS(DumpEncodePicReorder(
4207 oss,
4208 0,
4209 i,
4210 &(sliceParams->PicOrder[0][i])));
4211 CODECHAL_DEBUG_CHK_STATUS(DumpEncodePicReorder(
4212 oss,
4213 1,
4214 i,
4215 &(sliceParams->PicOrder[1][i])));
4216 }
4217
4218 oss << "# colour_plane_id = " << +sliceParams->colour_plane_id << std::endl;
4219 oss << "# frame_num = " << +sliceParams->frame_num << std::endl;
4220 oss << "# field_pic_flag = " << std::hex << +sliceParams->field_pic_flag << std::endl;
4221 oss << "# bottom_field_flag = " << std::hex << +sliceParams->bottom_field_flag << std::endl;
4222 oss << "# redundant_pic_cnt = " << std::dec << +sliceParams->redundant_pic_cnt << std::endl;
4223 oss << "# sp_for_switch_flag = " << std::hex << +sliceParams->sp_for_switch_flag << std::endl;
4224 oss << "# slice_qs_delta = " << std::dec << +sliceParams->slice_qs_delta << std::endl;
4225 oss << "# ref_pic_list_reordering_flag_l0 = " << std::hex << +sliceParams->ref_pic_list_reordering_flag_l0 << std::endl;
4226 oss << "# ref_pic_list_reordering_flag_l1 = " << std::hex << +sliceParams->ref_pic_list_reordering_flag_l1 << std::endl;
4227 oss << "# no_output_of_prior_pics_flag = " << std::hex << +sliceParams->no_output_of_prior_pics_flag << std::endl;
4228 oss << "# adaptive_ref_pic_marking_mode_flag = " << std::hex << +sliceParams->adaptive_ref_pic_marking_mode_flag << std::endl;
4229 oss << "# MaxFrameNum = " << std::dec << +sliceParams->MaxFrameNum << std::endl;
4230 oss << "# NumReorder = " << std::dec << +sliceParams->NumReorder << std::endl;
4231
4232 const char *fileName = m_debugInterface->CreateFileName(
4233 "_DDIEnc",
4234 CodechalDbgBufferType::bufSlcParams,
4235 CodechalDbgExtType::txt);
4236
4237 std::ofstream ofs(fileName, std::ios::out);
4238 ofs << oss.str();
4239 ofs.close();
4240
4241 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
4242 {
4243 if (!m_debugInterface->m_ddiFileName.empty())
4244 {
4245 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
4246 ofs << "SlcParamFile"
4247 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
4248 ofs.close();
4249 }
4250 }
4251
4252 return MOS_STATUS_SUCCESS;
4253 }
4254
DumpVuiParams(PCODECHAL_ENCODE_AVC_VUI_PARAMS vuiParams)4255 MOS_STATUS CodechalEncodeAvcBase::DumpVuiParams(
4256 PCODECHAL_ENCODE_AVC_VUI_PARAMS vuiParams)
4257 {
4258 CODECHAL_DEBUG_FUNCTION_ENTER;
4259
4260 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrVuiParams))
4261 {
4262 return MOS_STATUS_SUCCESS;
4263 }
4264
4265 CODECHAL_DEBUG_CHK_NULL(vuiParams);
4266
4267 std::ostringstream oss;
4268 oss.setf(std::ios::showbase | std::ios::uppercase);
4269
4270 oss << "# DDI Parameters:" << std::endl;
4271 oss << "aspect_ratio_info_present_flag = " << +vuiParams->aspect_ratio_info_present_flag << std::endl;
4272 oss << "overscan_info_present_flag = " << +vuiParams->overscan_info_present_flag << std::endl;
4273 oss << "overscan_appropriate_flag = " << +vuiParams->overscan_appropriate_flag << std::endl;
4274 oss << "video_signal_type_present_flag = " << +vuiParams->video_signal_type_present_flag << std::endl;
4275 oss << "video_full_range_flag = " << +vuiParams->video_full_range_flag << std::endl;
4276 oss << "colour_description_present_flag = " << +vuiParams->colour_description_present_flag << std::endl;
4277 oss << "chroma_loc_info_present_flag = " << +vuiParams->chroma_loc_info_present_flag << std::endl;
4278 oss << "timing_info_present_flag = " << +vuiParams->timing_info_present_flag << std::endl;
4279 oss << "fixed_frame_rate_flag = " << +vuiParams->fixed_frame_rate_flag << std::endl;
4280 oss << "nal_hrd_parameters_present_flag = " << +vuiParams->nal_hrd_parameters_present_flag << std::endl;
4281 oss << "vcl_hrd_parameters_present_flag = " << +vuiParams->vcl_hrd_parameters_present_flag << std::endl;
4282 oss << "low_delay_hrd_flag = " << +vuiParams->low_delay_hrd_flag << std::endl;
4283 oss << "pic_struct_present_flag = " << +vuiParams->pic_struct_present_flag << std::endl;
4284 oss << "bitstream_restriction_flag = " << +vuiParams->bitstream_restriction_flag << std::endl;
4285 oss << "motion_vectors_over_pic_boundaries_flag = " << +vuiParams->motion_vectors_over_pic_boundaries_flag << std::endl;
4286 oss << "sar_width = " << +vuiParams->sar_width << std::endl;
4287 oss << "sar_height = " << +vuiParams->sar_height << std::endl;
4288 oss << "aspect_ratio_idc = " << +vuiParams->aspect_ratio_idc << std::endl;
4289 oss << "video_format = " << +vuiParams->video_format << std::endl;
4290 oss << "colour_primaries = " << +vuiParams->colour_primaries << std::endl;
4291 oss << "transfer_characteristics = " << +vuiParams->transfer_characteristics << std::endl;
4292 oss << "matrix_coefficients = " << +vuiParams->matrix_coefficients << std::endl;
4293 oss << "chroma_sample_loc_type_top_field = " << +vuiParams->chroma_sample_loc_type_top_field << std::endl;
4294 oss << "chroma_sample_loc_type_bottom_field = " << +vuiParams->chroma_sample_loc_type_bottom_field << std::endl;
4295 oss << "max_bytes_per_pic_denom = " << +vuiParams->max_bytes_per_pic_denom << std::endl;
4296 oss << "max_bits_per_mb_denom = " << +vuiParams->max_bits_per_mb_denom << std::endl;
4297 oss << "log2_max_mv_length_horizontal = " << +vuiParams->log2_max_mv_length_horizontal << std::endl;
4298 oss << "log2_max_mv_length_vertical = " << +vuiParams->log2_max_mv_length_vertical << std::endl;
4299 oss << "num_reorder_frames = " << +vuiParams->num_reorder_frames << std::endl;
4300 oss << "num_units_in_tick = " << +vuiParams->num_units_in_tick << std::endl;
4301 oss << "time_scale = " << +vuiParams->time_scale << std::endl;
4302 oss << "max_dec_frame_buffering = " << +vuiParams->max_dec_frame_buffering << std::endl;
4303 oss << "cpb_cnt_minus1 = " << +vuiParams->cpb_cnt_minus1 << std::endl;
4304 oss << "bit_rate_scale = " << +vuiParams->bit_rate_scale << std::endl;
4305 oss << "cpb_size_scale = " << +vuiParams->cpb_size_scale << std::endl;
4306
4307 // bit_rate_value_minus1 (32 in size)
4308 for (uint8_t i = 0; i < 32; ++i)
4309 {
4310 oss << "bit_rate_value_minus1[" << +i << "] = " << +vuiParams->bit_rate_value_minus1[i] << std::endl;
4311 }
4312
4313 // cpb_size_value_minus1 (32 in size)
4314 for (uint8_t i = 0; i < 32; ++i)
4315 {
4316 oss << "cpb_size_value_minus1[" << +i << "] = " << +vuiParams->cpb_size_value_minus1[i] << std::endl;
4317 }
4318
4319 oss << "cbr_flag = " << +vuiParams->cbr_flag << std::endl;
4320 oss << "initial_cpb_removal_delay_length_minus1 = " << +vuiParams->initial_cpb_removal_delay_length_minus1 << std::endl;
4321 oss << "cpb_removal_delay_length_minus1 = " << +vuiParams->cpb_removal_delay_length_minus1 << std::endl;
4322 oss << "dpb_output_delay_length_minus1 = " << +vuiParams->dpb_output_delay_length_minus1 << std::endl;
4323 oss << "time_offset_length = " << +vuiParams->time_offset_length << std::endl;
4324
4325 const char *fileName = m_debugInterface->CreateFileName(
4326 "_DDIEnc",
4327 CodechalDbgBufferType::bufVuiParams,
4328 CodechalDbgExtType::txt);
4329
4330 std::ofstream ofs(fileName, std::ios::out);
4331 ofs << oss.str();
4332 ofs.close();
4333
4334 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
4335 {
4336 if (!m_debugInterface->m_ddiFileName.empty())
4337 {
4338 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
4339 ofs << "VuiParamFile"
4340 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
4341 ofs.close();
4342 }
4343 }
4344
4345 return MOS_STATUS_SUCCESS;
4346 }
4347
SearchNALHeader(PMHW_VDBOX_AVC_SLICE_STATE sliceState,uint32_t startCode)4348 bool SearchNALHeader(
4349 PMHW_VDBOX_AVC_SLICE_STATE sliceState,
4350 uint32_t startCode)
4351 {
4352 CODECHAL_DEBUG_FUNCTION_ENTER;
4353
4354 for (auto i = 0; i < CODECHAL_ENCODE_AVC_MAX_NAL_TYPE; i++)
4355 {
4356 if (sliceState->ppNalUnitParams[i]->uiSize > 0)
4357 {
4358 uint32_t offset = 0;
4359 uint8_t *dataBase = (uint8_t *)(sliceState->pBsBuffer->pBase + sliceState->ppNalUnitParams[i]->uiOffset);
4360
4361 while (offset < sliceState->ppNalUnitParams[i]->uiSize)
4362 {
4363 uint8_t *dataBuf = dataBase + offset;
4364
4365 if (*dataBuf == 0)
4366 {
4367 uint32_t data = ((*dataBuf) << 24) + ((*(dataBuf + 1)) << 16) + ((*(dataBuf + 2)) << 8) + (*(dataBuf + 3));
4368
4369 if ((data & 0xFFFFFF00) == 0x00000100)
4370 {
4371 if (data == startCode)
4372 {
4373 return true;
4374 }
4375
4376 offset += 4;
4377 }
4378 else
4379 {
4380 offset++;
4381 }
4382 }
4383 else
4384 {
4385 offset++;
4386 }
4387 }
4388 }
4389 }
4390
4391 return false;
4392 }
4393
CreateAvcPar()4394 MOS_STATUS CodechalEncodeAvcBase::CreateAvcPar()
4395 {
4396 CODECHAL_DEBUG_FUNCTION_ENTER;
4397
4398 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
4399
4400 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
4401 {
4402 CODECHAL_DEBUG_CHK_NULL(m_avcPar = MOS_New(EncodeAvcPar));
4403 MOS_ZeroMemory(m_avcPar, sizeof(EncodeAvcPar));
4404 }
4405
4406 return MOS_STATUS_SUCCESS;
4407 }
4408
DestroyAvcPar()4409 MOS_STATUS CodechalEncodeAvcBase::DestroyAvcPar()
4410 {
4411 CODECHAL_DEBUG_FUNCTION_ENTER;
4412
4413 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSeqParFile());
4414 MOS_Delete(m_avcPar);
4415
4416 return MOS_STATUS_SUCCESS;
4417 }
4418
PopulateConstParam()4419 MOS_STATUS CodechalEncodeAvcBase::PopulateConstParam()
4420 {
4421 CODECHAL_DEBUG_FUNCTION_ENTER;
4422
4423 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
4424
4425 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
4426 {
4427 return MOS_STATUS_SUCCESS;
4428 }
4429
4430 if (m_encodeParState->m_isConstDumped)
4431 {
4432 return MOS_STATUS_SUCCESS;
4433 }
4434
4435 CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateTargetUsage());
4436
4437 std::ostringstream oss;
4438 oss.setf(std::ios::showbase | std::ios::uppercase);
4439
4440 // Constant
4441 oss << "EnableStatistics = 0" << std::endl;
4442 oss << "KernelDumpEnable = 16" << std::endl;
4443 oss << "Kernel = 1" << std::endl;
4444 oss << "StartMB = -1" << std::endl;
4445 oss << "EndMB = -1" << std::endl;
4446 oss << "GOPMode = 0" << std::endl;
4447 oss << "BoxFilter = 1" << std::endl;
4448 oss << "EnableBpyramid = 0" << std::endl;
4449 oss << "EnableIPCM = 1" << std::endl;
4450 oss << "EnableMVUnpacked = 1" << std::endl;
4451 oss << "EnableNewModeCost = 1" << std::endl;
4452 oss << "EnablePAFF = 0" << std::endl;
4453 oss << "EnableSkip = 3" << std::endl;
4454 oss << "EnableSkipBiasAdjustment = 1" << std::endl;
4455 oss << "HierarchicalMEFlag = 3" << std::endl;
4456 oss << "NumRefStartB = 1" << std::endl;
4457 oss << "PAFFThreshold = 10000" << std::endl;
4458 oss << "PicScalingList = 0" << std::endl;
4459 oss << "SeqScalingList = 0" << std::endl;
4460 oss << "SkipChromaCBPDetection = 1" << std::endl;
4461 oss << "IdrInterval = 0" << std::endl;
4462 oss << "AddEoSquenceNAL = 1" << std::endl;
4463 oss << "AddEoStreamNAL = 1" << std::endl;
4464 oss << "CabacZeroWordFlag = 0" << std::endl;
4465 oss << "EncodeFrameSizeTolerance = 0" << std::endl;
4466 oss << "ForceIntraDC = 0" << std::endl;
4467 oss << "HMECoarseShape = 2" << std::endl;
4468 oss << "HMESubPelMode = 3" << std::endl;
4469 oss << "IntraDirectionBias = 1" << std::endl;
4470 oss << "InterSADMeasure = 2" << std::endl;
4471 oss << "IntraSADMeasure = 2" << std::endl;
4472 oss << "CostingFeature = 3" << std::endl;
4473 oss << "CostingType = 1" << std::endl;
4474 oss << "ModeCosting = 1" << std::endl;
4475 oss << "HighQPMvCostEnable = 1" << std::endl;
4476 oss << "HighQPHMECostEnable = 1" << std::endl;
4477 oss << "RefIDCostMode = 0" << std::endl;
4478 oss << "EnableAdaptiveLambdaOffset = 1" << std::endl;
4479
4480 m_encodeParState->m_isConstDumped = true;
4481
4482 const char *fileName = m_debugInterface->CreateFileName(
4483 "EncodeSequence",
4484 "EncodePar",
4485 CodechalDbgExtType::par);
4486
4487 std::ofstream ofs(fileName, std::ios::app);
4488 ofs << oss.str();
4489 ofs.close();
4490
4491 return MOS_STATUS_SUCCESS;
4492 }
4493
PopulateTargetUsage()4494 MOS_STATUS CodechalEncodeAvcBase::PopulateTargetUsage()
4495 {
4496 CODECHAL_DEBUG_FUNCTION_ENTER;
4497
4498 if (m_populateTargetUsage == false)
4499 {
4500 return MOS_STATUS_SUCCESS;
4501 }
4502
4503 const char *fileName = m_debugInterface->CreateFileName(
4504 "EncodeSequence",
4505 "EncodePar",
4506 CodechalDbgExtType::par);
4507
4508 std::ifstream ifs(fileName);
4509 std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
4510 ifs.close();
4511 std::ofstream ofs(fileName, std::ios::trunc);
4512 ofs << "TargetUsage = " << static_cast<uint32_t>(m_avcSeqParam->TargetUsage) << std::endl;
4513 ofs << str;
4514 ofs.close();
4515
4516 return MOS_STATUS_SUCCESS;
4517 }
4518
PopulateDdiParam(PCODEC_AVC_ENCODE_SEQUENCE_PARAMS avcSeqParams,PCODEC_AVC_ENCODE_PIC_PARAMS avcPicParams,PCODEC_AVC_ENCODE_SLICE_PARAMS avcSlcParams)4519 MOS_STATUS CodechalEncodeAvcBase::PopulateDdiParam(
4520 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS avcSeqParams,
4521 PCODEC_AVC_ENCODE_PIC_PARAMS avcPicParams,
4522 PCODEC_AVC_ENCODE_SLICE_PARAMS avcSlcParams)
4523 {
4524 CODECHAL_DEBUG_FUNCTION_ENTER;
4525
4526 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
4527
4528 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
4529 {
4530 return MOS_STATUS_SUCCESS;
4531 }
4532
4533 if (Slice_Type[avcSlcParams->slice_type] == SLICE_I || Slice_Type[avcSlcParams->slice_type] == SLICE_SI)
4534 {
4535 m_avcPar->ProfileIDC = avcSeqParams->Profile;
4536 m_avcPar->LevelIDC = avcSeqParams->Level;
4537 m_avcPar->DisableVUIHeader = !avcSeqParams->vui_parameters_present_flag;
4538 m_avcPar->ChromaFormatIDC = avcSeqParams->chroma_format_idc;
4539 m_avcPar->ChromaQpOffset = avcPicParams->chroma_qp_index_offset;
4540 m_avcPar->SecondChromaQpOffset = avcPicParams->second_chroma_qp_index_offset;
4541
4542 uint8_t pictureCodingType = CodecHal_PictureIsFrame(avcPicParams->CurrOriginalPic) ? 0 : (CodecHal_PictureIsTopField(avcPicParams->CurrOriginalPic) ? 1 : 3);
4543 m_avcPar->PictureCodingType = pictureCodingType;
4544
4545 uint16_t gopP = (avcSeqParams->GopRefDist) ? ((avcSeqParams->GopPicSize - 1) / avcSeqParams->GopRefDist) : 0;
4546 uint16_t gopB = avcSeqParams->GopPicSize - 1 - gopP;
4547 m_avcPar->NumP = gopP;
4548 m_avcPar->NumB = ((gopP > 0) ? (gopB / gopP) : 0);
4549
4550 if ((avcPicParams->NumSlice * m_sliceHeight) >=
4551 (uint32_t)(avcSeqParams->pic_height_in_map_units_minus1 + 1 + m_sliceHeight))
4552 {
4553 m_avcPar->NumSlices = avcPicParams->NumSlice - 1;
4554 }
4555 else
4556 {
4557 m_avcPar->NumSlices = avcPicParams->NumSlice;
4558 }
4559 m_avcPar->SliceHeight = m_sliceHeight;
4560
4561 m_avcPar->NumSuperSlices = m_avcPar->NumSlices;
4562 if (m_avcPar->NumSuperSlices)
4563 {
4564 uint32_t sliceIdx = 0;
4565 for (; sliceIdx < m_avcPar->NumSuperSlices - 1; sliceIdx++)
4566 {
4567 m_avcPar->SuperSliceHeight[sliceIdx] = m_sliceHeight;
4568 }
4569 m_avcPar->SuperSliceHeight[sliceIdx] = avcSeqParams->pic_height_in_map_units_minus1 + 1 - sliceIdx * m_sliceHeight;
4570 }
4571
4572 m_avcPar->ISliceQP = avcPicParams->QpY + avcSlcParams->slice_qp_delta;
4573 m_avcPar->FrameRateM = ((avcSeqParams->FramesPer100Sec % 100) == 0) ? (avcSeqParams->FramesPer100Sec / 100) : avcSeqParams->FramesPer100Sec;
4574 m_avcPar->FrameRateD = ((avcSeqParams->FramesPer100Sec % 100) == 0) ? 1 : 100;
4575
4576 uint8_t brcMethod = 0;
4577 uint8_t brcType = 0;
4578
4579 if (CodecHalIsRateControlBrc(avcSeqParams->RateControlMethod, CODECHAL_AVC))
4580 {
4581 brcMethod = 2;
4582
4583 switch (avcSeqParams->RateControlMethod)
4584 {
4585 case RATECONTROL_ICQ:
4586 brcMethod = m_vdencEnabled ? 2 : 3;
4587 brcType = 16;
4588 break;
4589 case RATECONTROL_QVBR:
4590 brcMethod = m_vdencEnabled ? 2 : 4;
4591 brcType = 2;
4592 break;
4593 case RATECONTROL_CBR:
4594 brcType = 1;
4595 break;
4596 case RATECONTROL_VBR:
4597 brcType = 2;
4598 break;
4599 case RATECONTROL_VCM:
4600 brcType = m_vdencEnabled ? 4 : 3;
4601 break;
4602 default:
4603 brcMethod = 0;
4604 brcType = 0;
4605 break;
4606 }
4607
4608 if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW)
4609 {
4610 // low delay mode
4611 brcType = 8;
4612 }
4613 }
4614
4615 m_avcPar->BRCMethod = brcMethod;
4616 m_avcPar->BRCType = brcType;
4617
4618 m_avcPar->DeblockingIDC = avcSlcParams->disable_deblocking_filter_idc;
4619 m_avcPar->DeblockingFilterAlpha = avcSlcParams->slice_alpha_c0_offset_div2 << 1;
4620 m_avcPar->DeblockingFilterBeta = avcSlcParams->slice_beta_offset_div2 << 1;
4621 m_avcPar->EntropyCodingMode = avcPicParams->entropy_coding_mode_flag;
4622 m_avcPar->DirectInference = avcSeqParams->direct_8x8_inference_flag;
4623 m_avcPar->Transform8x8Mode = avcPicParams->transform_8x8_mode_flag;
4624 m_avcPar->CRFQualityFactor = avcSeqParams->ICQQualityFactor;
4625 m_avcPar->ConstrainedIntraPred = avcPicParams->constrained_intra_pred_flag;
4626
4627 // This is only for header matching although I frame doesn't have references
4628 if (avcSlcParams->num_ref_idx_active_override_flag)
4629 {
4630 m_avcPar->MaxRefIdxL0 = MOS_MAX(m_avcPar->MaxRefIdxL0, avcSlcParams->num_ref_idx_l0_active_minus1);
4631 m_avcPar->MaxRefIdxL1 = MOS_MAX(m_avcPar->MaxRefIdxL1, avcSlcParams->num_ref_idx_l1_active_minus1);
4632 }
4633 else
4634 {
4635 m_avcPar->MaxRefIdxL0 = MOS_MAX(m_avcPar->MaxRefIdxL0, avcPicParams->num_ref_idx_l0_active_minus1);
4636 m_avcPar->MaxRefIdxL1 = MOS_MAX(m_avcPar->MaxRefIdxL1, avcPicParams->num_ref_idx_l1_active_minus1);
4637 }
4638
4639 if (m_vdencEnabled)
4640 {
4641 m_avcPar->SliceMode = avcSeqParams->EnableSliceLevelRateCtrl ? 2 : 0;
4642 }
4643 }
4644 else if (Slice_Type[avcSlcParams->slice_type] == SLICE_P || Slice_Type[avcSlcParams->slice_type] == SLICE_SP)
4645 {
4646 m_avcPar->PSliceQP = avcPicParams->QpY + avcSlcParams->slice_qp_delta;
4647 m_avcPar->CabacInitIDC = avcSlcParams->cabac_init_idc;
4648
4649 if (avcSlcParams->num_ref_idx_active_override_flag)
4650 {
4651 m_avcPar->MaxRefIdxL0 = MOS_MAX(m_avcPar->MaxRefIdxL0, avcSlcParams->num_ref_idx_l0_active_minus1);
4652 m_avcPar->MaxRefIdxL1 = MOS_MAX(m_avcPar->MaxRefIdxL1, avcSlcParams->num_ref_idx_l1_active_minus1);
4653 }
4654 else
4655 {
4656 m_avcPar->MaxRefIdxL0 = MOS_MAX(m_avcPar->MaxRefIdxL0, avcPicParams->num_ref_idx_l0_active_minus1);
4657 m_avcPar->MaxRefIdxL1 = MOS_MAX(m_avcPar->MaxRefIdxL1, avcPicParams->num_ref_idx_l1_active_minus1);
4658 }
4659
4660 if (m_avcPar->NumB == 0) // There's no B frame
4661 {
4662 m_avcPar->EnableWeightPredictionDetection = avcPicParams->weighted_pred_flag > 0 ? 1 : 0;
4663 }
4664 m_avcPar->WeightedPred = avcPicParams->weighted_pred_flag;
4665 m_avcPar->UseOrigAsRef = avcPicParams->UserFlags.bUseRawPicForRef;
4666 m_avcPar->BiSubMbPartMask = avcPicParams->UserFlags.bDisableSubMBPartition ? (bool)(CODECHAL_ENCODE_AVC_DISABLE_4X4_SUB_MB_PARTITION | CODECHAL_ENCODE_AVC_DISABLE_4X8_SUB_MB_PARTITION | CODECHAL_ENCODE_AVC_DISABLE_8X4_SUB_MB_PARTITION) : 0;
4667
4668 if (m_vdencEnabled)
4669 {
4670 if (m_targetUsage == 1 || m_targetUsage == 2)
4671 {
4672 m_avcPar->StaticFrameZMVPercent = avcPicParams->dwZMvThreshold;
4673 }
4674 else
4675 {
4676 m_avcPar->StaticFrameZMVPercent = 100;
4677 }
4678
4679 if (avcPicParams->bEnableHMEOffset)
4680 {
4681 m_avcPar->hme0XOffset = MOS_CLAMP_MIN_MAX(avcPicParams->HMEOffset[0][0][0], -128, 127);
4682 m_avcPar->hme0YOffset = MOS_CLAMP_MIN_MAX(avcPicParams->HMEOffset[0][0][1], -128, 127);
4683 m_avcPar->hme1XOffset = MOS_CLAMP_MIN_MAX(avcPicParams->HMEOffset[1][0][0], -128, 127);
4684 m_avcPar->hme1YOffset = MOS_CLAMP_MIN_MAX(avcPicParams->HMEOffset[1][0][1], -128, 127);
4685 }
4686 }
4687 }
4688 else if (Slice_Type[avcSlcParams->slice_type] == SLICE_B)
4689 {
4690 m_avcPar->BSliceQP = avcPicParams->QpY + avcSlcParams->slice_qp_delta;
4691
4692 if (avcSlcParams->num_ref_idx_active_override_flag)
4693 {
4694 m_avcPar->MaxBRefIdxL0 = MOS_MAX(m_avcPar->MaxBRefIdxL0, avcSlcParams->num_ref_idx_l0_active_minus1);
4695 }
4696 else
4697 {
4698 m_avcPar->MaxBRefIdxL0 = MOS_MAX(m_avcPar->MaxBRefIdxL0, avcPicParams->num_ref_idx_l0_active_minus1);
4699 }
4700
4701 m_avcPar->EnableWeightPredictionDetection = (avcPicParams->weighted_bipred_idc | avcPicParams->weighted_pred_flag) > 0 ? 1 : 0;
4702 m_avcPar->WeightedBiPred = avcPicParams->weighted_bipred_idc;
4703 m_avcPar->BiWeight = m_biWeight;
4704 }
4705
4706 return MOS_STATUS_SUCCESS;
4707 }
4708
PopulateSliceStateParam(bool adaptiveRoundingInterEnable,PMHW_VDBOX_AVC_SLICE_STATE sliceState)4709 MOS_STATUS CodechalEncodeAvcBase::PopulateSliceStateParam(
4710 bool adaptiveRoundingInterEnable,
4711 PMHW_VDBOX_AVC_SLICE_STATE sliceState)
4712 {
4713 CODECHAL_DEBUG_FUNCTION_ENTER;
4714
4715 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
4716
4717 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
4718 {
4719 return MOS_STATUS_SUCCESS;
4720 }
4721
4722 if (m_pictureCodingType == I_TYPE)
4723 {
4724 m_avcPar->RoundingIntraEnabled = true;
4725 m_avcPar->RoundingIntra = 5;
4726 // Set to 1 first, we don't consider 0 case as we only dump I frame param once
4727 m_avcPar->FrmHdrEncodingFrequency = 1; // 1: picture header in every IDR frame
4728
4729 // Search SEI NAL
4730 m_avcPar->EnableSEI = SearchNALHeader(sliceState, CODECHAL_DEBUG_ENCODE_AVC_NAL_START_CODE_SEI);
4731 }
4732 else if (m_pictureCodingType == P_TYPE)
4733 {
4734 m_avcPar->EnableAdaptiveRounding = adaptiveRoundingInterEnable;
4735 m_avcPar->RoundingInterEnabled = sliceState->bRoundingInterEnable;
4736 m_avcPar->RoundingInter = sliceState->dwRoundingValue;
4737
4738 // Search PPS NAL
4739 m_avcPar->FrmHdrEncodingFrequency =
4740 SearchNALHeader(sliceState, CODECHAL_DEBUG_ENCODE_AVC_NAL_START_CODE_PPS) ? 2 : m_avcPar->FrmHdrEncodingFrequency;
4741 }
4742 else if (m_pictureCodingType == B_TYPE)
4743 {
4744 m_avcPar->RoundingInterB = sliceState->dwRoundingValue;
4745 }
4746
4747 return MOS_STATUS_SUCCESS;
4748 }
4749
PopulateSfdParam(void * cmd)4750 MOS_STATUS CodechalEncodeAvcBase::PopulateSfdParam(
4751 void *cmd)
4752 {
4753 CODECHAL_DEBUG_FUNCTION_ENTER;
4754
4755 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
4756
4757 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
4758 {
4759 return MOS_STATUS_SUCCESS;
4760 }
4761
4762 CODECHAL_ENCODE_AVC_SFD_CURBE_COMMON *curbe = (CODECHAL_ENCODE_AVC_SFD_CURBE_COMMON *)cmd;
4763
4764 if (m_pictureCodingType == P_TYPE)
4765 {
4766 m_avcPar->EnableIntraCostScalingForStaticFrame = curbe->DW0.EnableIntraCostScalingForStaticFrame;
4767 m_avcPar->StaticFrameIntraCostScalingRatioP = 240;
4768 m_avcPar->AdaptiveMvStreamIn = curbe->DW0.EnableAdaptiveMvStreamIn;
4769 m_avcPar->LargeMvThresh = curbe->DW3.LargeMvThresh;
4770 m_avcPar->LargeMvPctThreshold = 1;
4771 }
4772
4773 return MOS_STATUS_SUCCESS;
4774 }
4775 #endif
4776
SetFrameStoreIds(uint8_t frameIdx)4777 MOS_STATUS CodechalEncodeAvcBase::SetFrameStoreIds(uint8_t frameIdx)
4778 {
4779 uint8_t invalidFrame = (m_mode == CODECHAL_DECODE_MODE_AVCVLD) ? 0x7f : 0x1f;
4780
4781 for (uint8_t i = 0; i < m_refList[frameIdx]->ucNumRef; i++)
4782 {
4783 uint8_t index;
4784 index = m_refList[frameIdx]->RefList[i].FrameIdx;
4785 if (m_refList[index]->ucFrameId == invalidFrame)
4786 {
4787 uint8_t j;
4788 for (j = 0; j < CODEC_AVC_MAX_NUM_REF_FRAME; j++)
4789 {
4790 if (!m_avcFrameStoreID[j].inUse)
4791 {
4792 m_refList[index]->ucFrameId = j;
4793 m_avcFrameStoreID[j].inUse = true;
4794 break;
4795 }
4796 }
4797 if (j == CODEC_AVC_MAX_NUM_REF_FRAME)
4798 {
4799 // should never happen, something must be wrong
4800 CODECHAL_PUBLIC_ASSERT(false);
4801 m_refList[index]->ucFrameId = 0;
4802 m_avcFrameStoreID[0].inUse = true;
4803 }
4804 }
4805 }
4806 return MOS_STATUS_SUCCESS;
4807 }
4808
AddMfxAvcSlice(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_SLICE_STATE avcSliceState)4809 MOS_STATUS CodechalEncodeAvcBase::AddMfxAvcSlice(
4810 PMOS_COMMAND_BUFFER cmdBuffer,
4811 PMHW_BATCH_BUFFER batchBuffer,
4812 PMHW_VDBOX_AVC_SLICE_STATE avcSliceState)
4813 {
4814 CODECHAL_ENCODE_FUNCTION_ENTER;
4815
4816 CODECHAL_ENCODE_CHK_NULL_RETURN(m_mfxInterface);
4817 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcSlice(cmdBuffer, batchBuffer, avcSliceState));
4818
4819 return MOS_STATUS_SUCCESS;
4820 }
4821
AddVdencSliceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_AVC_SLICE_STATE params)4822 MOS_STATUS CodechalEncodeAvcBase::AddVdencSliceStateCmd(
4823 PMOS_COMMAND_BUFFER cmdBuffer,
4824 PMHW_VDBOX_AVC_SLICE_STATE params)
4825 {
4826 CODECHAL_ENCODE_FUNCTION_ENTER;
4827
4828 CODECHAL_ENCODE_CHK_NULL_RETURN(m_vdencInterface);
4829 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencSliceStateCmd(cmdBuffer, params));
4830
4831 return MOS_STATUS_SUCCESS;
4832 }
GetStatusReport(EncodeStatus * encodeStatus,EncodeStatusReport * encodeStatusReport)4833 MOS_STATUS CodechalEncodeAvcBase::GetStatusReport(
4834 EncodeStatus* encodeStatus,
4835 EncodeStatusReport* encodeStatusReport)
4836 {
4837 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4838
4839 encodeStatusReport->CodecStatus = CODECHAL_STATUS_SUCCESSFUL;
4840 encodeStatusReport->bitstreamSize =
4841 encodeStatus->dwMFCBitstreamByteCountPerFrame + encodeStatus->dwHeaderBytesInserted;
4842
4843 // dwHeaderBytesInserted is for WAAVCSWHeaderInsertion
4844 // and is 0 otherwise
4845 encodeStatusReport->QpY = encodeStatus->BrcQPReport.DW0.QPPrimeY;
4846 encodeStatusReport->SuggestedQpYDelta =
4847 encodeStatus->ImageStatusCtrl.CumulativeSliceDeltaQP;
4848 encodeStatusReport->NumberPasses = (uint8_t)encodeStatus->dwNumberPasses;
4849 ENCODE_VERBOSEMESSAGE("statusReportData->numberPasses: %d\n", encodeStatusReport->NumberPasses);
4850 encodeStatusReport->SceneChangeDetected =
4851 (encodeStatus->dwSceneChangedFlag & CODECHAL_ENCODE_SCENE_CHANGE_DETECTED_MASK) ? 1 : 0;
4852
4853 CODECHAL_ENCODE_CHK_NULL_RETURN(m_skuTable);
4854
4855 if (m_picWidthInMb != 0 && m_frameFieldHeightInMb != 0)
4856 {
4857 encodeStatusReport->AverageQp = (unsigned char)(((uint32_t)encodeStatus->QpStatusCount.cumulativeQP) / (m_picWidthInMb * m_frameFieldHeightInMb));
4858 }
4859 encodeStatusReport->PanicMode = encodeStatus->ImageStatusCtrl.Panic;
4860
4861 // If Num slices is greater than spec limit set NumSlicesNonCompliant to 1 and report error
4862 PMHW_VDBOX_PAK_NUM_OF_SLICES numSlices = &encodeStatus->NumSlices;
4863 if (numSlices->NumberOfSlices > m_maxNumSlicesAllowed)
4864 {
4865 encodeStatusReport->NumSlicesNonCompliant = 1;
4866 }
4867 encodeStatusReport->NumberSlices = numSlices->NumberOfSlices;
4868
4869 return eStatus;
4870 }