1 /*
2 * Copyright (c) 2017-2019, 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(m_mfxInterface->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(m_vdencInterface->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
1252 //!
1253 //! \brief Pack AUD parameters
1254 //!
1255 //! \param [in] params
1256 //! Pointer to codechal encode Avc pack picture header parameter
1257 //!
1258 //! \return MOS_STATUS
1259 //! Return MOS_STATUS_SUCCESS if call success, else fail reason
1260 //!
CodecHal_PackPictureHeader_AUDParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)1261 MOS_STATUS CodecHal_PackPictureHeader_AUDParams(
1262 PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
1263 {
1264 uint32_t picType;
1265 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1266
1267 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1268 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1269
1270 // refer table 7-5 in H.264 spec on primary_pic_type
1271 // Here I,P,B types are included
1272 // According BD Spec 9.5.1.1, 0 - I; 1 - P; 2 - B
1273
1274 picType = (uint32_t)(params->wPictureCodingType) - 1;
1275 PutBits(params->pBsBuffer, picType, 3);
1276
1277 return eStatus;
1278 }
1279
1280 // Refer to H264 picture reordering session
CodecHal_PackSliceHeader_RefPicListReordering(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)1281 static MOS_STATUS CodecHal_PackSliceHeader_RefPicListReordering(
1282 PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
1283 {
1284 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
1285 PBSBuffer bsbuffer;
1286 CODEC_PIC_REORDER * picOrder;
1287 uint8_t sliceType;
1288 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1289
1290 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1291 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
1292
1293 slcParams = params->pAvcSliceParams;
1294 bsbuffer = params->pBsBuffer;
1295 sliceType = Slice_Type[slcParams->slice_type];
1296
1297 // Generate the initial reference list
1298 CodecHal_PackSliceHeader_SetInitialRefPicList(params);
1299
1300 if (sliceType != SLICE_I && sliceType != SLICE_SI)
1301 {
1302 if (slcParams->ref_pic_list_reordering_flag_l0)
1303 {
1304 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackSliceHeader_SetRefPicListParam(params, 0));
1305
1306 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l0);
1307
1308 if (slcParams->ref_pic_list_reordering_flag_l0)
1309 {
1310 picOrder = &slcParams->PicOrder[0][0];
1311 do
1312 {
1313 PutVLCCode(bsbuffer, picOrder->ReorderPicNumIDC);
1314 if (picOrder->ReorderPicNumIDC == 0 ||
1315 picOrder->ReorderPicNumIDC == 1)
1316 {
1317 PutVLCCode(bsbuffer, picOrder->DiffPicNumMinus1);
1318 }
1319 } while ((picOrder++)->ReorderPicNumIDC != 3);
1320 }
1321 }
1322 else
1323 {
1324 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l0);
1325 }
1326 }
1327 if (sliceType == SLICE_B)
1328 {
1329 if (slcParams->ref_pic_list_reordering_flag_l1)
1330 {
1331 CodecHal_PackSliceHeader_SetRefPicListParam(params, 1);
1332
1333 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l1);
1334
1335 if (slcParams->ref_pic_list_reordering_flag_l1)
1336 {
1337 picOrder = &slcParams->PicOrder[1][0];
1338 do
1339 {
1340 PutVLCCode(bsbuffer, picOrder->ReorderPicNumIDC);
1341 if (picOrder->ReorderPicNumIDC == 0 ||
1342 picOrder->ReorderPicNumIDC == 1)
1343 {
1344 PutVLCCode(bsbuffer, picOrder->DiffPicNumMinus1);
1345 }
1346 } while ((picOrder++)->ReorderPicNumIDC != 3);
1347 }
1348 }
1349 else
1350 {
1351 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l1);
1352 }
1353 }
1354
1355 return eStatus;
1356 }
1357
1358 //!
1359 //! \brief Pack sequence parameters
1360 //!
1361 //! \param [in] params
1362 //! Pointer to codechal encode Avc pack picture header parameter
1363 //!
1364 //! \return MOS_STATUS
1365 //! Return MOS_STATUS_SUCCESS if call success, else fail reason
1366 //!
CodecHal_PackPictureHeader_SeqParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)1367 MOS_STATUS CodecHal_PackPictureHeader_SeqParams(
1368 PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
1369 {
1370 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams;
1371 BSBuffer * bsbuffer;
1372 uint8_t i;
1373 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1374
1375 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1376 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1377 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
1378
1379 seqParams = params->pSeqParams;
1380 bsbuffer = params->pBsBuffer;
1381
1382 PutBits(bsbuffer, seqParams->Profile, 8);
1383
1384 PutBit(bsbuffer, seqParams->constraint_set0_flag);
1385 PutBit(bsbuffer, seqParams->constraint_set1_flag);
1386 PutBit(bsbuffer, seqParams->constraint_set2_flag);
1387 PutBit(bsbuffer, seqParams->constraint_set3_flag);
1388
1389 PutBits(bsbuffer, 0, 4);
1390 PutBits(bsbuffer, seqParams->Level, 8);
1391 PutVLCCode(bsbuffer, seqParams->seq_parameter_set_id);
1392
1393 if (seqParams->Profile == CODEC_AVC_HIGH_PROFILE ||
1394 seqParams->Profile == CODEC_AVC_HIGH10_PROFILE ||
1395 seqParams->Profile == CODEC_AVC_HIGH422_PROFILE ||
1396 seqParams->Profile == CODEC_AVC_HIGH444_PROFILE ||
1397 seqParams->Profile == CODEC_AVC_CAVLC444_INTRA_PROFILE ||
1398 seqParams->Profile == CODEC_AVC_SCALABLE_BASE_PROFILE ||
1399 seqParams->Profile == CODEC_AVC_SCALABLE_HIGH_PROFILE)
1400 {
1401 PutVLCCode(bsbuffer, seqParams->chroma_format_idc);
1402 if (seqParams->chroma_format_idc == 3)
1403 {
1404 PutBit(bsbuffer, seqParams->separate_colour_plane_flag);
1405 }
1406 PutVLCCode(bsbuffer, seqParams->bit_depth_luma_minus8);
1407 PutVLCCode(bsbuffer, seqParams->bit_depth_chroma_minus8);
1408 PutBit(bsbuffer, seqParams->qpprime_y_zero_transform_bypass_flag);
1409 PutBit(bsbuffer, seqParams->seq_scaling_matrix_present_flag);
1410 if (seqParams->seq_scaling_matrix_present_flag)
1411 {
1412 //Iterate thro' the scaling lists. Refer to ITU-T H.264 std. section 7.3.2.1
1413 for (i = 0; i < 8; i++)
1414 {
1415 // scaling list present flag
1416 PutBit(bsbuffer, seqParams->seq_scaling_list_present_flag[i]);
1417 if (seqParams->seq_scaling_list_present_flag[i])
1418 {
1419 if (i < 6)
1420 {
1421 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList4x4[i][0], 16);
1422 }
1423 else
1424 {
1425 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList8x8[i - 6][0], 64);
1426 }
1427 }
1428 }
1429 }
1430 }
1431
1432 PutVLCCode(bsbuffer, seqParams->log2_max_frame_num_minus4);
1433 PutVLCCode(bsbuffer, seqParams->pic_order_cnt_type);
1434 if (seqParams->pic_order_cnt_type == 0)
1435 {
1436 PutVLCCode(bsbuffer, seqParams->log2_max_pic_order_cnt_lsb_minus4);
1437 }
1438 else if (seqParams->pic_order_cnt_type == 1)
1439 {
1440 PutBit(bsbuffer, seqParams->delta_pic_order_always_zero_flag);
1441 PutVLCCode(bsbuffer, SIGNED(seqParams->offset_for_non_ref_pic));
1442 PutVLCCode(bsbuffer, SIGNED(seqParams->offset_for_top_to_bottom_field));
1443 PutVLCCode(bsbuffer, seqParams->num_ref_frames_in_pic_order_cnt_cycle);
1444 for (i = 0; i < seqParams->num_ref_frames_in_pic_order_cnt_cycle; i++)
1445 {
1446 PutVLCCode(bsbuffer, SIGNED(seqParams->offset_for_ref_frame[i]));
1447 }
1448 }
1449
1450 PutVLCCode(bsbuffer, seqParams->NumRefFrames);
1451 PutBit(bsbuffer, seqParams->gaps_in_frame_num_value_allowed_flag);
1452 PutVLCCode(bsbuffer, seqParams->pic_width_in_mbs_minus1);
1453 PutVLCCode(bsbuffer, seqParams->pic_height_in_map_units_minus1);
1454 PutBit(bsbuffer, seqParams->frame_mbs_only_flag);
1455
1456 if (!seqParams->frame_mbs_only_flag)
1457 {
1458 PutBit(bsbuffer, seqParams->mb_adaptive_frame_field_flag);
1459 }
1460
1461 PutBit(bsbuffer, seqParams->direct_8x8_inference_flag);
1462
1463 if ((!seqParams->frame_cropping_flag) &&
1464 (params->dwFrameHeight != params->dwOriFrameHeight))
1465 {
1466 seqParams->frame_cropping_flag = 1;
1467 seqParams->frame_crop_bottom_offset =
1468 (int16_t)((params->dwFrameHeight - params->dwOriFrameHeight) >>
1469 (2 - seqParams->frame_mbs_only_flag)); // 4:2:0
1470 }
1471
1472 PutBit(bsbuffer, seqParams->frame_cropping_flag);
1473
1474 if (seqParams->frame_cropping_flag)
1475 {
1476 PutVLCCode(bsbuffer, seqParams->frame_crop_left_offset);
1477 PutVLCCode(bsbuffer, seqParams->frame_crop_right_offset);
1478 PutVLCCode(bsbuffer, seqParams->frame_crop_top_offset);
1479 PutVLCCode(bsbuffer, seqParams->frame_crop_bottom_offset);
1480 }
1481
1482 PutBit(bsbuffer, seqParams->vui_parameters_present_flag);
1483
1484 if (seqParams->vui_parameters_present_flag)
1485 {
1486 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackPictureHeader_VuiParams(params));
1487 }
1488
1489 *params->pbNewSeqHeader = 1;
1490
1491 return eStatus;
1492 }
1493
1494 //!
1495 //! \brief Pack picture parameters
1496 //!
1497 //! \param [in] params
1498 //! Pointer to codechal encode Avc pack picture header parameter
1499 //!
1500 //! \return MOS_STATUS
1501 //! Return MOS_STATUS_SUCCESS if call success, else fail reason
1502 //!
CodecHal_PackPictureHeader_PicParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)1503 MOS_STATUS CodecHal_PackPictureHeader_PicParams(
1504 PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
1505 {
1506 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams;
1507 PCODEC_AVC_ENCODE_PIC_PARAMS picParams;
1508 PBSBuffer bsbuffer;
1509 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1510
1511 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1512 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
1513 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pPicParams);
1514 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1515
1516 seqParams = params->pSeqParams;
1517 picParams = params->pPicParams;
1518 bsbuffer = params->pBsBuffer;
1519
1520 PutVLCCode(bsbuffer, picParams->pic_parameter_set_id);
1521 PutVLCCode(bsbuffer, picParams->seq_parameter_set_id);
1522
1523 PutBit(bsbuffer, picParams->entropy_coding_mode_flag);
1524 PutBit(bsbuffer, picParams->pic_order_present_flag);
1525
1526 PutVLCCode(bsbuffer, picParams->num_slice_groups_minus1);
1527
1528 PutVLCCode(bsbuffer, picParams->num_ref_idx_l0_active_minus1);
1529 PutVLCCode(bsbuffer, picParams->num_ref_idx_l1_active_minus1);
1530
1531 PutBit(bsbuffer, picParams->weighted_pred_flag);
1532 PutBits(bsbuffer, picParams->weighted_bipred_idc, 2);
1533
1534 PutVLCCode(bsbuffer, SIGNED(picParams->pic_init_qp_minus26));
1535 PutVLCCode(bsbuffer, SIGNED(picParams->pic_init_qs_minus26));
1536 PutVLCCode(bsbuffer, SIGNED(picParams->chroma_qp_index_offset));
1537
1538 PutBit(bsbuffer, picParams->deblocking_filter_control_present_flag);
1539 PutBit(bsbuffer, picParams->constrained_intra_pred_flag);
1540 PutBit(bsbuffer, picParams->redundant_pic_cnt_present_flag);
1541
1542 // The syntax elements transform_8x8_mode_flag, pic_scaling_matrix_present_flag, and second_chroma_qp_index_offset
1543 // shall not be present for main profile
1544 if (seqParams->Profile == CODEC_AVC_MAIN_PROFILE || seqParams->Profile == CODEC_AVC_BASE_PROFILE)
1545 {
1546 return eStatus;
1547 }
1548
1549 PutBit(bsbuffer, picParams->transform_8x8_mode_flag);
1550 PutBit(bsbuffer, picParams->pic_scaling_matrix_present_flag);
1551 if (picParams->pic_scaling_matrix_present_flag)
1552 {
1553 uint8_t i;
1554
1555 //Iterate thro' the scaling lists. Refer to ITU-T H.264 std. section 7.3.2.2
1556 for (i = 0; i < 6 + 2 * picParams->transform_8x8_mode_flag; i++)
1557 {
1558 //Put scaling list present flag
1559 PutBit(bsbuffer, picParams->pic_scaling_list_present_flag[i]);
1560 if (picParams->pic_scaling_list_present_flag[i])
1561 {
1562 if (i < 6)
1563 {
1564 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList4x4[i][0], 16);
1565 }
1566 else
1567 {
1568 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList8x8[i - 6][0], 64);
1569 }
1570 }
1571 }
1572 }
1573
1574 PutVLCCode(bsbuffer, SIGNED(picParams->second_chroma_qp_index_offset));
1575
1576 *params->pbNewPPSHeader = 1;
1577
1578 return eStatus;
1579 }
1580
CodecHalAvcEncode_PackPictureHeader(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)1581 MOS_STATUS CodecHalAvcEncode_PackPictureHeader(
1582 PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
1583 {
1584 PBSBuffer bsbuffer;
1585 uint32_t indexNALUnit;
1586 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1587
1588 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1589 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1590 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
1591 CODECHAL_ENCODE_CHK_NULL_RETURN(params->ppNALUnitParams);
1592
1593 bsbuffer = params->pBsBuffer;
1594 *(bsbuffer->pBase) = 0; // init first byte to 0
1595 bsbuffer->pCurrent = bsbuffer->pBase;
1596 bsbuffer->SliceOffset = 0;
1597 bsbuffer->BitOffset = 0;
1598 bsbuffer->BitSize = 0;
1599
1600 MOS_ZeroMemory(params->ppNALUnitParams[0], sizeof(CODECHAL_NAL_UNIT_PARAMS) * CODECHAL_ENCODE_AVC_MAX_NAL_TYPE);
1601 indexNALUnit = 0;
1602
1603 // AU_Delimiter
1604 // nal_ref_idc to be 0 for all nal_unit_type equal to 6, 9, 10, 11 or12
1605 params->ppNALUnitParams[indexNALUnit]->uiOffset = 0;
1606 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_AUD;
1607 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = true;
1608 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
1609 SetNalUnit(&bsbuffer->pCurrent, 0, CODECHAL_ENCODE_AVC_NAL_UT_AUD);
1610 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackPictureHeader_AUDParams(params));
1611 SetTrailingBits(bsbuffer);
1612 //NAL unit are byte aligned, bsbuffer->BitOffset should be 0
1613 params->ppNALUnitParams[indexNALUnit]->uiSize =
1614 (uint32_t)(bsbuffer->pCurrent -
1615 bsbuffer->pBase -
1616 params->ppNALUnitParams[indexNALUnit]->uiOffset);
1617 indexNALUnit++;
1618
1619 // If this is a new sequence, write the seq set
1620 if (params->bNewSeq && !params->pSeqParams->bNoAcceleratorSPSInsertion)
1621 {
1622 // Pack SPS
1623 params->ppNALUnitParams[indexNALUnit]->uiOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
1624 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_SPS;
1625 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = true;
1626 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
1627 SetNalUnit(&bsbuffer->pCurrent, 1, CODECHAL_ENCODE_AVC_NAL_UT_SPS);
1628 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackPictureHeader_SeqParams(params));
1629 SetTrailingBits(bsbuffer);
1630 params->ppNALUnitParams[indexNALUnit]->uiSize =
1631 (uint32_t)(bsbuffer->pCurrent -
1632 bsbuffer->pBase -
1633 params->ppNALUnitParams[indexNALUnit]->uiOffset);
1634 indexNALUnit++;
1635 }
1636
1637 // Pack PPS
1638 params->ppNALUnitParams[indexNALUnit]->uiOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
1639 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_PPS;
1640 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = true;
1641 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
1642 SetNalUnit(&bsbuffer->pCurrent, 1, CODECHAL_ENCODE_AVC_NAL_UT_PPS);
1643 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackPictureHeader_PicParams(params));
1644 SetTrailingBits(bsbuffer);
1645 params->ppNALUnitParams[indexNALUnit]->uiSize =
1646 (uint32_t)(bsbuffer->pCurrent -
1647 bsbuffer->pBase -
1648 params->ppNALUnitParams[indexNALUnit]->uiOffset);
1649 indexNALUnit++;
1650
1651 // Pack SEI
1652 if (params->pSeiData->newSEIData)
1653 {
1654 params->ppNALUnitParams[indexNALUnit]->uiOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
1655 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_SEI;
1656 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = false;
1657 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
1658 eStatus = MOS_SecureMemcpy(bsbuffer->pCurrent,
1659 params->pSeiData->dwSEIBufSize,
1660 params->pSeiData->pSEIBuffer,
1661 params->pSeiData->dwSEIBufSize);
1662 if (eStatus != MOS_STATUS_SUCCESS)
1663 {
1664 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
1665 return eStatus;
1666 }
1667 bsbuffer->pCurrent += params->pSeiData->dwSEIDataSize;
1668 params->pSeiData->newSEIData = false;
1669 params->ppNALUnitParams[indexNALUnit]->uiSize =
1670 (uint32_t)(bsbuffer->pCurrent -
1671 bsbuffer->pBase -
1672 params->ppNALUnitParams[indexNALUnit]->uiOffset);
1673 indexNALUnit++;
1674 }
1675
1676 bsbuffer->SliceOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
1677
1678 return eStatus;
1679 }
1680
CodecHalAvcEncode_GetMaxNumSlicesAllowed(CODEC_AVC_PROFILE_IDC profileIdc,CODEC_AVC_LEVEL_IDC levelIdc,uint32_t framesPer100Sec)1681 uint16_t CodecHalAvcEncode_GetMaxNumSlicesAllowed(
1682 CODEC_AVC_PROFILE_IDC profileIdc,
1683 CODEC_AVC_LEVEL_IDC levelIdc,
1684 uint32_t framesPer100Sec)
1685 {
1686 uint16_t maxAllowedNumSlices = 0;
1687
1688 if ((profileIdc == CODEC_AVC_MAIN_PROFILE) ||
1689 (profileIdc == CODEC_AVC_HIGH_PROFILE) ||
1690 (profileIdc == CODEC_AVC_HIGH10_PROFILE) ||
1691 (profileIdc == CODEC_AVC_HIGH422_PROFILE) ||
1692 (profileIdc == CODEC_AVC_HIGH444_PROFILE) ||
1693 (profileIdc == CODEC_AVC_CAVLC444_INTRA_PROFILE))
1694 {
1695 switch (levelIdc)
1696 {
1697 case CODEC_AVC_LEVEL_3:
1698 maxAllowedNumSlices = (uint16_t)(40500.0 * 100 / 22.0 / framesPer100Sec);
1699 break;
1700 case CODEC_AVC_LEVEL_31:
1701 maxAllowedNumSlices = (uint16_t)(108000.0 * 100 / 60.0 / framesPer100Sec);
1702 break;
1703 case CODEC_AVC_LEVEL_32:
1704 maxAllowedNumSlices = (uint16_t)(216000.0 * 100 / 60.0 / framesPer100Sec);
1705 break;
1706 case CODEC_AVC_LEVEL_4:
1707 case CODEC_AVC_LEVEL_41:
1708 maxAllowedNumSlices = (uint16_t)(245760.0 * 100 / 24.0 / framesPer100Sec);
1709 break;
1710 case CODEC_AVC_LEVEL_42:
1711 maxAllowedNumSlices = (uint16_t)(522240.0 * 100 / 24.0 / framesPer100Sec);
1712 break;
1713 case CODEC_AVC_LEVEL_5:
1714 maxAllowedNumSlices = (uint16_t)(589824.0 * 100 / 24.0 / framesPer100Sec);
1715 break;
1716 case CODEC_AVC_LEVEL_51:
1717 maxAllowedNumSlices = (uint16_t)(983040.0 * 100 / 24.0 / framesPer100Sec);
1718 break;
1719 case CODEC_AVC_LEVEL_52:
1720 maxAllowedNumSlices = (uint16_t)(2073600.0 * 100 / 24.0 / framesPer100Sec);
1721 break;
1722 default:
1723 maxAllowedNumSlices = 0;
1724 }
1725 }
1726
1727 return maxAllowedNumSlices;
1728 }
1729
1730 //Pack Slice Header
CodecHalAvcEncode_PackSliceHeader(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)1731 MOS_STATUS CodecHalAvcEncode_PackSliceHeader(
1732 PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
1733 {
1734 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams;
1735 PCODEC_AVC_ENCODE_PIC_PARAMS picParams;
1736 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
1737 PBSBuffer bsbuffer;
1738 uint8_t sliceType;
1739 CODECHAL_ENCODE_AVC_NAL_UNIT_TYPE nalType;
1740 bool ref;
1741 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1742
1743 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1744 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
1745 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pPicParams);
1746 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
1747 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
1748
1749 slcParams = params->pAvcSliceParams;
1750 picParams = params->pPicParams;
1751 seqParams = params->pSeqParams;
1752 bsbuffer = params->pBsBuffer;
1753 sliceType = Slice_Type[slcParams->slice_type];
1754 nalType = params->NalUnitType;
1755 ref = params->ppRefList[params->CurrReconPic.FrameIdx]->bUsedAsRef;
1756
1757 // Make slice header uint8_t aligned
1758 while (bsbuffer->BitOffset)
1759 {
1760 PutBit(bsbuffer, 0);
1761 }
1762
1763 // zero byte shall exist when the byte stream NAL unit syntax structure contains the first
1764 // NAL unit of an access unit in decoding order, as specified by subclause 7.4.1.2.3.
1765 // VDEnc Slice header packing handled by PAK does not need the 0 byte inserted
1766 if (params->UserFlags.bDisableAcceleratorHeaderPacking && (!params->bVdencEnabled))
1767 {
1768 *bsbuffer->pCurrent = 0;
1769 bsbuffer->pCurrent++;
1770 }
1771
1772 SetNalUnit(&bsbuffer->pCurrent, (uint8_t)ref, nalType);
1773
1774 PutVLCCode(bsbuffer, slcParams->first_mb_in_slice);
1775 PutVLCCode(bsbuffer, slcParams->slice_type);
1776 PutVLCCode(bsbuffer, slcParams->pic_parameter_set_id);
1777
1778 if (seqParams->separate_colour_plane_flag)
1779 {
1780 PutBits(bsbuffer, slcParams->colour_plane_id, 2);
1781 }
1782
1783 PutBits(bsbuffer, slcParams->frame_num, seqParams->log2_max_frame_num_minus4 + 4);
1784
1785 if (!seqParams->frame_mbs_only_flag)
1786 {
1787 PutBit(bsbuffer, slcParams->field_pic_flag);
1788 if (slcParams->field_pic_flag)
1789 {
1790 PutBit(bsbuffer, slcParams->bottom_field_flag);
1791 }
1792 }
1793
1794 if (nalType == CODECHAL_ENCODE_AVC_NAL_UT_IDR_SLICE)
1795 {
1796 PutVLCCode(bsbuffer, slcParams->idr_pic_id);
1797 }
1798
1799 if (seqParams->pic_order_cnt_type == 0)
1800 {
1801 PutBits(bsbuffer, slcParams->pic_order_cnt_lsb, seqParams->log2_max_pic_order_cnt_lsb_minus4 + 4);
1802 if (picParams->pic_order_present_flag && !slcParams->field_pic_flag)
1803 {
1804 PutVLCCode(bsbuffer, SIGNED(slcParams->delta_pic_order_cnt_bottom));
1805 }
1806 }
1807
1808 if (seqParams->pic_order_cnt_type == 1 && !seqParams->delta_pic_order_always_zero_flag)
1809 {
1810 PutVLCCode(bsbuffer, SIGNED(slcParams->delta_pic_order_cnt[0]));
1811 if (picParams->pic_order_present_flag && !slcParams->field_pic_flag)
1812 {
1813 PutVLCCode(bsbuffer, SIGNED(slcParams->delta_pic_order_cnt[1]));
1814 }
1815 }
1816
1817 if (picParams->redundant_pic_cnt_present_flag)
1818 {
1819 PutVLCCode(bsbuffer, slcParams->redundant_pic_cnt);
1820 }
1821
1822 if (sliceType == SLICE_B)
1823 {
1824 PutBit(bsbuffer, slcParams->direct_spatial_mv_pred_flag);
1825 }
1826
1827 if (sliceType == SLICE_P || sliceType == SLICE_SP || sliceType == SLICE_B)
1828 {
1829 PutBit(bsbuffer, slcParams->num_ref_idx_active_override_flag);
1830 if (slcParams->num_ref_idx_active_override_flag)
1831 {
1832 PutVLCCode(bsbuffer, slcParams->num_ref_idx_l0_active_minus1);
1833 if (sliceType == SLICE_B)
1834 {
1835 PutVLCCode(bsbuffer, slcParams->num_ref_idx_l1_active_minus1);
1836 }
1837 }
1838 }
1839
1840 // ref_pic_list_reordering()
1841 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackSliceHeader_RefPicListReordering(params));
1842
1843 if ((picParams->weighted_pred_flag &&
1844 (sliceType == SLICE_P || sliceType == SLICE_SP)) ||
1845 (picParams->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE &&
1846 sliceType == SLICE_B))
1847 {
1848 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_PackSliceHeader_PredWeightTable(params));
1849 }
1850
1851 // dec_ref_pic_marking()
1852 if (nalType == CODECHAL_ENCODE_AVC_NAL_UT_IDR_SLICE)
1853 {
1854 PutBit(bsbuffer, slcParams->no_output_of_prior_pics_flag);
1855 PutBit(bsbuffer, slcParams->long_term_reference_flag);
1856 }
1857 else if (ref)
1858 {
1859 PutBit(bsbuffer, slcParams->adaptive_ref_pic_marking_mode_flag);
1860 }
1861
1862 if (picParams->entropy_coding_mode_flag && sliceType != SLICE_I && sliceType != SLICE_SI)
1863 {
1864 PutVLCCode(bsbuffer, slcParams->cabac_init_idc);
1865 }
1866
1867 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_qp_delta));
1868
1869 if (sliceType == SLICE_SP || sliceType == SLICE_SI)
1870 {
1871 if (sliceType == SLICE_SP)
1872 {
1873 PutBit(bsbuffer, slcParams->sp_for_switch_flag);
1874 }
1875 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_qs_delta));
1876 }
1877
1878 if (picParams->deblocking_filter_control_present_flag)
1879 {
1880 PutVLCCode(bsbuffer, slcParams->disable_deblocking_filter_idc);
1881 if (slcParams->disable_deblocking_filter_idc != 1)
1882 {
1883 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_alpha_c0_offset_div2));
1884 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_beta_offset_div2));
1885 }
1886 }
1887
1888 bsbuffer->BitSize =
1889 (uint32_t)((bsbuffer->pCurrent - bsbuffer->SliceOffset - bsbuffer->pBase) * 8 + bsbuffer->BitOffset);
1890 bsbuffer->SliceOffset =
1891 (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase + (bsbuffer->BitOffset != 0));
1892
1893 return eStatus;
1894 }
1895
InitMmcState()1896 MOS_STATUS CodechalEncodeAvcBase::InitMmcState()
1897 {
1898 #ifdef _MMC_SUPPORTED
1899 m_mmcState = MOS_New(CodechalMmcEncodeAvc, m_hwInterface, this);
1900 CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
1901 #endif
1902 return MOS_STATUS_SUCCESS;
1903 }
1904
CodechalEncodeAvcBase(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)1905 CodechalEncodeAvcBase::CodechalEncodeAvcBase(
1906 CodechalHwInterface * hwInterface,
1907 CodechalDebugInterface *debugInterface,
1908 PCODECHAL_STANDARD_INFO standardInfo) : CodechalEncoderState(hwInterface, debugInterface, standardInfo)
1909 {
1910 CODECHAL_ENCODE_FUNCTION_ENTER;
1911
1912 MOS_ZeroMemory(m_avcPicParams, CODEC_AVC_MAX_PPS_NUM * sizeof(PCODEC_AVC_ENCODE_PIC_PARAMS));
1913 MOS_ZeroMemory(m_avcSeqParams, CODEC_AVC_MAX_SPS_NUM * sizeof(PCODEC_AVC_ENCODE_SEQUENCE_PARAMS));
1914 MOS_ZeroMemory(&m_userFlags, sizeof(CODEC_AVC_ENCODE_USER_FLAGS));
1915 MOS_ZeroMemory(m_picIdx, CODEC_AVC_MAX_NUM_REF_FRAME * sizeof(CODEC_PIC_ID));
1916 MOS_ZeroMemory(m_refList, CODEC_AVC_NUM_UNCOMPRESSED_SURFACE * sizeof(PCODEC_REF_LIST));
1917 MOS_ZeroMemory(m_avcFrameStoreID, CODEC_AVC_MAX_NUM_REF_FRAME * sizeof(CODEC_AVC_FRAME_STORE_ID));
1918 MOS_ZeroMemory(&m_nalUnitType, sizeof(CODECHAL_ENCODE_AVC_NAL_UNIT_TYPE));
1919 MOS_ZeroMemory(&m_trellisQuantParams, sizeof(CODECHAL_ENCODE_AVC_TQ_PARAMS));
1920 MOS_ZeroMemory(m_distScaleFactorList0, 2 * CODEC_AVC_MAX_NUM_REF_FRAME * sizeof(uint32_t));
1921 MOS_ZeroMemory(m_batchBufferForVdencImgStat, CODECHAL_ENCODE_RECYCLED_BUFFER_NUM * sizeof(MHW_BATCH_BUFFER));
1922 MOS_ZeroMemory(&m_4xMeMvDataBuffer, sizeof(MOS_SURFACE));
1923 MOS_ZeroMemory(&m_16xMeMvDataBuffer, sizeof(MOS_SURFACE));
1924 MOS_ZeroMemory(&m_32xMeMvDataBuffer, sizeof(MOS_SURFACE));
1925 MOS_ZeroMemory(&m_4xMeDistortionBuffer, sizeof(MOS_SURFACE));
1926 MOS_ZeroMemory(&m_intraRowStoreScratchBuffer, sizeof(MOS_RESOURCE));
1927 MOS_ZeroMemory(m_batchBufferForPakSlices, CODECHAL_ENCODE_RECYCLED_BUFFER_NUM * sizeof(MHW_BATCH_BUFFER));
1928 MOS_ZeroMemory(&m_pakSliceSizeStreamoutBuffer, sizeof(MOS_RESOURCE));
1929
1930 m_hwInterface->GetStateHeapSettings()->dwNumSyncTags = CODECHAL_ENCODE_AVC_NUM_SYNC_TAGS;
1931 m_hwInterface->GetStateHeapSettings()->dwDshSize = CODECHAL_ENCODE_AVC_INIT_DSH_SIZE;
1932 }
1933
~CodechalEncodeAvcBase()1934 CodechalEncodeAvcBase::~CodechalEncodeAvcBase()
1935 {
1936 CODECHAL_ENCODE_FUNCTION_ENTER;
1937
1938 // Release Ref Lists
1939 CodecHalFreeDataList(m_refList, CODEC_AVC_NUM_UNCOMPRESSED_SURFACE);
1940
1941 for (uint8_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
1942 {
1943 ReleaseBatchBufferForPakSlices(i);
1944 }
1945
1946 m_osInterface->pfnFreeResource(m_osInterface, &m_intraRowStoreScratchBuffer);
1947
1948 if (m_encEnabled)
1949 {
1950 if (m_hmeSupported)
1951 {
1952 if (m_hmeKernel)
1953 {
1954 MOS_Delete(m_hmeKernel);
1955 }
1956 else
1957 {
1958 HmeParams hmeParams;
1959
1960 MOS_ZeroMemory(&hmeParams, sizeof(hmeParams));
1961 hmeParams.b4xMeDistortionBufferSupported = true;
1962 hmeParams.ps16xMeMvDataBuffer = &m_16xMeMvDataBuffer;
1963 hmeParams.ps32xMeMvDataBuffer = &m_32xMeMvDataBuffer;
1964 hmeParams.ps4xMeDistortionBuffer = &m_4xMeDistortionBuffer;
1965 hmeParams.ps4xMeMvDataBuffer = &m_4xMeMvDataBuffer;
1966 DestroyMeResources(&hmeParams);
1967 }
1968 }
1969 }
1970
1971 if (m_sliceSizeStreamoutSupported)
1972 {
1973 m_osInterface->pfnFreeResource(m_osInterface, &m_pakSliceSizeStreamoutBuffer);
1974 }
1975 }
1976
Initialize(CodechalSetting * settings)1977 MOS_STATUS CodechalEncodeAvcBase::Initialize(CodechalSetting *settings)
1978 {
1979 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitMmcState());
1980 return CodechalEncoderState::Initialize(settings);
1981 }
1982
UserFeatureKeyReport()1983 MOS_STATUS CodechalEncodeAvcBase::UserFeatureKeyReport()
1984 {
1985 return CodechalEncoderState::UserFeatureKeyReport();
1986 }
1987
Initialize()1988 MOS_STATUS CodechalEncodeAvcBase::Initialize()
1989 {
1990 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1991
1992 m_hwInterface->GetMfxPrimitiveCommandsDataSize(
1993 m_mode,
1994 &m_pakSliceSize,
1995 &m_pakSlicePatchListSize,
1996 false);
1997
1998 // overwrite, must be zero, no patching into second level batch buffer allowed
1999 m_pakSlicePatchListSize = 0;
2000
2001 return eStatus;
2002 }
2003
ScalingListFlat()2004 void CodechalEncodeAvcBase::ScalingListFlat()
2005 {
2006 // 4x4 block
2007 for (uint8_t idx2 = 0; idx2 < 6; idx2++)
2008 {
2009 for (uint8_t idx1 = 0; idx1 < 16; idx1++)
2010 {
2011 m_avcIQWeightScaleLists->WeightScale4x4[idx2][idx1] = 16;
2012 }
2013 }
2014 // 8x8 block
2015 for (uint8_t idx2 = 0; idx2 < 2; idx2++)
2016 {
2017 for (uint8_t idx1 = 0; idx1 < 64; idx1++)
2018 {
2019 m_avcIQWeightScaleLists->WeightScale8x8[idx2][idx1] = 16;
2020 }
2021 }
2022 }
2023
ScalingListFallbackRuleA()2024 void CodechalEncodeAvcBase::ScalingListFallbackRuleA()
2025 {
2026 for (uint8_t idx1 = 0; idx1 < 16; idx1++)
2027 {
2028 for (uint8_t idx2 = 0; idx2 < 3; idx2++)
2029 {
2030 m_avcIQWeightScaleLists->WeightScale4x4[idx2][CODEC_AVC_Qmatrix_scan_4x4[idx1]] =
2031 CODEC_AVC_Default_4x4_Intra[idx1];
2032 }
2033 for (uint8_t idx2 = 3; idx2 < 6; idx2++)
2034 {
2035 m_avcIQWeightScaleLists->WeightScale4x4[idx2][CODEC_AVC_Qmatrix_scan_4x4[idx1]] =
2036 CODEC_AVC_Default_4x4_Inter[idx1];
2037 }
2038 }
2039 // 8x8 block
2040 for (uint8_t idx1 = 0; idx1 < 64; idx1++)
2041 {
2042 m_avcIQWeightScaleLists->WeightScale8x8[0][CODEC_AVC_Qmatrix_scan_8x8[idx1]] =
2043 CODEC_AVC_Default_8x8_Intra[idx1];
2044 m_avcIQWeightScaleLists->WeightScale8x8[1][CODEC_AVC_Qmatrix_scan_8x8[idx1]] =
2045 CODEC_AVC_Default_8x8_Inter[idx1];
2046 }
2047 }
2048
GetDistScaleFactor()2049 void CodechalEncodeAvcBase::GetDistScaleFactor()
2050 {
2051 auto picParams = m_avcPicParam;
2052 auto refList = &(m_refList[0]);
2053 auto picIdx = &(m_picIdx[0]);
2054
2055 bool bottom = CodecHal_PictureIsBottomField(picParams->CurrOriginalPic);
2056 int pocCurr = picParams->CurrFieldOrderCnt[bottom];
2057
2058 MOS_ZeroMemory(m_distScaleFactorList0, sizeof(uint32_t) * CODEC_AVC_MAX_NUM_REF_FRAME * 2);
2059 for (unsigned int index = 0; index <= m_avcSliceParams->num_ref_idx_l0_active_minus1; index++)
2060 {
2061 auto picture = m_avcSliceParams->RefPicList[LIST_0][index];
2062 if (!CodecHal_PictureIsInvalid(picture))
2063 {
2064 auto pictureIdx = picIdx[picture.FrameIdx].ucPicIdx;
2065 int pocPic0 = CodecHal_PictureIsBottomField(picture) ? refList[pictureIdx]->iFieldOrderCnt[1] : refList[pictureIdx]->iFieldOrderCnt[0];
2066 picture = m_avcSliceParams->RefPicList[LIST_1][0];
2067 pictureIdx = picIdx[picture.FrameIdx].ucPicIdx;
2068 int pocPic1 = CodecHal_PictureIsBottomField(picture) ? refList[pictureIdx]->iFieldOrderCnt[1] : refList[pictureIdx]->iFieldOrderCnt[0];
2069 int tb = CodecHal_Clip3(-128, 127, (pocCurr - pocPic0));
2070 int td = CodecHal_Clip3(-128, 127, (pocPic1 - pocPic0));
2071 if (td == 0)
2072 {
2073 td = 1;
2074 }
2075 int tx = (16384 + ABS(td / 2)) / td;
2076
2077 m_distScaleFactorList0[index] = CodecHal_Clip3(-1024, 1023, (tb * tx + 32) >> 6);
2078 }
2079 }
2080 }
2081
AllocateBatchBufferForPakSlices(uint32_t numSlices,uint8_t numPakPasses,uint8_t currRecycledBufIdx)2082 MOS_STATUS CodechalEncodeAvcBase::AllocateBatchBufferForPakSlices(
2083 uint32_t numSlices,
2084 uint8_t numPakPasses,
2085 uint8_t currRecycledBufIdx)
2086 {
2087 CODECHAL_ENCODE_FUNCTION_ENTER;
2088 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2089
2090 MOS_ZeroMemory(
2091 &m_batchBufferForPakSlices[currRecycledBufIdx],
2092 sizeof(MHW_BATCH_BUFFER));
2093
2094 // Get the slice size
2095 uint32_t size = (numPakPasses + 1) * numSlices * m_pakSliceSize;
2096
2097 m_batchBufferForPakSlices[currRecycledBufIdx].bSecondLevel = true;
2098 CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
2099 m_osInterface,
2100 &m_batchBufferForPakSlices[currRecycledBufIdx],
2101 nullptr,
2102 size));
2103
2104 MOS_LOCK_PARAMS lockFlags;
2105 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
2106 lockFlags.WriteOnly = 1;
2107 uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
2108 m_osInterface,
2109 &m_batchBufferForPakSlices[currRecycledBufIdx].OsResource,
2110 &lockFlags);
2111
2112 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
2113
2114 MOS_ZeroMemory(data, size);
2115 m_osInterface->pfnUnlockResource(
2116 m_osInterface,
2117 &m_batchBufferForPakSlices[currRecycledBufIdx].OsResource);
2118
2119 return eStatus;
2120 }
2121
ReleaseBatchBufferForPakSlices(uint8_t currRecycledBufIdx)2122 MOS_STATUS CodechalEncodeAvcBase::ReleaseBatchBufferForPakSlices(
2123 uint8_t currRecycledBufIdx)
2124 {
2125 CODECHAL_ENCODE_FUNCTION_ENTER;
2126 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2127
2128 if (m_batchBufferForPakSlices[currRecycledBufIdx].iSize)
2129 {
2130 Mhw_FreeBb(m_osInterface, &m_batchBufferForPakSlices[currRecycledBufIdx], nullptr);
2131 }
2132
2133 return eStatus;
2134 }
2135
2136 //==<Functions>=======================================================
2137
2138 // Calculate BiWeight for AVC B frame
2139 // for AVC, we cannot use the CodecHal_GetBiWeight function since AVC can use B as reference and
2140 // also supports PAFF
GetBiWeight(uint32_t distScaleFactorRefID0List0,uint16_t weightedBiPredIdc)2141 int32_t CodechalEncodeAvcBase::GetBiWeight(
2142 uint32_t distScaleFactorRefID0List0,
2143 uint16_t weightedBiPredIdc)
2144 {
2145 int32_t biWeight = 32; // default value
2146 if (weightedBiPredIdc != IMPLICIT_WEIGHTED_INTER_PRED_MODE)
2147 {
2148 biWeight = 32;
2149 }
2150 else
2151 {
2152 biWeight = (distScaleFactorRefID0List0 + 2) >> 2;
2153
2154 if (biWeight != 16 && biWeight != 21 &&
2155 biWeight != 32 && biWeight != 43 && biWeight != 48)
2156 {
2157 biWeight = 32; // If # of B-pics between two refs is more than 3. VME does not support it.
2158 }
2159 }
2160
2161 return biWeight;
2162 }
2163
AllocateEncResources()2164 MOS_STATUS CodechalEncodeAvcBase::AllocateEncResources()
2165 {
2166 CODECHAL_ENCODE_FUNCTION_ENTER;
2167 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2168
2169 uint32_t fieldNumMBs = m_picWidthInMb * ((m_picHeightInMb + 1) >> 1);
2170
2171 // to be used in CodecHalEncode_TrackedBuffer_AllocateMbCodeMvDataResources() later
2172 m_mbCodeSize = MOS_ALIGN_CEIL(fieldNumMBs * 16 * 4, CODECHAL_PAGE_SIZE) + fieldNumMBs * 16 * 4;
2173 m_mvDataSize = MOS_ALIGN_CEIL(fieldNumMBs * (32 * 4), CODECHAL_PAGE_SIZE) + // top field MV + 4K align for bottom field MV
2174 fieldNumMBs * (32 * 4); // bottom field MV
2175
2176 // allocate 3 + 2 buffers initially
2177 if ((m_codecFunction == CODECHAL_FUNCTION_ENC_PAK) && (!m_vdencEnabled))
2178 {
2179 for (uint8_t j = 0; j < 3; j++)
2180 {
2181 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_trackedBuf->AllocateMbCodeResources(j));
2182 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_trackedBuf->AllocateMvDataResources(j));
2183 }
2184
2185 for (uint8_t k = 0; k < 2; k++)
2186 {
2187 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_trackedBuf->AllocateMbCodeResources(CODEC_NUM_REF_BUFFERS + k));
2188 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_trackedBuf->AllocateMvDataResources(CODEC_NUM_REF_BUFFERS + k));
2189 }
2190 }
2191
2192 if (m_encEnabled && m_hmeSupported)
2193 {
2194 if (m_hmeKernel)
2195 {
2196 m_hmeKernel->AllocateResources();
2197 }
2198 else
2199 {
2200 HmeParams hmeParams;
2201 MOS_ZeroMemory(&hmeParams, sizeof(hmeParams));
2202 hmeParams.b4xMeDistortionBufferSupported = true;
2203 hmeParams.ps4xMeDistortionBuffer = &m_4xMeDistortionBuffer;
2204 hmeParams.ps4xMeMvDataBuffer = &m_4xMeMvDataBuffer;
2205 hmeParams.ps16xMeMvDataBuffer = &m_16xMeMvDataBuffer;
2206 hmeParams.ps32xMeMvDataBuffer = &m_32xMeMvDataBuffer;
2207
2208 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResources4xMe(&hmeParams));
2209 if (m_16xMeSupported)
2210 {
2211 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResources16xMe(&hmeParams));
2212 }
2213 if (m_32xMeSupported)
2214 {
2215 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResources32xMe(&hmeParams));
2216 }
2217 }
2218 }
2219
2220 return eStatus;
2221 }
2222
AllocateResources()2223 MOS_STATUS CodechalEncodeAvcBase::AllocateResources()
2224 {
2225 CODECHAL_ENCODE_FUNCTION_ENTER;
2226 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2227
2228 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::AllocateResources());
2229
2230 // initiate allocation parameters and lock flags
2231 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
2232 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
2233 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
2234 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
2235 allocParamsForBufferLinear.Format = Format_Buffer;
2236
2237 AllocateEncResources();
2238
2239 // Allocate Ref Lists
2240 CodecHalAllocateDataList(
2241 m_refList,
2242 CODEC_AVC_NUM_UNCOMPRESSED_SURFACE);
2243
2244 if (m_pakEnabled && m_mfxInterface->IsIntraRowstoreCacheEnabled() == false)
2245 {
2246 // Intra Row Store Scratch buffer
2247 // 1 cacheline per MB
2248 allocParamsForBufferLinear.dwBytes = m_picWidthInMb * CODECHAL_CACHELINE_SIZE;
2249 allocParamsForBufferLinear.pBufName = "Intra Row Store Scratch Buffer";
2250
2251 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
2252 m_osInterface,
2253 &allocParamsForBufferLinear,
2254 &m_intraRowStoreScratchBuffer);
2255
2256 if (eStatus != MOS_STATUS_SUCCESS)
2257 {
2258 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate Intra Row Store Scratch Buffer.");
2259 return eStatus;
2260 }
2261 }
2262
2263 if (m_sliceSizeStreamoutSupported)
2264 {
2265 // PAK Slice Size Streamout Buffer
2266 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(CODECHAL_ENCODE_SLICESIZE_BUF_SIZE, CODECHAL_PAGE_SIZE);
2267 allocParamsForBufferLinear.pBufName = "PAK Slice Size Streamout Buffer";
2268
2269 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
2270 m_osInterface,
2271 &allocParamsForBufferLinear,
2272 &m_pakSliceSizeStreamoutBuffer);
2273
2274 if (eStatus != MOS_STATUS_SUCCESS)
2275 {
2276 CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate Slice Size Streamout Buffer\n", __FUNCTION__);
2277 return eStatus;
2278 }
2279 }
2280
2281 return eStatus;
2282 }
2283
SetSequenceStructs()2284 MOS_STATUS CodechalEncodeAvcBase::SetSequenceStructs()
2285 {
2286 CODECHAL_ENCODE_FUNCTION_ENTER;
2287 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2288
2289 auto seqParams = m_avcSeqParam;
2290
2291 // seq_scaling_matrix_present_flag and chroma_format_idc
2292 // shall not be present for main profile
2293 if (seqParams->Profile == CODEC_AVC_MAIN_PROFILE)
2294 {
2295 seqParams->seq_scaling_matrix_present_flag = 0;
2296 for (uint8_t i = 0; i < 12; i++)
2297 {
2298 seqParams->seq_scaling_list_present_flag[i] = 0;
2299 }
2300 seqParams->chroma_format_idc = 1;
2301 }
2302 // high profile chroma_format_idc in the range of 0 to 1 inclusive
2303 if (seqParams->chroma_format_idc > 1)
2304 {
2305 seqParams->chroma_format_idc = 1;
2306 }
2307
2308 // main & high profile support only 8bpp
2309 seqParams->bit_depth_luma_minus8 = 0;
2310 seqParams->bit_depth_chroma_minus8 = 0;
2311
2312 seqParams->NumRefFrames = seqParams->NumRefFrames * 2;
2313
2314 // setup parameters corresponding to H264 bit stream definition
2315 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;
2316 seqParams->pic_width_in_mbs_minus1 = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(seqParams->FrameWidth) - 1;
2317 seqParams->constraint_set0_flag = 0;
2318 seqParams->constraint_set1_flag = (seqParams->Profile == CODEC_AVC_BASE_PROFILE) ? 1 : 0;
2319 seqParams->constraint_set2_flag = 0;
2320 seqParams->constraint_set3_flag = 0;
2321 seqParams->gaps_in_frame_num_value_allowed_flag = 0;
2322 seqParams->qpprime_y_zero_transform_bypass_flag = 0;
2323 seqParams->separate_colour_plane_flag = 0;
2324
2325 // setup internal parameters
2326 m_picWidthInMb = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(seqParams->FrameWidth);
2327 m_picHeightInMb = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(seqParams->FrameHeight);
2328 m_frameWidth = m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH;
2329 m_frameHeight = m_picHeightInMb * CODECHAL_MACROBLOCK_HEIGHT;
2330
2331 // HME Scaling WxH
2332 m_downscaledWidthInMb4x =
2333 CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_4x);
2334 m_downscaledHeightInMb4x =
2335 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_4x);
2336 m_downscaledWidth4x =
2337 m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
2338 m_downscaledHeight4x =
2339 m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT;
2340
2341 // SuperHME Scaling WxH
2342 m_downscaledWidthInMb16x =
2343 CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_16x);
2344 m_downscaledHeightInMb16x =
2345 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_16x);
2346 m_downscaledWidth16x =
2347 m_downscaledWidthInMb16x * CODECHAL_MACROBLOCK_WIDTH;
2348 m_downscaledHeight16x =
2349 m_downscaledHeightInMb16x * CODECHAL_MACROBLOCK_HEIGHT;
2350
2351 // UltraHME Scaling WxH
2352 m_downscaledWidthInMb32x =
2353 CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_32x);
2354 m_downscaledHeightInMb32x =
2355 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_32x);
2356 m_downscaledWidth32x =
2357 m_downscaledWidthInMb32x * CODECHAL_MACROBLOCK_WIDTH;
2358 m_downscaledHeight32x =
2359 m_downscaledHeightInMb32x * CODECHAL_MACROBLOCK_HEIGHT;
2360
2361 MotionEstimationDisableCheck();
2362
2363 m_kernelMode =
2364 CodecHal_TargetUsageToMode_AVC[seqParams->TargetUsage & 0x7];
2365 m_targetUsage = seqParams->TargetUsage & 0x7;
2366
2367 if (!seqParams->frame_cropping_flag)
2368 {
2369 // do cropping only when the picture dimension is not MB aligned...
2370 seqParams->frame_crop_left_offset = 0;
2371 seqParams->frame_crop_top_offset = 0;
2372
2373 if (m_frameWidth != seqParams->FrameWidth ||
2374 m_frameHeight != seqParams->FrameHeight)
2375 {
2376 seqParams->frame_cropping_flag = 1;
2377 seqParams->frame_crop_right_offset = (uint16_t)((m_frameWidth - seqParams->FrameWidth) >> 1); // 4:2:0
2378 seqParams->frame_crop_bottom_offset = (uint16_t)((m_frameHeight - seqParams->FrameHeight) >> (2 - seqParams->frame_mbs_only_flag)); // 4:2:0
2379 }
2380 else
2381 {
2382 seqParams->frame_cropping_flag = 0;
2383 seqParams->frame_crop_right_offset = 0;
2384 seqParams->frame_crop_bottom_offset = 0;
2385 }
2386 }
2387
2388 if (m_mfxInterface->IsRowStoreCachingSupported())
2389 {
2390 MHW_VDBOX_ROWSTORE_PARAMS rowstoreParams;
2391 MOS_ZeroMemory(&rowstoreParams, sizeof(rowstoreParams));
2392 rowstoreParams.Mode = CODECHAL_ENCODE_MODE_AVC;
2393 rowstoreParams.dwPicWidth = m_frameWidth;
2394 rowstoreParams.bIsFrame = (seqParams->frame_mbs_only_flag == 1);
2395 m_hwInterface->SetRowstoreCachingOffsets(&rowstoreParams);
2396 }
2397
2398 return eStatus;
2399 }
2400
SetPictureStructs()2401 MOS_STATUS CodechalEncodeAvcBase::SetPictureStructs()
2402 {
2403 CODECHAL_ENCODE_FUNCTION_ENTER;
2404 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2405
2406 auto picParams = m_avcPicParam;
2407 auto seqParams = m_avcSeqParam;
2408 auto avcRefList = &m_refList[0];
2409 auto avcPicIdx = &m_picIdx[0];
2410 auto slcParams = m_avcSliceParams;
2411
2412 if (seqParams->Profile == CODEC_AVC_MAIN_PROFILE || seqParams->Profile == CODEC_AVC_BASE_PROFILE)
2413 {
2414 picParams->transform_8x8_mode_flag = 0;
2415 picParams->pic_scaling_matrix_present_flag = 0;
2416 for (uint8_t i = 0; i < 12; i++)
2417 {
2418 picParams->pic_scaling_list_present_flag[i] = 0;
2419 }
2420 picParams->second_chroma_qp_index_offset = picParams->chroma_qp_index_offset;
2421 }
2422 if (picParams->QpY < 0)
2423 {
2424 picParams->QpY = 25; // Set to default, recommended value used in simulation.
2425 }
2426 else if (picParams->QpY > CODECHAL_ENCODE_AVC_MAX_SLICE_QP)
2427 {
2428 picParams->QpY = CODECHAL_ENCODE_AVC_MAX_SLICE_QP; // Crop to 51 if larger
2429 }
2430 picParams->pic_init_qp_minus26 = picParams->QpY - 26;
2431
2432 if (!seqParams->seq_scaling_matrix_present_flag)
2433 {
2434 if (!picParams->pic_scaling_matrix_present_flag)
2435 ScalingListFlat();
2436 else if (!picParams->pic_scaling_list_present_flag[0])
2437 ScalingListFallbackRuleA();
2438 }
2439 else if (!seqParams->seq_scaling_list_present_flag[0] &&
2440 !picParams->pic_scaling_list_present_flag[0])
2441 { // fall-back rule A
2442 ScalingListFallbackRuleA();
2443 }
2444
2445 picParams->num_slice_groups_minus1 = 0; // do not support flexible MB ordering
2446 picParams->deblocking_filter_control_present_flag = 1; // always set to 1
2447 picParams->redundant_pic_cnt_present_flag = 0;
2448 picParams->pic_init_qs_minus26 = 0; // not used
2449
2450 m_userFlags = picParams->UserFlags;
2451 m_nalUnitType = picParams->bIdrPic ? CODECHAL_ENCODE_AVC_NAL_UT_IDR_SLICE : CODECHAL_ENCODE_AVC_NAL_UT_SLICE;
2452 m_frameNum = picParams->frame_num;
2453 m_lastPicInSeq = picParams->bLastPicInSeq;
2454 m_lastPicInStream = picParams->bLastPicInStream;
2455 // App handles tail insertion for VDEnc dynamic slice in non-cp case
2456 if (m_vdencNoTailInsertion)
2457 {
2458 m_lastPicInSeq = m_lastPicInStream = 0;
2459 }
2460 m_statusReportFeedbackNumber = picParams->StatusReportFeedbackNumber;
2461
2462 auto prevPic = m_currOriginalPic;
2463 auto prevIdx = prevPic.FrameIdx;
2464 auto currPic = picParams->CurrOriginalPic;
2465 auto currIdx = currPic.FrameIdx;
2466 auto prevRefIdx = m_currReconstructedPic.FrameIdx;
2467 auto currRefIdx = picParams->CurrReconstructedPic.FrameIdx;
2468
2469 m_prevReconFrameIdx = m_currReconFrameIdx;
2470 m_currReconFrameIdx = picParams->CurrReconstructedPic.FrameIdx;
2471
2472 avcRefList[currRefIdx]->sRefReconBuffer = m_reconSurface;
2473 avcRefList[currRefIdx]->sRefRawBuffer = m_rawSurface;
2474 avcRefList[currRefIdx]->sFrameNumber = picParams->frame_num;
2475 avcRefList[currRefIdx]->RefPic = currPic;
2476 m_currOriginalPic = currPic;
2477 m_currReconstructedPic = picParams->CurrReconstructedPic;
2478
2479 if (picParams->FieldCodingFlag)
2480 {
2481 m_frameFieldHeight = ((m_frameHeight + 1) >> 1);
2482 m_frameFieldHeightInMb = ((m_picHeightInMb + 1) >> 1);
2483 m_downscaledFrameFieldHeightInMb4x = ((m_downscaledHeightInMb4x + 1) >> 1);
2484 m_downscaledFrameFieldHeightInMb16x = ((m_downscaledHeightInMb16x + 1) >> 1);
2485 m_downscaledFrameFieldHeightInMb32x = ((m_downscaledHeightInMb32x + 1) >> 1);
2486 m_currEncBbSet = MB_ENC_Field_BB;
2487 if (CodecHal_PictureIsFrame(prevPic) || prevIdx != currIdx ||
2488 ((prevPic.PicFlags != currPic.PicFlags) && !(slcParams->pic_order_cnt_lsb & 1)))
2489 {
2490 m_firstField = 1;
2491 // Enable self referencing for both IDR and I pics
2492 m_firstFieldIdrPic = (picParams->CodingType == I_TYPE) ? 1 : 0;
2493 }
2494 else
2495 {
2496 m_firstField = 0;
2497 }
2498 }
2499 else
2500 {
2501 m_frameFieldHeight = m_frameHeight;
2502 m_frameFieldHeightInMb = m_picHeightInMb;
2503 m_downscaledFrameFieldHeightInMb4x = m_downscaledHeightInMb4x;
2504 m_downscaledFrameFieldHeightInMb16x = m_downscaledHeightInMb16x;
2505 m_downscaledFrameFieldHeightInMb32x = m_downscaledHeightInMb32x;
2506 m_firstField = 1;
2507 m_currEncBbSet = MB_ENC_Frame_BB;
2508 }
2509
2510 if (picParams->FieldFrameCodingFlag)
2511 { // Mbaff
2512 seqParams->mb_adaptive_frame_field_flag = 1;
2513 m_mbaffEnabled = 1;
2514 }
2515 else
2516 {
2517 seqParams->mb_adaptive_frame_field_flag = 0;
2518 m_mbaffEnabled = 0;
2519 }
2520
2521 // P/B frames with empty ref lists are internally encoded as I frames,
2522 // while picture header packing remains the original value
2523 m_pictureCodingType = picParams->CodingType;
2524
2525 bool emptyRefFrmList = true;
2526 for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
2527 {
2528 if (picParams->RefFrameList[i].PicFlags != PICTURE_INVALID)
2529 {
2530 emptyRefFrmList = false;
2531 break;
2532 }
2533 }
2534
2535 if (emptyRefFrmList && m_pictureCodingType != I_TYPE)
2536 {
2537 m_pictureCodingType = I_TYPE;
2538 }
2539
2540 avcRefList[currRefIdx]->bUsedAsRef = picParams->RefPicFlag;
2541 avcRefList[currRefIdx]->resBitstreamBuffer = m_resBitstreamBuffer;
2542
2543 for (uint8_t i = 0; i < 16; i++)
2544 {
2545 m_avcFrameStoreID[i].inUse = false;
2546 }
2547
2548 for (uint8_t i = 0; i < 16; i++)
2549 {
2550 avcPicIdx[i].bValid = false;
2551 if (picParams->RefFrameList[i].PicFlags != PICTURE_INVALID)
2552 {
2553 auto index = picParams->RefFrameList[i].FrameIdx;
2554 uint8_t duplicatedIdx = 0;
2555 for (uint8_t ii = 0; ii < i; ii++)
2556 {
2557 if (avcPicIdx[ii].bValid && index == picParams->RefFrameList[ii].FrameIdx)
2558 {
2559 duplicatedIdx = 1;
2560 break;
2561 }
2562 }
2563 if (duplicatedIdx)
2564 {
2565 continue;
2566 }
2567
2568 avcRefList[index]->RefPic.PicFlags =
2569 CodecHal_CombinePictureFlags(avcRefList[index]->RefPic, picParams->RefFrameList[i]);
2570 avcRefList[index]->iFieldOrderCnt[0] = picParams->FieldOrderCntList[i][0];
2571 avcRefList[index]->iFieldOrderCnt[1] = picParams->FieldOrderCntList[i][1];
2572 avcPicIdx[i].bValid = true;
2573 avcPicIdx[i].ucPicIdx = index;
2574 if (prevPic.PicFlags != PICTURE_INVALID)
2575 {
2576 uint8_t ii;
2577 for (ii = 0; ii < avcRefList[prevRefIdx]->ucNumRef; ii++)
2578 {
2579 if (index == avcRefList[prevRefIdx]->RefList[ii].FrameIdx)
2580 {
2581 if (avcRefList[index]->ucFrameId == 0x1f)
2582 {
2583 // Should never happen, something must be wrong
2584 CODECHAL_ENCODE_ASSERT(false);
2585 avcRefList[index]->ucFrameId = 0;
2586 }
2587 m_avcFrameStoreID[avcRefList[index]->ucFrameId].inUse = true;
2588 break;
2589 }
2590 }
2591 if (ii == avcRefList[prevRefIdx]->ucNumRef)
2592 {
2593 avcRefList[index]->ucFrameId = 0x1f;
2594 }
2595 }
2596 }
2597 }
2598
2599 // Save the current RefList
2600 uint8_t ii = 0;
2601 for (uint8_t i = 0; i < 16; i++)
2602 {
2603 if (avcPicIdx[i].bValid)
2604 {
2605 avcRefList[currRefIdx]->RefList[ii] = picParams->RefFrameList[i];
2606 ii++;
2607 }
2608 }
2609 avcRefList[currRefIdx]->ucNumRef = ii;
2610 m_currRefList = avcRefList[currRefIdx];
2611
2612 if (m_codecFunction == CODECHAL_FUNCTION_ENC)
2613 {
2614 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encodeParams.presMbCodeSurface);
2615 m_resMbCodeSurface = *(m_encodeParams.presMbCodeSurface);
2616 }
2617 else if (m_codecFunction == CODECHAL_FUNCTION_ENC_PAK)
2618 {
2619 if (m_encodeParams.presMbCodeSurface == nullptr ||
2620 Mos_ResourceIsNull(m_encodeParams.presMbCodeSurface))
2621 {
2622 // the actual MbCode/MvData surface to be allocated later
2623 m_trackedBuf->SetAllocationFlag(true);
2624 }
2625 else
2626 {
2627 m_resMbCodeSurface = *(m_encodeParams.presMbCodeSurface);
2628 m_resMvDataSurface = *(m_encodeParams.presMbCodeSurface);
2629 }
2630 }
2631 else if (CodecHalIsFeiEncode(m_codecFunction))
2632 {
2633 CodecEncodeAvcFeiPicParams *feiPicParams;
2634
2635 feiPicParams = (CodecEncodeAvcFeiPicParams *)m_encodeParams.pFeiPicParams;
2636 CODECHAL_ENCODE_CHK_NULL_RETURN(feiPicParams);
2637
2638 // Use app provided buffer if available. For FEI_ENC and FEI_PAK, MBCodeMvEnable needs to be set to true
2639 if (feiPicParams->MbCodeMvEnable)
2640 {
2641 m_resMbCodeSurface = feiPicParams->resMBCode;
2642 m_resMvDataSurface = feiPicParams->resMVData;
2643
2644 // Inside the AvcRefList, mbCodesurface and mvdatasurface are stored at frame basis,
2645 // For FEI, mbcode and mv data buffer are provided separately for each field picture and we need to store them separately.
2646 if (CodecHal_PictureIsTopField(picParams->CurrOriginalPic))
2647 {
2648 avcRefList[currRefIdx]->resRefTopFieldMbCodeBuffer = m_resMbCodeSurface;
2649 avcRefList[currRefIdx]->resRefTopFieldMvDataBuffer = m_resMvDataSurface;
2650 }
2651 else if (CodecHal_PictureIsBottomField(picParams->CurrOriginalPic))
2652 {
2653 avcRefList[currRefIdx]->resRefBotFieldMbCodeBuffer = m_resMbCodeSurface;
2654 avcRefList[currRefIdx]->resRefBotFieldMvDataBuffer = m_resMvDataSurface;
2655 }
2656
2657 avcRefList[currRefIdx]->resRefMbCodeBuffer = m_resMbCodeSurface;
2658 avcRefList[currRefIdx]->resRefMvDataBuffer = m_resMvDataSurface;
2659 }
2660 else
2661 {
2662 // the actual MbCode/MvData surface to be allocated later
2663 m_trackedBuf->SetAllocationFlag(true);
2664 }
2665
2666 if (feiPicParams->DistortionEnable)
2667 {
2668 m_resDistortionBuffer = feiPicParams->resDistortion;
2669 }
2670 }
2671
2672 SetFrameStoreIds(currRefIdx);
2673
2674 avcRefList[currRefIdx]->iFieldOrderCnt[0] = picParams->CurrFieldOrderCnt[0];
2675 avcRefList[currRefIdx]->iFieldOrderCnt[1] = picParams->CurrFieldOrderCnt[1];
2676 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);
2677
2678 m_hmeEnabled = m_hmeSupported && m_pictureCodingType != I_TYPE;
2679 m_16xMeEnabled = m_16xMeSupported && m_pictureCodingType != I_TYPE;
2680 m_32xMeEnabled = m_32xMeSupported && m_pictureCodingType != I_TYPE;
2681
2682 if (m_pictureCodingType == B_TYPE)
2683 {
2684 GetDistScaleFactor();
2685 m_biWeight = GetBiWeight(
2686 m_distScaleFactorList0[0],
2687 m_avcPicParam->weighted_bipred_idc);
2688 }
2689
2690 m_verticalLineStride = CODECHAL_VLINESTRIDE_FRAME;
2691 m_verticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_TOP_FIELD;
2692 m_mbcodeBottomFieldOffset = 0;
2693 m_mvBottomFieldOffset = 0;
2694 m_meDistortionBottomFieldOffset = 0;
2695 m_meMvBottomFieldOffset = 0;
2696 m_meMv16xBottomFieldOffset = 0;
2697 m_meMv32xBottomFieldOffset = 0;
2698 m_sliceMapBottomFieldOffset = 0;
2699 if (m_hmeKernel)
2700 {
2701 m_hmeKernel->Set4xMeMvBottomFieldOffset(0);
2702 m_hmeKernel->Set16xMeMvBottomFieldOffset(0);
2703 m_hmeKernel->Set32xMeMvBottomFieldOffset(0);
2704 m_hmeKernel->SetDistortionBottomFieldOffset(0);
2705 }
2706
2707 if (CodecHal_PictureIsField(m_currOriginalPic))
2708 {
2709 m_verticalLineStride = CODECHAL_VLINESTRIDE_FIELD;
2710 m_frameHeight = m_frameFieldHeightInMb * 2 * 16;
2711 m_picHeightInMb = (uint16_t)(m_frameHeight / 16);
2712 if (CodecHal_PictureIsBottomField(m_currOriginalPic))
2713 {
2714 m_sliceMapBottomFieldOffset = MOS_ALIGN_CEIL((m_picWidthInMb + 1) * sizeof(uint32_t), 64) * m_frameFieldHeightInMb;
2715 m_verticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_BOT_FIELD;
2716
2717 if (CodecHalIsFeiEncode(m_codecFunction))
2718 {
2719 CodecEncodeAvcFeiPicParams *feiPicParams;
2720
2721 feiPicParams = (CodecEncodeAvcFeiPicParams *)m_encodeParams.pFeiPicParams;
2722 CODECHAL_ENCODE_CHK_NULL_RETURN(feiPicParams);
2723
2724 // for user provided MbCode and Mv data buffer, set BottomFieldOffset to 0
2725 if (feiPicParams->MbCodeMvEnable)
2726 {
2727 m_mbcodeBottomFieldOffset = 0;
2728 m_mvBottomFieldOffset = 0;
2729 }
2730 else
2731 {
2732 m_mbcodeBottomFieldOffset = m_frameFieldHeightInMb * m_picWidthInMb * 64;
2733 m_mvBottomFieldOffset =
2734 MOS_ALIGN_CEIL(m_frameFieldHeightInMb * m_picWidthInMb * (32 * 4), CODECHAL_PAGE_SIZE);
2735 }
2736 }
2737 else
2738 {
2739 m_mbcodeBottomFieldOffset = m_frameFieldHeightInMb * m_picWidthInMb * 64;
2740 m_mvBottomFieldOffset =
2741 MOS_ALIGN_CEIL(m_frameFieldHeightInMb * m_picWidthInMb * (32 * 4), CODECHAL_PAGE_SIZE);
2742 }
2743
2744 m_meDistortionBottomFieldOffset =
2745 MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64) *
2746 MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4 * 10), 8);
2747 m_meMvBottomFieldOffset =
2748 MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64) *
2749 (m_downscaledFrameFieldHeightInMb4x * 4);
2750 if (m_16xMeEnabled)
2751 {
2752 m_meMv16xBottomFieldOffset =
2753 MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64) *
2754 (m_downscaledFrameFieldHeightInMb16x * 4);
2755 if (m_32xMeEnabled)
2756 {
2757 m_meMv32xBottomFieldOffset =
2758 MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64) *
2759 (m_downscaledFrameFieldHeightInMb32x * 4);
2760 }
2761 }
2762
2763 if (m_hmeKernel)
2764 {
2765 m_hmeKernel->SetDistortionBottomFieldOffset(
2766 MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64) *
2767 MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4 * 10), 8));
2768 m_hmeKernel->Set4xMeMvBottomFieldOffset(
2769 MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64) *
2770 (m_downscaledFrameFieldHeightInMb4x * 4));
2771 if (m_hmeKernel->Is16xMeEnabled())
2772 {
2773 m_hmeKernel->Set16xMeMvBottomFieldOffset(
2774 MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64) *
2775 (m_downscaledFrameFieldHeightInMb16x * 4));
2776 if (m_hmeKernel->Is32xMeEnabled())
2777 {
2778 m_hmeKernel->Set32xMeMvBottomFieldOffset(
2779 MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64) *
2780 (m_downscaledFrameFieldHeightInMb32x * 4));
2781 }
2782 }
2783 }
2784 }
2785 }
2786
2787 return eStatus;
2788 }
2789
EncodeMeKernel(EncodeBrcBuffers * brcBuffers,HmeLevel hmeLevel)2790 MOS_STATUS CodechalEncodeAvcBase::EncodeMeKernel(
2791 EncodeBrcBuffers *brcBuffers,
2792 HmeLevel hmeLevel)
2793 {
2794 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2795
2796 CODECHAL_ENCODE_FUNCTION_ENTER;
2797
2798 PerfTagSetting perfTag;
2799 perfTag.Value = 0;
2800 perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
2801 perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_ME_KERNEL;
2802 perfTag.PictureCodingType = m_pictureCodingType;
2803 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
2804 // Each ME kernel buffer counts as a separate perf task
2805 m_osInterface->pfnResetPerfBufferID(m_osInterface);
2806
2807 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;
2808
2809 bool vdencMeInUse = false;
2810 if (m_vdencEnabled && (encFunctionType == CODECHAL_MEDIA_STATE_4X_ME))
2811 {
2812 vdencMeInUse = true;
2813 encFunctionType = CODECHAL_MEDIA_STATE_ME_VDENC_STREAMIN;
2814 }
2815
2816 uint32_t krnStateIdx = vdencMeInUse ? CODECHAL_ENCODE_ME_IDX_VDENC : ((m_pictureCodingType == P_TYPE) ? CODECHAL_ENCODE_ME_IDX_P : CODECHAL_ENCODE_ME_IDX_B);
2817 auto kernelState = &m_meKernelStates[krnStateIdx];
2818
2819 // If Single Task Phase is not enabled, use BT count for the kernel state.
2820 if (m_firstTaskInPhase || !m_singleTaskPhaseSupported)
2821 {
2822 uint32_t maxBtCount = m_singleTaskPhaseSupported ? m_maxBtCount : kernelState->KernelParams.iBTCount;
2823 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
2824 m_stateHeapInterface,
2825 maxBtCount));
2826 m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount);
2827 CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
2828 }
2829
2830 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
2831 m_stateHeapInterface,
2832 kernelState,
2833 false,
2834 0,
2835 false,
2836 m_storeData));
2837
2838 MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
2839 MOS_ZeroMemory(&idParams, sizeof(idParams));
2840 idParams.pKernelState = kernelState;
2841 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
2842 m_stateHeapInterface,
2843 1,
2844 &idParams));
2845
2846 // Setup AVC Curbe
2847 MeCurbeParams meParams;
2848 MOS_ZeroMemory(&meParams, sizeof(meParams));
2849 meParams.hmeLvl = hmeLevel;
2850 meParams.pKernelState = kernelState;
2851
2852 if (!m_useCommonKernel)
2853 {
2854 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeMe(&meParams));
2855 }
2856
2857 CODECHAL_DEBUG_TOOL(
2858 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2859 encFunctionType,
2860 MHW_DSH_TYPE,
2861 kernelState));
2862 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
2863 encFunctionType,
2864 kernelState));
2865 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2866 encFunctionType,
2867 MHW_ISH_TYPE,
2868 kernelState));)
2869
2870 MOS_COMMAND_BUFFER cmdBuffer;
2871 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
2872
2873 SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
2874 sendKernelCmdsParams.EncFunctionType = encFunctionType;
2875 sendKernelCmdsParams.pKernelState = kernelState;
2876
2877 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
2878
2879 // Add binding table
2880 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
2881 m_stateHeapInterface,
2882 kernelState));
2883
2884 //Add surface states
2885 MeSurfaceParams meSurfaceParams;
2886 MOS_ZeroMemory(&meSurfaceParams, sizeof(meSurfaceParams));
2887 meSurfaceParams.dwNumRefIdxL0ActiveMinus1 = m_avcSliceParams->num_ref_idx_l0_active_minus1;
2888 meSurfaceParams.dwNumRefIdxL1ActiveMinus1 = m_avcSliceParams->num_ref_idx_l1_active_minus1;
2889 meSurfaceParams.pL0RefFrameList = &(m_avcSliceParams->RefPicList[LIST_0][0]);
2890 meSurfaceParams.pL1RefFrameList = &(m_avcSliceParams->RefPicList[LIST_1][0]);
2891 meSurfaceParams.ppRefList = &m_refList[0];
2892 meSurfaceParams.pPicIdx = &m_picIdx[0];
2893 meSurfaceParams.pCurrOriginalPic = &m_currOriginalPic;
2894 meSurfaceParams.ps4xMeMvDataBuffer = &m_4xMeMvDataBuffer;
2895 meSurfaceParams.dw4xMeMvBottomFieldOffset = (uint32_t)m_meMvBottomFieldOffset;
2896 meSurfaceParams.ps16xMeMvDataBuffer = &m_16xMeMvDataBuffer;
2897 meSurfaceParams.dw16xMeMvBottomFieldOffset = (uint32_t)m_meMv16xBottomFieldOffset;
2898 meSurfaceParams.ps32xMeMvDataBuffer = &m_32xMeMvDataBuffer;
2899 meSurfaceParams.dw32xMeMvBottomFieldOffset = (uint32_t)m_meMv32xBottomFieldOffset;
2900 meSurfaceParams.dw4xScaledBottomFieldOffset = (uint32_t)m_scaledBottomFieldOffset;
2901 meSurfaceParams.dw16xScaledBottomFieldOffset = (uint32_t)m_scaled16xBottomFieldOffset;
2902 meSurfaceParams.dw32xScaledBottomFieldOffset = (uint32_t)m_scaled32xBottomFieldOffset;
2903 meSurfaceParams.psMeDistortionBuffer = &m_4xMeDistortionBuffer;
2904 meSurfaceParams.dwMeDistortionBottomFieldOffset = (uint32_t)m_meDistortionBottomFieldOffset;
2905 if (nullptr != brcBuffers)
2906 {
2907 meSurfaceParams.psMeBrcDistortionBuffer = &brcBuffers->sMeBrcDistortionBuffer;
2908 meSurfaceParams.dwMeBrcDistortionBottomFieldOffset = brcBuffers->dwMeBrcDistortionBottomFieldOffset;
2909 }
2910 meSurfaceParams.psMeVdencStreamInBuffer = &m_resVdencStreamInBuffer[m_currRecycledBufIdx];
2911 meSurfaceParams.dwDownscaledWidthInMb = (hmeLevel == HME_LEVEL_32x) ? m_downscaledWidthInMb32x : (hmeLevel == HME_LEVEL_16x) ? m_downscaledWidthInMb16x : m_downscaledWidthInMb4x;
2912 meSurfaceParams.dwDownscaledHeightInMb = (hmeLevel == HME_LEVEL_32x) ? m_downscaledFrameFieldHeightInMb32x : (hmeLevel == HME_LEVEL_16x) ? m_downscaledFrameFieldHeightInMb16x : m_downscaledFrameFieldHeightInMb4x;
2913 meSurfaceParams.dwVerticalLineStride = m_verticalLineStride;
2914 meSurfaceParams.dwVerticalLineStrideOffset = m_verticalLineStrideOffset;
2915 meSurfaceParams.b32xMeInUse = (hmeLevel == HME_LEVEL_32x) ? true : false;
2916 meSurfaceParams.b16xMeInUse = (hmeLevel == HME_LEVEL_16x) ? true : false;
2917 meSurfaceParams.b32xMeEnabled = m_32xMeEnabled;
2918 meSurfaceParams.b16xMeEnabled = m_16xMeEnabled;
2919 meSurfaceParams.bVdencStreamInEnabled = m_vdencEnabled && (m_16xMeSupported || m_staticFrameDetectionInUse);
2920 meSurfaceParams.pMeBindingTable = &m_meBindingTable;
2921 meSurfaceParams.pKernelState = kernelState;
2922 meSurfaceParams.dwVDEncStreamInSurfaceSize = MOS_BYTES_TO_DWORDS(m_picHeightInMb * m_picWidthInMb * 64);
2923
2924 if (!m_useCommonKernel)
2925 {
2926 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendMeSurfaces(&cmdBuffer, &meSurfaceParams));
2927 }
2928
2929 // Dump SSH for ME kernel
2930 CODECHAL_DEBUG_TOOL(
2931 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2932 encFunctionType,
2933 MHW_SSH_TYPE,
2934 kernelState)));
2935
2936 /* zero out the mv data memory and me distortion buffer for the driver ULT
2937 kernel only writes out this data used for current frame, in some cases the the data used for
2938 previous frames would be left in the buffer (for example, the L1 mv for B frame would still show
2939 in the P frame mv data buffer */
2940
2941 /* Zeroing out the buffers has perf impact, so zero it out only when dumps are actually enabled */
2942
2943 CODECHAL_DEBUG_TOOL(
2944 CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface);
2945 uint8_t * data;
2946 uint32_t size;
2947 bool driverMeDumpEnabled;
2948
2949 driverMeDumpEnabled = m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel4xMe) ||
2950 m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel16xMe) ||
2951 m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel32xMe);
2952
2953 if (driverMeDumpEnabled) {
2954 MOS_LOCK_PARAMS lockFlags;
2955 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
2956 lockFlags.WriteOnly = 1;
2957
2958 switch (hmeLevel)
2959 {
2960 case HME_LEVEL_32x:
2961 data = (uint8_t *)m_osInterface->pfnLockResource(
2962 m_osInterface,
2963 &m_32xMeMvDataBuffer.OsResource,
2964 &lockFlags);
2965 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
2966 size = MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64) *
2967 (m_downscaledHeightInMb32x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
2968 MOS_ZeroMemory(data, size);
2969 m_osInterface->pfnUnlockResource(
2970 m_osInterface,
2971 &m_32xMeMvDataBuffer.OsResource);
2972 break;
2973 case HME_LEVEL_16x:
2974 data = (uint8_t *)m_osInterface->pfnLockResource(
2975 m_osInterface,
2976 &m_16xMeMvDataBuffer.OsResource,
2977 &lockFlags);
2978 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
2979 size = MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64) *
2980 (m_downscaledHeightInMb16x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
2981 MOS_ZeroMemory(data, size);
2982 m_osInterface->pfnUnlockResource(
2983 m_osInterface,
2984 &m_16xMeMvDataBuffer.OsResource);
2985 break;
2986 case HME_LEVEL_4x:
2987 if (!m_vdencEnabled)
2988 {
2989 data = (uint8_t *)m_osInterface->pfnLockResource(
2990 m_osInterface,
2991 &m_4xMeMvDataBuffer.OsResource,
2992 &lockFlags);
2993 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
2994 size = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64) *
2995 (m_downscaledHeightInMb4x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
2996 MOS_ZeroMemory(data, size);
2997 m_osInterface->pfnUnlockResource(
2998 m_osInterface,
2999 &m_4xMeMvDataBuffer.OsResource);
3000 }
3001 break;
3002 default:
3003 return MOS_STATUS_INVALID_PARAMETER;
3004 }
3005
3006 // zeroing out ME dist buffer
3007 if (m_4xMeDistortionBufferSupported)
3008 {
3009 data = (uint8_t *)m_osInterface->pfnLockResource(
3010 m_osInterface, &m_4xMeDistortionBuffer.OsResource, &lockFlags);
3011 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3012 size = m_4xMeDistortionBuffer.dwHeight * m_4xMeDistortionBuffer.dwPitch;
3013 MOS_ZeroMemory(data, size);
3014 m_osInterface->pfnUnlockResource(
3015 m_osInterface,
3016 &m_4xMeDistortionBuffer.OsResource);
3017 }
3018 });
3019
3020 uint32_t scalingFactor = (hmeLevel == HME_LEVEL_32x) ? SCALE_FACTOR_32x : (hmeLevel == HME_LEVEL_16x) ? SCALE_FACTOR_16x : SCALE_FACTOR_4x;
3021
3022 uint32_t resolutionX = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / scalingFactor);
3023 uint32_t resolutionY = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scalingFactor);
3024
3025 CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
3026 MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
3027 walkerCodecParams.WalkerMode = m_walkerMode;
3028 walkerCodecParams.dwResolutionX = resolutionX;
3029 walkerCodecParams.dwResolutionY = resolutionY;
3030 walkerCodecParams.bNoDependency = true;
3031 walkerCodecParams.bMbaff = m_mbaffEnabled;
3032 walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported;
3033 walkerCodecParams.ucGroupId = m_groupId;
3034
3035 MHW_WALKER_PARAMS walkerParams;
3036 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
3037 m_hwInterface,
3038 &walkerParams,
3039 &walkerCodecParams));
3040
3041 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd(
3042 &cmdBuffer,
3043 &walkerParams));
3044
3045 CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));
3046
3047 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks(
3048 m_stateHeapInterface,
3049 kernelState));
3050 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
3051 {
3052 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
3053 m_stateHeapInterface));
3054 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
3055 }
3056
3057 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
3058 &cmdBuffer,
3059 encFunctionType,
3060 nullptr)));
3061
3062 m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase);
3063
3064 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
3065
3066 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
3067 {
3068 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface->pOsContext);
3069 m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
3070 m_lastTaskInPhase = false;
3071 }
3072
3073 return eStatus;
3074 }
3075
SetSliceStructs()3076 MOS_STATUS CodechalEncodeAvcBase::SetSliceStructs()
3077 {
3078 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3079 CODECHAL_ENCODE_FUNCTION_ENTER;
3080
3081 auto slcParams = m_avcSliceParams;
3082 auto seqParams = m_avcSeqParam;
3083 auto picParams = m_avcPicParam;
3084
3085 // Save the QP value
3086 if (CodecHal_PictureIsBottomField(picParams->CurrOriginalPic))
3087 {
3088 m_refList[m_currReconstructedPic.FrameIdx]->ucQPValue[1] =
3089 picParams->pic_init_qp_minus26 + 26 + slcParams->slice_qp_delta;
3090 }
3091 else
3092 {
3093 m_refList[m_currReconstructedPic.FrameIdx]->ucQPValue[0] =
3094 picParams->pic_init_qp_minus26 + 26 + slcParams->slice_qp_delta;
3095 }
3096
3097 uint32_t numMbsInPrevSlice = slcParams->NumMbsForSlice; // Initiailize to num mbs in first slice
3098 uint32_t numMbsForFirstSlice;
3099
3100 for (uint32_t sliceCount = 0; sliceCount < m_numSlices; sliceCount++)
3101 {
3102 if (m_sliceStructCaps != CODECHAL_SLICE_STRUCT_ARBITRARYMBSLICE)
3103 {
3104 if (sliceCount == 0)
3105 {
3106 numMbsForFirstSlice = slcParams->NumMbsForSlice;
3107 // In current kernel, the same MB number in the slice must be number of MB rows.
3108 if (numMbsForFirstSlice % m_picWidthInMb)
3109 {
3110 eStatus = MOS_STATUS_INVALID_PARAMETER;
3111 return eStatus;
3112 }
3113 m_sliceHeight = numMbsForFirstSlice / m_picWidthInMb;
3114 // Slice height should be in power of 2
3115 if (m_sliceStructCaps == CODECHAL_SLICE_STRUCT_POW2ROWS && (m_sliceHeight & (m_sliceHeight - 1)))
3116 {
3117 // app can only pass orig numMBs in picture for single slice, set slice height to the nearest pow2
3118 if (m_numSlices == 1)
3119 {
3120 uint16_t sliceHeightPow2 = 1;
3121 while (sliceHeightPow2 < m_sliceHeight)
3122 {
3123 sliceHeightPow2 <<= 1;
3124 }
3125 m_sliceHeight = sliceHeightPow2;
3126 }
3127 else
3128 {
3129 eStatus = MOS_STATUS_INVALID_PARAMETER;
3130 return eStatus;
3131 }
3132 }
3133 }
3134 // 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
3135 else
3136 {
3137 if ((sliceCount < m_numSlices - 1 && numMbsForFirstSlice != slcParams->NumMbsForSlice) ||
3138 (sliceCount == m_numSlices - 1 && numMbsForFirstSlice < slcParams->NumMbsForSlice))
3139 {
3140 eStatus = MOS_STATUS_INVALID_PARAMETER;
3141 return eStatus;
3142 }
3143 }
3144
3145 if (slcParams->first_mb_in_slice != numMbsForFirstSlice * sliceCount)
3146 {
3147 eStatus = MOS_STATUS_INVALID_PARAMETER;
3148 return eStatus;
3149 }
3150 }
3151 else // SLICE_STRUCT_ARBITRARYMBSLICE
3152 {
3153 uint8_t ppsIdx = m_avcSliceParams->pic_parameter_set_id;
3154 uint8_t refPicListIdx = m_avcSliceParams[ppsIdx].RefPicList[0][0].FrameIdx;
3155 uint8_t refFrameListIdx = m_avcPicParam[ppsIdx].RefFrameList[refPicListIdx].FrameIdx;
3156
3157 bool dirtyRoiEnabled = (m_pictureCodingType == P_TYPE && m_avcPicParams[ppsIdx]->NumDirtyROI > 0 && m_prevReconFrameIdx == refFrameListIdx);
3158
3159 if (m_mfeEnabled && m_numSlices > 1)
3160 {
3161 m_arbitraryNumMbsInSlice = 1;
3162 if (sliceCount == 0)
3163 {
3164 m_sliceHeight = slcParams->NumMbsForSlice / m_picWidthInMb;
3165 }
3166 }
3167 else if ((slcParams->NumMbsForSlice % m_picWidthInMb) || // If slice is partial MB row,
3168 ((sliceCount < m_numSlices - 1) && (numMbsInPrevSlice != slcParams->NumMbsForSlice)) || // OR not the last slice and num mbs is not same as prev slice
3169 ((sliceCount == m_numSlices - 1) && ((numMbsInPrevSlice < slcParams->NumMbsForSlice) || // OR it is the last slice and num mbs is not less than prev slice
3170 (MEDIA_IS_WA(m_waTable, WaArbitraryNumMbsInSlice) && (m_numSlices > 16) &&
3171 (!m_vdencEnabled) && (!dirtyRoiEnabled)))))
3172 {
3173 m_arbitraryNumMbsInSlice = 1; // then set flag to use sliceMapSurface
3174 m_sliceHeight = 1; // Slice height doesn't matter if using slicemap just set to any non-zero value.
3175 }
3176 else if ((m_numSlices == 1) || (sliceCount == 0))
3177 {
3178 m_sliceHeight = slcParams->NumMbsForSlice / m_picWidthInMb;
3179 m_arbitraryNumMbsInSlice = 0;
3180 }
3181 numMbsInPrevSlice = slcParams->NumMbsForSlice;
3182 }
3183
3184 if ((picParams->pic_init_qp_minus26 + 26 + slcParams->slice_qp_delta) > CODECHAL_ENCODE_AVC_MAX_SLICE_QP)
3185 {
3186 slcParams->slice_qp_delta = CODECHAL_ENCODE_AVC_MAX_SLICE_QP - (picParams->pic_init_qp_minus26 + 26);
3187 }
3188 else
3189 {
3190 slcParams->slice_qp_delta = slcParams->slice_qp_delta;
3191 }
3192 slcParams->redundant_pic_cnt = 0;
3193 slcParams->sp_for_switch_flag = 0;
3194 slcParams->slice_qs_delta = 0;
3195 slcParams->ref_pic_list_reordering_flag_l0 = 0;
3196 slcParams->ref_pic_list_reordering_flag_l1 = 0;
3197 slcParams->adaptive_ref_pic_marking_mode_flag = 0;
3198 slcParams->no_output_of_prior_pics_flag = 0;
3199 slcParams->redundant_pic_cnt = 0;
3200
3201 slcParams->MaxFrameNum =
3202 1 << (seqParams[picParams->seq_parameter_set_id].log2_max_frame_num_minus4 + 4);
3203 slcParams->frame_num = m_frameNum;
3204 slcParams->field_pic_flag = picParams->FieldCodingFlag;
3205 slcParams->bottom_field_flag =
3206 (CodecHal_PictureIsBottomField(picParams->CurrOriginalPic)) ? 1 : 0;
3207
3208 if (m_pictureCodingType != I_TYPE)
3209 {
3210 for (uint8_t i = 0; i < (slcParams->num_ref_idx_l0_active_minus1 + 1); i++)
3211 {
3212 slcParams->PicOrder[0][i].Picture.FrameIdx =
3213 m_picIdx[slcParams->RefPicList[0][i].FrameIdx].ucPicIdx;
3214 slcParams->PicOrder[0][i].Picture.PicFlags =
3215 slcParams->RefPicList[0][i].PicFlags;
3216 }
3217 }
3218 if (m_pictureCodingType == B_TYPE)
3219 {
3220 for (uint8_t i = 0; i < (slcParams->num_ref_idx_l1_active_minus1 + 1); i++)
3221 {
3222 slcParams->PicOrder[1][i].Picture.FrameIdx =
3223 m_picIdx[slcParams->RefPicList[1][i].FrameIdx].ucPicIdx;
3224 slcParams->PicOrder[1][i].Picture.PicFlags =
3225 slcParams->RefPicList[1][i].PicFlags;
3226 }
3227 }
3228 slcParams++;
3229 }
3230
3231 if (eStatus == MOS_STATUS_INVALID_PARAMETER)
3232 {
3233 CODECHAL_ENCODE_ASSERTMESSAGE("Invalid slice parameters.");
3234 }
3235 return eStatus;
3236 }
3237
SetMfxPipeModeSelectParams(const CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS & genericParam,MHW_VDBOX_PIPE_MODE_SELECT_PARAMS & param)3238 void CodechalEncodeAvcBase::SetMfxPipeModeSelectParams(
3239 const CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS &genericParam,
3240 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS & param)
3241 {
3242 // set MFX_PIPE_MODE_SELECT values
3243 param = {};
3244 param.Mode = m_mode;
3245 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
3246 param.bVdencEnabled = m_vdencEnabled;
3247 param.bDeblockerStreamOutEnable = genericParam.bDeblockerStreamOutEnable;
3248 param.bStreamOutEnabledExtEnabled = genericParam.bPerMBStreamOutEnable;
3249 param.bPostDeblockOutEnable = genericParam.bPostDeblockOutEnable;
3250 param.bPreDeblockOutEnable = genericParam.bPreDeblockOutEnable;
3251 param.bDynamicSliceEnable = m_avcSeqParam->EnableSliceLevelRateCtrl;
3252 param.bVdencStreamInEnable = m_vdencStreamInEnabled;
3253 param.bTlbPrefetchEnable = m_tlbPrefetchEnable;
3254 param.ChromaType = m_avcSeqParam->chroma_format_idc;
3255 param.Format = m_rawSurfaceToPak->Format;
3256 }
3257
SetMfxPipeBufAddrStateParams(CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS genericParam,MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & param)3258 MOS_STATUS CodechalEncodeAvcBase::SetMfxPipeBufAddrStateParams(
3259 CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS genericParam,
3260 MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & param)
3261 {
3262 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3263
3264 param.Mode = m_mode;
3265 param.psPreDeblockSurface = genericParam.psPreDeblockSurface;
3266 param.psPostDeblockSurface = genericParam.psPostDeblockSurface;
3267
3268 param.psRawSurface = m_rawSurfaceToPak;
3269 param.presStreamOutBuffer = &m_resStreamOutBuffer[m_currRecycledBufIdx];
3270 param.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resDeblockingFilterRowStoreScratchBuffer;
3271 param.presMfdIntraRowStoreScratchBuffer = &m_intraRowStoreScratchBuffer;
3272 param.bVdencEnabled = m_vdencEnabled;
3273 param.presMacroblockIldbStreamOutBuffer1 = genericParam.presMacroblockIldbStreamOutBuffer1;
3274 param.presMacroblockIldbStreamOutBuffer2 = genericParam.presMacroblockIldbStreamOutBuffer2;
3275
3276 CODECHAL_DEBUG_TOOL(
3277 // PAK Input Raw Surface
3278 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
3279 m_rawSurfaceToPak,
3280 CodechalDbgAttr::attrEncodeRawInputSurface,
3281 "PAK_Input_SrcSurf")););
3282
3283 auto firstValidFrame = &m_reconSurface.OsResource;
3284
3285 // Setting invalid entries to nullptr
3286 for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
3287 param.presReferences[i] = nullptr;
3288
3289 uint8_t firstValidFrameId = CODEC_AVC_MAX_NUM_REF_FRAME;
3290 uint8_t numrefL0 = m_avcPicParam->num_ref_idx_l0_active_minus1 + 1;
3291 uint8_t numrefL1 = m_avcPicParam->num_ref_idx_l1_active_minus1 + 1;
3292
3293 for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
3294 {
3295 if (m_picIdx[i].bValid)
3296 {
3297 auto picIdx = m_picIdx[i].ucPicIdx;
3298 auto frameStoreId = m_refList[picIdx]->ucFrameId;
3299
3300 CodecHalGetResourceInfo(m_osInterface, &(m_refList[picIdx]->sRefReconBuffer));
3301 param.presReferences[frameStoreId] = &(m_refList[picIdx]->sRefReconBuffer.OsResource);
3302
3303 if (picIdx < firstValidFrameId)
3304 {
3305 firstValidFrameId = picIdx;
3306 firstValidFrame = param.presReferences[picIdx];
3307 }
3308
3309 }
3310 }
3311 CODECHAL_DEBUG_TOOL(
3312 MOS_SURFACE refSurface;
3313 for (uint8_t i = 0; i < numrefL0; i++)
3314 {
3315 if (m_pictureCodingType != I_TYPE && m_avcSliceParams->RefPicList[0][i].PicFlags != PICTURE_INVALID)
3316 {
3317 auto refPic = m_avcSliceParams->RefPicList[0][i];
3318 auto picIdx = m_picIdx[refPic.FrameIdx].ucPicIdx;
3319 auto frameStoreId = m_refList[picIdx]->ucFrameId;
3320 CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface);
3321
3322 MOS_ZeroMemory(&refSurface, sizeof(refSurface));
3323 refSurface.Format = Format_NV12;
3324 refSurface.OsResource = *(param.presReferences[frameStoreId]);
3325 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
3326 m_osInterface,
3327 &refSurface));
3328 m_debugInterface->m_refIndex = frameStoreId;
3329 std::string refSurfName = "RefSurfL0[" + std::to_string(static_cast<uint32_t>(i)) + "]";
3330 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
3331 &refSurface,
3332 CodechalDbgAttr::attrReferenceSurfaces,
3333 refSurfName.c_str()));
3334 }
3335 }
3336 for (uint8_t i = 0; i < numrefL1; i++)
3337 {
3338 if (m_pictureCodingType == B_TYPE && m_avcSliceParams->RefPicList[1][i].PicFlags != PICTURE_INVALID)
3339 {
3340 auto refPic = m_avcSliceParams->RefPicList[1][i];
3341 auto picIdx = m_picIdx[refPic.FrameIdx].ucPicIdx;
3342 auto frameStoreId = m_refList[picIdx]->ucFrameId;
3343 CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface);
3344 //MOS_SURFACE refSurface;
3345 MOS_ZeroMemory(&refSurface, sizeof(refSurface));
3346 refSurface.Format = Format_NV12;
3347 refSurface.OsResource = *(param.presReferences[frameStoreId]);
3348 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
3349 m_osInterface,
3350 &refSurface));
3351 m_debugInterface->m_refIndex = frameStoreId;
3352 std::string refSurfName = "RefSurfL1[" + std::to_string(static_cast<uint32_t>(i)) + "]";
3353 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
3354 &refSurface,
3355 CodechalDbgAttr::attrReferenceSurfaces,
3356 refSurfName.c_str()));
3357 }
3358 }
3359
3360 );
3361
3362 for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
3363 {
3364 // error concealment for the unset reference addresses
3365 if (!param.presReferences[i])
3366 {
3367 param.presReferences[i] = firstValidFrame;
3368 }
3369 }
3370
3371 if (m_sliceSizeStreamoutSupported)
3372 {
3373 param.presSliceSizeStreamOutBuffer = &m_pakSliceSizeStreamoutBuffer;
3374 }
3375 return eStatus;
3376 }
3377
SetMfxIndObjBaseAddrStateParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS & param)3378 void CodechalEncodeAvcBase::SetMfxIndObjBaseAddrStateParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS ¶m)
3379 {
3380 MOS_ZeroMemory(¶m, sizeof(param));
3381 param.Mode = CODECHAL_ENCODE_MODE_AVC;
3382 param.presPakBaseObjectBuffer = &m_resBitstreamBuffer;
3383 param.dwPakBaseObjectSize = m_bitstreamUpperBound;
3384 }
3385
SetMfxBspBufBaseAddrStateParams(MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS & param)3386 void CodechalEncodeAvcBase::SetMfxBspBufBaseAddrStateParams(MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS ¶m)
3387 {
3388 MOS_ZeroMemory(¶m, sizeof(param));
3389 param.presBsdMpcRowStoreScratchBuffer = &m_resMPCRowStoreScratchBuffer;
3390 }
3391
SetMfxQmStateParams(MHW_VDBOX_QM_PARAMS & qmParams,MHW_VDBOX_QM_PARAMS & fqmParams)3392 void CodechalEncodeAvcBase::SetMfxQmStateParams(MHW_VDBOX_QM_PARAMS &qmParams, MHW_VDBOX_QM_PARAMS &fqmParams)
3393 {
3394 MOS_ZeroMemory(&qmParams, sizeof(qmParams));
3395 MOS_ZeroMemory(&fqmParams, sizeof(fqmParams));
3396
3397 qmParams.Standard = CODECHAL_AVC;
3398 qmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists;
3399
3400 fqmParams.Standard = CODECHAL_AVC;
3401 fqmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists;
3402 }
3403
SetMfxAvcImgStateParams(MHW_VDBOX_AVC_IMG_PARAMS & param)3404 void CodechalEncodeAvcBase::SetMfxAvcImgStateParams(MHW_VDBOX_AVC_IMG_PARAMS ¶m)
3405 {
3406 param = {};
3407 param.ucCurrPass = m_currPass;
3408 param.pEncodeAvcPicParams = m_avcPicParam;
3409 param.pEncodeAvcSeqParams = m_avcSeqParam;
3410 param.pEncodeAvcSliceParams = m_avcSliceParams;
3411 param.wPicWidthInMb = m_picWidthInMb;
3412 param.wPicHeightInMb = m_picHeightInMb;
3413 param.ppRefList = &(m_refList[0]);
3414 param.pPicIdx = &(m_picIdx[0]);
3415 param.dwTqEnabled = m_trellisQuantParams.dwTqEnabled;
3416 param.dwTqRounding = m_trellisQuantParams.dwTqRounding;
3417 param.ucKernelMode = m_kernelMode;
3418 param.wSlcHeightInMb = m_sliceHeight;
3419 param.dwMaxVmvR = CodecHalAvcEncode_GetMaxVmvR(m_avcSeqParam->Level);
3420 param.bVdencStreamInEnabled = m_vdencStreamInEnabled;
3421 param.bSliceSizeStreamOutEnabled = m_sliceSizeStreamoutSupported;
3422 param.bCrePrefetchEnable = m_crePrefetchEnable;
3423
3424 if (m_currPass && (m_currPass == m_numPasses) && (!m_vdencBrcEnabled))
3425 {
3426 // Enable IPCM pass, excluding VDENC BRC case
3427 param.bIPCMPass = true;
3428 }
3429 }
3430
UpdateSSDSliceCount()3431 void CodechalEncodeAvcBase::UpdateSSDSliceCount()
3432 {
3433 m_setRequestedEUSlices = ((m_frameHeight * m_frameWidth) >= m_ssdResolutionThreshold &&
3434 m_targetUsage <= m_ssdTargetUsageThreshold)
3435 ? true
3436 : false;
3437
3438 m_hwInterface->m_numRequestedEuSlices = (m_setRequestedEUSlices) ? m_sliceShutdownRequestState : m_sliceShutdownDefaultState;
3439 }
3440
AddIshSize(uint32_t kuid,uint8_t * kernelBase)3441 MOS_STATUS CodechalEncodeAvcBase::AddIshSize(uint32_t kuid, uint8_t *kernelBase)
3442 {
3443 uint8_t *kernelBinary;
3444 uint32_t kernelSize;
3445
3446 MOS_STATUS status = CodecHalGetKernelBinaryAndSize(kernelBase, kuid, &kernelBinary, &kernelSize);
3447 CODECHAL_ENCODE_CHK_STATUS_RETURN(status);
3448 m_hwInterface->GetStateHeapSettings()->dwIshSize += MOS_ALIGN_CEIL(kernelSize, (1 << MHW_KERNEL_OFFSET_SHIFT));
3449 return status;
3450 }
3451
StoreNumPasses(EncodeStatusBuffer * encodeStatusBuf,MhwMiInterface * miInterface,PMOS_COMMAND_BUFFER cmdBuffer,uint32_t currPass)3452 MOS_STATUS CodechalEncodeAvcBase::StoreNumPasses(
3453 EncodeStatusBuffer *encodeStatusBuf,
3454 MhwMiInterface * miInterface,
3455 PMOS_COMMAND_BUFFER cmdBuffer,
3456 uint32_t currPass)
3457 {
3458 MHW_MI_STORE_DATA_PARAMS storeDataParams;
3459 uint32_t offset;
3460 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3461
3462 CODECHAL_ENCODE_FUNCTION_ENTER;
3463
3464 CODECHAL_ENCODE_CHK_NULL_RETURN(encodeStatusBuf);
3465 CODECHAL_ENCODE_CHK_NULL_RETURN(miInterface);
3466 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
3467
3468 offset =
3469 (encodeStatusBuf->wCurrIndex * encodeStatusBuf->dwReportSize) +
3470 encodeStatusBuf->dwNumPassesOffset + // Num passes offset
3471 sizeof(uint32_t) * 2; // pEncodeStatus is offset by 2 DWs in the resource
3472
3473 storeDataParams.pOsResource = &encodeStatusBuf->resStatusBuffer;
3474 storeDataParams.dwResourceOffset = offset;
3475 storeDataParams.dwValue = currPass + 1;
3476 CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
3477
3478 return MOS_STATUS_SUCCESS;
3479 }
3480
3481 #if USE_CODECHAL_DEBUG_TOOL
DumpEncodePicReorder(std::ostringstream & oss,uint32_t x,uint32_t y,CODEC_PIC_REORDER * picReorder)3482 static MOS_STATUS DumpEncodePicReorder(
3483 std::ostringstream &oss,
3484 uint32_t x,
3485 uint32_t y,
3486 CODEC_PIC_REORDER * picReorder)
3487 {
3488 uint8_t botField;
3489
3490 CODECHAL_DEBUG_CHK_NULL(picReorder);
3491
3492 botField = CodecHal_PictureIsBottomField(picReorder->Picture) ? 1 : 0;
3493
3494 oss << "# PicOrder[" << std::dec << +x << "][" << std::dec << +y << "] =" << std::endl;
3495 oss << "# \tPicNum = " << std::dec << +picReorder->PicNum << std::endl;
3496 oss << "# \tPOC = " << std::dec << +picReorder->POC << std::endl;
3497 oss << "# \tReorderPicNumIDC = " << std::dec << +picReorder->ReorderPicNumIDC << std::endl;
3498 oss << "# \tDiffPicNumMinus1 = " << std::dec << +picReorder->DiffPicNumMinus1 << std::endl;
3499 oss << "# \tFrameIdx = " << std::dec << +picReorder->Picture.FrameIdx << std::endl;
3500 oss << "# \tBotField = " << std::dec << +botField << std::endl;
3501
3502 return MOS_STATUS_SUCCESS;
3503 }
3504
DumpSeqParams(PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams,PCODEC_AVC_IQ_MATRIX_PARAMS matrixParams)3505 MOS_STATUS CodechalEncodeAvcBase::DumpSeqParams(
3506 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams,
3507 PCODEC_AVC_IQ_MATRIX_PARAMS matrixParams)
3508 {
3509 CODECHAL_DEBUG_FUNCTION_ENTER;
3510
3511 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSeqParams))
3512 {
3513 return MOS_STATUS_SUCCESS;
3514 }
3515
3516 CODECHAL_DEBUG_CHK_NULL(seqParams);
3517
3518 std::ostringstream oss;
3519 oss.setf(std::ios::showbase | std::ios::uppercase);
3520
3521 oss << "# DDI Parameters:" << std::endl;
3522 oss << "FrameWidth = " << +seqParams->FrameWidth << std::endl;
3523 oss << "FrameHeight = " << +seqParams->FrameHeight << std::endl;
3524 oss << "Profile = " << +seqParams->Profile << std::endl;
3525 oss << "Level = " << +seqParams->Level << std::endl;
3526 oss << "GopPicSize = " << +seqParams->GopPicSize << std::endl;
3527 oss << "GopRefDist = " << +seqParams->GopRefDist << std::endl;
3528 oss << "GopOptFlag = " << +seqParams->GopOptFlag << std::endl;
3529 oss << "TargetUsage = " << +seqParams->TargetUsage << std::endl;
3530 oss << "RateControlMethod = " << +seqParams->RateControlMethod << std::endl;
3531 oss << "TargetBitRate = " << +seqParams->TargetBitRate << std::endl;
3532 oss << "MaxBitRate = " << +seqParams->MaxBitRate << std::endl;
3533 oss << "MinBitRate = " << +seqParams->MinBitRate << std::endl;
3534 oss << "FramesPer100Sec = " << +seqParams->FramesPer100Sec << std::endl;
3535 oss << "InitVBVBufferFullnessInBit = " << +seqParams->InitVBVBufferFullnessInBit << std::endl;
3536 oss << "VBVBufferSizeInBit = " << +seqParams->VBVBufferSizeInBit << std::endl;
3537 oss << "NumRefFrames = " << +seqParams->NumRefFrames / 2 << std::endl; // this prints the value passed from DDI
3538 oss << "# NumRefFrames (Actual Value in CodecHal is twice the value passed from DDI) = "
3539 << +seqParams->NumRefFrames << std::endl; // this prints the actual value in CodecHal seq param structure
3540 oss << "seq_parameter_set_id = " << +seqParams->seq_parameter_set_id << std::endl;
3541 oss << "chroma_format_idc = " << +seqParams->chroma_format_idc << std::endl;
3542 oss << "bit_depth_luma_minus8 = " << +seqParams->bit_depth_luma_minus8 << std::endl;
3543 oss << "bit_depth_chroma_minus8 = " << +seqParams->bit_depth_chroma_minus8 << std::endl;
3544 oss << "log2_max_frame_num_minus4 = " << +seqParams->log2_max_frame_num_minus4 << std::endl;
3545 oss << "pic_order_cnt_type = " << +seqParams->pic_order_cnt_type << std::endl;
3546 oss << "log2_max_pic_order_cnt_lsb_minus4 = " << +seqParams->log2_max_pic_order_cnt_lsb_minus4 << std::endl;
3547 oss << "num_ref_frames_in_pic_order_cnt_cycle = " << +seqParams->num_ref_frames_in_pic_order_cnt_cycle << std::endl;
3548 oss << "offset_for_non_ref_pic = " << +seqParams->offset_for_non_ref_pic << std::endl;
3549 oss << "offset_for_top_to_bottom_field = " << +seqParams->offset_for_top_to_bottom_field << std::endl;
3550
3551 // Conditionally printed (only when pic_order_cnt_type = 1). Contains 256 elements.
3552 if (seqParams->pic_order_cnt_type == 1)
3553 {
3554 for (uint16_t i = 0; i < 256; ++i)
3555 {
3556 oss << "offset_for_ref_frame[" << +i << "] = " << +seqParams->offset_for_ref_frame[i] << std::endl;
3557 }
3558 }
3559
3560 oss << "frame_crop_left_offset = " << +seqParams->frame_crop_left_offset << std::endl;
3561 oss << "frame_crop_right_offset = " << +seqParams->frame_crop_right_offset << std::endl;
3562 oss << "frame_crop_top_offset = " << +seqParams->frame_crop_top_offset << std::endl;
3563 oss << "frame_crop_bottom_offset = " << +seqParams->frame_crop_bottom_offset << std::endl;
3564 oss << "seq_scaling_matrix_present_flag = " << +seqParams->seq_scaling_matrix_present_flag << std::endl;
3565 oss << "seq_scaling_list_present_flag = " << +seqParams->seq_scaling_list_present_flag[0] << std::endl;
3566
3567 // seq_scaling_list_present_flag with 12 elements (only 1 element acknowledged in DDI doc)
3568 oss << "# seq_scaling_list_present_flag[1-11]:";
3569 for (uint8_t i = 1; i < 12; i++)
3570 oss << +seqParams->seq_scaling_list_present_flag[i] << " ";
3571 oss << std::endl;
3572
3573 oss << "delta_pic_order_always_zero_flag = " << +seqParams->delta_pic_order_always_zero_flag << std::endl;
3574 oss << "frame_mbs_only_flag = " << +seqParams->frame_mbs_only_flag << std::endl;
3575 oss << "direct_8x8_inference_flag = " << +seqParams->direct_8x8_inference_flag << std::endl;
3576 oss << "vui_parameters_present_flag = " << +seqParams->vui_parameters_present_flag << std::endl;
3577 oss << "frame_cropping_flag = " << +seqParams->frame_cropping_flag << std::endl;
3578 oss << "EnableSliceLevelRateCtrl = " << +seqParams->EnableSliceLevelRateCtrl << std::endl;
3579 oss << "ICQQualityFactor = " << +seqParams->ICQQualityFactor << std::endl;
3580 oss << "InputColorSpace = " << +seqParams->InputColorSpace << std::endl;
3581
3582 // begining of union/struct
3583 oss << "# bResetBRC = " << +seqParams->bResetBRC << std::endl;
3584 oss << "# bNoAcceleratorSPSInsertion = " << +seqParams->bNoAcceleratorSPSInsertion << std::endl;
3585 oss << "# GlobalSearch = " << +seqParams->GlobalSearch << std::endl;
3586 oss << "# LocalSearch = " << +seqParams->LocalSearch << std::endl;
3587 oss << "# EarlySkip = " << +seqParams->EarlySkip << std::endl;
3588 oss << "# Trellis = " << +seqParams->Trellis << std::endl;
3589 oss << "# MBBRC = " << +seqParams->MBBRC << std::endl;
3590 oss << "# bTemporalScalability = " << +seqParams->bTemporalScalability << std::endl;
3591 oss << "# ROIValueInDeltaQP = " << +seqParams->ROIValueInDeltaQP << std::endl;
3592 oss << "# bAutoMaxPBFrameSizeForSceneChange = " << +seqParams->bAutoMaxPBFrameSizeForSceneChange << std::endl;
3593 oss << "sFlags = " << +seqParams->sFlags << std::endl;
3594
3595 // end of union/struct
3596 oss << "UserMaxIFrameSize = " << +seqParams->UserMaxFrameSize << std::endl;
3597 oss << "UserMaxPBFrameSize = " << +seqParams->UserMaxPBFrameSize << std::endl;
3598
3599 // Parameters not defined in DDI (Any non-DDI parameters printed should be preceeded by #)
3600 oss << "# Non-DDI Parameters:" << std::endl;
3601 oss << "# constraint_set0_flag = " << std::hex << +seqParams->constraint_set0_flag << std::endl;
3602 oss << "# constraint_set1_flag = " << std::hex << +seqParams->constraint_set1_flag << std::endl;
3603 oss << "# constraint_set2_flag = " << std::hex << +seqParams->constraint_set2_flag << std::endl;
3604 oss << "# constraint_set3_flag = " << std::hex << +seqParams->constraint_set3_flag << std::endl;
3605
3606 oss << "# separate_colour_plane_flag = " << std::hex << +seqParams->separate_colour_plane_flag << std::endl;
3607 oss << "# qpprime_y_zero_transform_bypass_flag = " << std::hex << +seqParams->qpprime_y_zero_transform_bypass_flag << std::endl;
3608 oss << "# gaps_in_frame_num_value_allowed_flag = " << std::hex << +seqParams->gaps_in_frame_num_value_allowed_flag << std::endl;
3609 oss << "# pic_width_in_mbs_minus1 = " << std::hex << +seqParams->pic_width_in_mbs_minus1 << std::endl;
3610 oss << "# pic_height_in_map_units_minus1 = " << std::hex << +seqParams->pic_height_in_map_units_minus1 << std::endl;
3611 oss << "# mb_adaptive_frame_field_flag = " << std::hex << +seqParams->mb_adaptive_frame_field_flag << std::endl;
3612
3613 // Dump ScalingList4x4 (6 x 16)
3614 for (uint8_t i = 0; i < 16; ++i)
3615 {
3616 oss << "# ScalingList4x4[" << std::dec << +i * 6 << "-" << (+i * 6) + 5 << "][" << +i << "]";
3617 for (uint8_t j = 0; j < 6; j++)
3618 oss << std::hex << +matrixParams->ScalingList4x4[j][i] << " ";
3619 oss << std::endl;
3620 }
3621
3622 // ScalingList8x8 (2 x 64)
3623 for (uint8_t i = 0; i < 64; ++i)
3624 {
3625 oss << "# ScalingList8x8[0 / 1][ " << std::dec << +i << "] = ";
3626 oss << +matrixParams->ScalingList8x8[0][i] << " / " << +matrixParams->ScalingList8x8[1][i];
3627 oss << std::endl;
3628 }
3629
3630 const char *fileName = m_debugInterface->CreateFileName(
3631 "_DDIEnc",
3632 CodechalDbgBufferType::bufSeqParams,
3633 CodechalDbgExtType::txt);
3634
3635 std::ofstream ofs(fileName, std::ios::out);
3636 ofs << oss.str();
3637 ofs.close();
3638
3639 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
3640 {
3641 if (!m_debugInterface->m_ddiFileName.empty())
3642 {
3643 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
3644 ofs << "SeqParamFile"
3645 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
3646 ofs.close();
3647 }
3648 }
3649
3650 return MOS_STATUS_SUCCESS;
3651 }
3652
DumpPicParams(PCODEC_AVC_ENCODE_PIC_PARAMS picParams,PCODEC_AVC_IQ_MATRIX_PARAMS matrixParams)3653 MOS_STATUS CodechalEncodeAvcBase::DumpPicParams(
3654 PCODEC_AVC_ENCODE_PIC_PARAMS picParams,
3655 PCODEC_AVC_IQ_MATRIX_PARAMS matrixParams)
3656 {
3657 CODECHAL_DEBUG_FUNCTION_ENTER;
3658
3659 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
3660 {
3661 return MOS_STATUS_SUCCESS;
3662 }
3663
3664 CODECHAL_DEBUG_CHK_NULL(picParams);
3665
3666 std::ostringstream oss;
3667 oss.setf(std::ios::showbase | std::ios::uppercase);
3668
3669 oss << "# DDI Parameters:" << std::endl;
3670 oss << "CurrOriginalPic = " << +picParams->CurrOriginalPic.PicEntry << std::endl;
3671 oss << "CurrReconstructedPic = " << +picParams->CurrReconstructedPic.PicEntry << std::endl;
3672 oss << "CodingType = " << +picParams->CodingType << std::endl;
3673 oss << "FieldCodingFlag = " << +picParams->FieldCodingFlag << std::endl;
3674 oss << "FieldFrameCodingFlag = " << +picParams->FieldFrameCodingFlag << std::endl;
3675 oss << "NumSlice = " << +picParams->NumSlice << std::endl;
3676 oss << "QpY = " << +picParams->QpY << std::endl;
3677
3678 for (uint8_t i = 0; i < 16; ++i)
3679 {
3680 oss << "RefFrameList[" << +i << "] = " << +picParams->RefFrameList[i].PicEntry << std::endl;
3681 }
3682
3683 oss << "UsedForReferenceFlags = " << +picParams->UsedForReferenceFlags << std::endl;
3684 oss << "CurrFieldOrderCnt[0] = " << +picParams->CurrFieldOrderCnt[0] << std::endl;
3685 oss << "CurrFieldOrderCnt[1] = " << +picParams->CurrFieldOrderCnt[1] << std::endl;
3686
3687 for (uint8_t i = 0; i < 16; ++i)
3688 {
3689 for (uint8_t j = 0; j < 2; ++j)
3690 {
3691 oss << "FieldOrderCntList[" << +i << "]"
3692 << "[" << +j << "] = " << +picParams->FieldOrderCntList[i][j] << std::endl;
3693 }
3694 }
3695
3696 oss << "frame_num = " << +picParams->frame_num << std::endl;
3697 oss << "bLastPicInSeq = " << +picParams->bLastPicInSeq << std::endl;
3698 oss << "bLastPicInStream = " << +picParams->bLastPicInStream << std::endl;
3699
3700 // User Flags parameters
3701 oss << "# bUseRawPicForRef = " << +picParams->UserFlags.bUseRawPicForRef << std::endl;
3702 oss << "# bDisableAcceleratorHeaderPacking = " << +picParams->UserFlags.bDisableAcceleratorHeaderPacking << std::endl;
3703 oss << "# bDisableSubMBPartition = " << +picParams->UserFlags.bDisableSubMBPartition << std::endl;
3704 oss << "# bEmulationByteInsertion = " << +picParams->UserFlags.bEmulationByteInsertion << std::endl;
3705 oss << "# bEnableRollingIntraRefresh = " << +picParams->UserFlags.bEnableRollingIntraRefresh << std::endl;
3706 oss << "ForceRepartitionCheck =" << +picParams->UserFlags.ForceRepartitionCheck << std::endl;
3707 oss << "UserFlags = " << +picParams->UserFlags.Value << std::endl;
3708 oss << "StatusReportFeedbackNumber = " << +picParams->StatusReportFeedbackNumber << std::endl;
3709 oss << "bIdrPic = " << +picParams->bIdrPic << std::endl;
3710 oss << "pic_parameter_set_id = " << +picParams->pic_parameter_set_id << std::endl;
3711 oss << "seq_parameter_set_id = " << +picParams->seq_parameter_set_id << std::endl;
3712 oss << "num_ref_idx_l0_active_minus1 = " << +picParams->num_ref_idx_l0_active_minus1 << std::endl;
3713 oss << "num_ref_idx_l1_active_minus1 = " << +picParams->num_ref_idx_l1_active_minus1 << std::endl;
3714 oss << "chroma_qp_index_offset = " << +picParams->chroma_qp_index_offset << std::endl;
3715 oss << "second_chroma_qp_index_offset = " << +picParams->second_chroma_qp_index_offset << std::endl;
3716 oss << "entropy_coding_mode_flag = " << +picParams->entropy_coding_mode_flag << std::endl;
3717 oss << "pic_order_present_flag = " << +picParams->pic_order_present_flag << std::endl;
3718 oss << "weighted_pred_flag = " << +picParams->weighted_pred_flag << std::endl;
3719 oss << "weighted_bipred_idc = " << +picParams->weighted_bipred_idc << std::endl;
3720 oss << "constrained_intra_pred_flag = " << +picParams->constrained_intra_pred_flag << std::endl;
3721 oss << "transform_8x8_mode_flag = " << +picParams->transform_8x8_mode_flag << std::endl;
3722 oss << "pic_scaling_matrix_present_flag = " << +picParams->pic_scaling_matrix_present_flag << std::endl;
3723 oss << "pic_scaling_list_present_flag = " << +picParams->pic_scaling_list_present_flag[0] << std::endl;
3724
3725 // pic_scaling_list_present_flag buffer contains 12 elements (only 1 acknowledged DDI document)
3726 oss << "# pic_scaling_list_present_flag[1-11]:";
3727 oss << +picParams->pic_scaling_list_present_flag[1] << " ";
3728 oss << +picParams->pic_scaling_list_present_flag[2] << " ";
3729 oss << +picParams->pic_scaling_list_present_flag[3] << " ";
3730 oss << +picParams->pic_scaling_list_present_flag[4] << " ";
3731 oss << +picParams->pic_scaling_list_present_flag[5] << " ";
3732 oss << +picParams->pic_scaling_list_present_flag[6] << " ";
3733 oss << +picParams->pic_scaling_list_present_flag[7] << " ";
3734 oss << +picParams->pic_scaling_list_present_flag[8] << " ";
3735 oss << +picParams->pic_scaling_list_present_flag[9] << " ";
3736 oss << +picParams->pic_scaling_list_present_flag[10] << " ";
3737 oss << +picParams->pic_scaling_list_present_flag[11] << std::endl;
3738
3739 oss << "RefPicFlag = " << +picParams->RefPicFlag << std::endl;
3740 oss << "BRCPrecision = " << +picParams->BRCPrecision << std::endl;
3741 oss << "IntraInsertionLocation = " << +picParams->IntraRefreshMBNum << std::endl;
3742 oss << "IntraInsertionSize = " << +picParams->IntraRefreshUnitinMB << std::endl;
3743 oss << "QpDeltaForInsertedIntra = " << +picParams->IntraRefreshQPDelta << std::endl;
3744 oss << "SliceSizeInBytes = " << +picParams->SliceSizeInBytes << std::endl;
3745 oss << "bDisableRollingIntraRefreshOverlap = " << +picParams->bDisableRollingIntraRefreshOverlap << std::endl;
3746 oss << "NumROI = " << +picParams->NumROI << std::endl;
3747 oss << "MinDeltaQp = " << +picParams->MinDeltaQp << std::endl;
3748 oss << "MaxDeltaQp = " << +picParams->MaxDeltaQp << std::endl;
3749
3750 // Dump ROI coordinates and PriorityLevelOrDQp
3751 for (uint16_t i = 0; i < picParams->NumROI; ++i)
3752 {
3753 oss << "ROI[" << +i << "] = [";
3754 oss << +picParams->ROI[i].Top << ",";
3755 oss << +picParams->ROI[i].Bottom << ",";
3756 oss << +picParams->ROI[i].Left << ",";
3757 oss << +picParams->ROI[i].Right << "], ";
3758 oss << "PriorityLevelOrDQp = " << +picParams->ROI[i].PriorityLevelOrDQp << std::endl;
3759 }
3760
3761 oss << "NumDirtyROI = " << +picParams->NumDirtyROI << std::endl;
3762
3763 // Dump Dirty ROI coordinates and PriorityLevelOrDQp
3764 for (uint16_t i = 0; i < picParams->NumDirtyROI; ++i)
3765 {
3766 oss << "DirtyROI[" << +i << "] = [";
3767 oss << +picParams->DirtyROI[i].Top << ",";
3768 oss << +picParams->DirtyROI[i].Bottom << ",";
3769 oss << +picParams->DirtyROI[i].Left << ",";
3770 oss << +picParams->DirtyROI[i].Right << "], ";
3771 oss << "PriorityLevelOrDQp = " << +picParams->DirtyROI[i].PriorityLevelOrDQp << std::endl;
3772 }
3773
3774 oss << "SkipFrameFlag = " << +picParams->SkipFrameFlag << std::endl;
3775 oss << "NumSkipFrames = " << +picParams->NumSkipFrames << std::endl;
3776 oss << "SizeSkipFrames = " << +picParams->SizeSkipFrames << std::endl;
3777
3778 // Dump Min/Max QP params
3779 oss << "BRCMinQp = " << +picParams->ucMinimumQP << std::endl;
3780 oss << "BRCMaxQp = " << +picParams->ucMaximumQP << std::endl;
3781
3782 // Dump SFD threshold
3783 oss << "dwZMvThreshold = " << +picParams->dwZMvThreshold << std::endl;
3784
3785 // Dump HME offset
3786 for (uint8_t i = 0; i < 16; ++i)
3787 {
3788 for (uint8_t j = 0; j < 2; ++j)
3789 {
3790 for (uint8_t k = 0; k < 2; ++k)
3791 {
3792 oss << "HMEOffset[" << +i << "][" << +j << "][" << +k << "] = " << +picParams->HMEOffset[i][j][k] << std::endl;
3793 }
3794 }
3795 }
3796
3797 // Parameters not defined in DDI (Any non-DDI parameters printed should be preceeded by #)
3798 oss << "# Non-DDI Parameters:" << std::endl;
3799 oss << "# num_slice_groups_minus1 = " << +picParams->num_slice_groups_minus1 << std::endl;
3800 oss << "# pic_init_qp_minus26 = " << +picParams->pic_init_qp_minus26 << std::endl;
3801 oss << "# pic_init_qs_minus26 = " << +picParams->pic_init_qs_minus26 << std::endl;
3802 oss << "# deblocking_filter_control_present_flag = " << +picParams->deblocking_filter_control_present_flag << std::endl;
3803 oss << "# redundant_pic_cnt_present_flag = " << +picParams->redundant_pic_cnt_present_flag << std::endl;
3804 oss << "# EnableRollingIntraRefresh = " << +picParams->EnableRollingIntraRefresh << std::endl;
3805 oss << "# IntraRefreshMBx = " << +picParams->IntraRefreshMBx << std::endl;
3806 oss << "# IntraRefreshMBy = " << +picParams->IntraRefreshMBy << std::endl;
3807 oss << "# IntraRefreshUnitinMB = " << +picParams->IntraRefreshUnitinMB << std::endl;
3808 oss << "# IntraRefreshQPDelta = " << +picParams->IntraRefreshQPDelta << std::endl;
3809
3810 // Dump ScalingList4x4 (6 x 16)
3811 for (uint8_t i = 0; i < 16; ++i)
3812 {
3813 oss << "# ScalingList4x4[" << +i << "] = ";
3814 oss << +matrixParams->ScalingList4x4[0][i] << " ";
3815 oss << +matrixParams->ScalingList4x4[1][i] << " ";
3816 oss << +matrixParams->ScalingList4x4[2][i] << " ";
3817 oss << +matrixParams->ScalingList4x4[3][i] << " ";
3818 oss << +matrixParams->ScalingList4x4[4][i] << " ";
3819 oss << +matrixParams->ScalingList4x4[5][i] << std::endl;
3820 }
3821
3822 // ScalingList8x8 (2 x 64)
3823 for (uint8_t i = 0; i < 64; ++i)
3824 {
3825 oss << "# ScalingList8x8[0/1][" << +i << "] = " << +matrixParams->ScalingList8x8[0][i] << " / " << +matrixParams->ScalingList8x8[1][i] << std::endl;
3826 }
3827
3828 const char *fileName = m_debugInterface->CreateFileName(
3829 "_DDIEnc",
3830 CodechalDbgBufferType::bufPicParams,
3831 CodechalDbgExtType::txt);
3832
3833 std::ofstream ofs(fileName, std::ios::out);
3834 ofs << oss.str();
3835 ofs.close();
3836
3837 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
3838 {
3839 if (!m_debugInterface->m_ddiFileName.empty())
3840 {
3841 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
3842 ofs << "PicNum"
3843 << " = \"" << m_debugInterface->m_bufferDumpFrameNum << "\"" << std::endl;
3844 ofs << "PicParamFile"
3845 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
3846 ofs.close();
3847 }
3848 }
3849
3850 return MOS_STATUS_SUCCESS;
3851 }
3852
DumpFeiPicParams(CodecEncodeAvcFeiPicParams * feiPicParams)3853 MOS_STATUS CodechalEncodeAvcBase::DumpFeiPicParams(
3854 CodecEncodeAvcFeiPicParams *feiPicParams)
3855 {
3856 CODECHAL_DEBUG_FUNCTION_ENTER;
3857
3858 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrFeiPicParams))
3859 {
3860 return MOS_STATUS_SUCCESS;
3861 }
3862
3863 CODECHAL_DEBUG_CHK_NULL(feiPicParams);
3864
3865 std::ostringstream oss;
3866 oss.setf(std::ios::showbase | std::ios::uppercase);
3867
3868 oss << "# DDI Parameters:" << std::endl;
3869 oss << "SearchPath = " << +feiPicParams->SearchPath << std::endl;
3870 oss << "LenSP = " << +feiPicParams->LenSP << std::endl;
3871 oss << "SubMBPartMask = " << +feiPicParams->SubMBPartMask << std::endl;
3872 oss << "IntraPartMask = " << +feiPicParams->IntraPartMask << std::endl;
3873 oss << "MultiPredL0 = " << +feiPicParams->MultiPredL0 << std::endl;
3874 oss << "MultiPredL1 = " << +feiPicParams->MultiPredL1 << std::endl;
3875 oss << "SubPelMode = " << +feiPicParams->SubPelMode << std::endl;
3876 oss << "InterSAD = " << +feiPicParams->InterSAD << std::endl;
3877 oss << "IntraSAD = " << +feiPicParams->IntraSAD << std::endl;
3878 oss << "NumMVPredictors = " << +feiPicParams->NumMVPredictorsL0 << std::endl;
3879 oss << "NumMVPredictorsL1 = " << +feiPicParams->NumMVPredictorsL1 << std::endl;
3880 oss << "DistortionType = " << +feiPicParams->DistortionType << std::endl;
3881 oss << "DistortionEnable = " << +feiPicParams->DistortionEnable << std::endl;
3882 oss << "RepartitionCheckEnable = " << +feiPicParams->RepartitionCheckEnable << std::endl;
3883 oss << "AdaptiveSearch = " << +feiPicParams->AdaptiveSearch << std::endl;
3884 oss << "MVPredictorEnable = " << +feiPicParams->MVPredictorEnable << std::endl;
3885 oss << "bMBQp = " << +feiPicParams->bMBQp << std::endl;
3886 oss << "bPerMBInput = " << +feiPicParams->bPerMBInput << std::endl;
3887 oss << "bMBSizeCtrl = " << +feiPicParams->bMBSizeCtrl << std::endl;
3888 oss << "RefWidth = " << +feiPicParams->RefWidth << std::endl;
3889 oss << "RefHeight = " << +feiPicParams->RefHeight << std::endl;
3890 oss << "SearchWindow = " << +feiPicParams->SearchWindow << std::endl;
3891
3892 const char *fileName = m_debugInterface->CreateFileName(
3893 "_DDIEnc",
3894 CodechalDbgBufferType::bufFeiPicParams,
3895 CodechalDbgExtType::txt);
3896
3897 std::ofstream ofs(fileName, std::ios::out);
3898 ofs << oss.str();
3899 ofs.close();
3900
3901 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
3902 {
3903 if (!m_debugInterface->m_ddiFileName.empty())
3904 {
3905 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
3906 ofs << "PicNum"
3907 << " = \"" << m_debugInterface->m_bufferDumpFrameNum << "\"" << std::endl;
3908 ofs << "FeiPicParamFile"
3909 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
3910 ofs.close();
3911 }
3912 }
3913
3914 return MOS_STATUS_SUCCESS;
3915 }
3916
DumpSliceParams(PCODEC_AVC_ENCODE_SLICE_PARAMS sliceParams,PCODEC_AVC_ENCODE_PIC_PARAMS picParams)3917 MOS_STATUS CodechalEncodeAvcBase::DumpSliceParams(
3918 PCODEC_AVC_ENCODE_SLICE_PARAMS sliceParams,
3919 PCODEC_AVC_ENCODE_PIC_PARAMS picParams)
3920 {
3921 CODECHAL_DEBUG_FUNCTION_ENTER;
3922
3923 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
3924 {
3925 return MOS_STATUS_SUCCESS;
3926 }
3927
3928 CODECHAL_DEBUG_CHK_NULL(sliceParams);
3929
3930 m_debugInterface->m_sliceId = sliceParams->slice_id; // set here for constructing debug file name
3931
3932 std::ostringstream oss;
3933 oss.setf(std::ios::showbase | std::ios::uppercase);
3934
3935 oss << "# DDI Parameters:" << std::endl;
3936 oss << "NumMbsForSlice = " << +sliceParams->NumMbsForSlice << std::endl;
3937
3938 // RefPicList (2 x 32)
3939 for (uint8_t i = 0; i < 2; ++i)
3940 {
3941 for (uint8_t j = 0; j < 32; ++j)
3942 {
3943 oss << "RefPicList[" << +i << "][" << +j << "] = " << +sliceParams->RefPicList[i][j].PicEntry << std::endl;
3944 }
3945 }
3946
3947 // Conditionally printed (only when picture parameters weighted_pred_flag or weighted_bipred_idc are set).
3948 // Weights contains 192 elements (2 x 32 x 3 x 2).
3949 if (picParams->weighted_pred_flag || picParams->weighted_bipred_idc)
3950 {
3951 for (uint8_t i = 0; i < 2; ++i)
3952 {
3953 for (uint8_t j = 0; j < 32; ++j)
3954 {
3955 for (uint8_t k = 0; k < 3; ++k)
3956 {
3957 for (uint8_t l = 0; l < 2; ++l)
3958 {
3959 oss << "Weights[" << +i << "][" << +j << "][" << +k << "][" << +l << "]: " << +sliceParams->Weights[i][j][k][l] << std::endl;
3960 }
3961 }
3962 }
3963 }
3964 }
3965
3966 oss << "first_mb_in_slice = " << +sliceParams->first_mb_in_slice << std::endl;
3967 oss << "slice_type = " << +sliceParams->slice_type << std::endl;
3968 oss << "pic_parameter_set_id = " << +sliceParams->pic_parameter_set_id << std::endl;
3969 oss << "direct_spatial_mv_pred_flag = " << +sliceParams->direct_spatial_mv_pred_flag << std::endl;
3970 oss << "num_ref_idx_active_override_flag = " << +sliceParams->num_ref_idx_active_override_flag << std::endl;
3971 oss << "long_term_reference_flag = " << +sliceParams->long_term_reference_flag << std::endl;
3972 oss << "idr_pic_id = " << +sliceParams->idr_pic_id << std::endl;
3973 oss << "pic_order_cnt_lsb = " << +sliceParams->pic_order_cnt_lsb << std::endl;
3974 oss << "delta_pic_order_cnt_bottom = " << +sliceParams->delta_pic_order_cnt_bottom << std::endl;
3975 oss << "delta_pic_order_cnt[0] = " << +sliceParams->delta_pic_order_cnt[0] << std::endl;
3976 oss << "delta_pic_order_cnt[1] = " << +sliceParams->delta_pic_order_cnt[1] << std::endl;
3977 oss << "num_ref_idx_l0_active_minus1 = " << +sliceParams->num_ref_idx_l0_active_minus1 << std::endl;
3978 oss << "num_ref_idx_l1_active_minus1 = " << +sliceParams->num_ref_idx_l1_active_minus1 << std::endl;
3979 oss << "luma_log2_weight_denom = " << +sliceParams->luma_log2_weight_denom << std::endl;
3980 oss << "chroma_log2_weight_denom = " << +sliceParams->chroma_log2_weight_denom << std::endl;
3981 oss << "cabac_init_idc = " << +sliceParams->cabac_init_idc << std::endl;
3982 oss << "slice_qp_delta = " << +sliceParams->slice_qp_delta << std::endl;
3983 oss << "disable_deblocking_filter_idc = " << +sliceParams->disable_deblocking_filter_idc << std::endl;
3984 oss << "slice_alpha_c0_offset_div2 = " << +sliceParams->slice_alpha_c0_offset_div2 << std::endl;
3985 oss << "slice_beta_offset_div2 = " << +sliceParams->slice_beta_offset_div2 << std::endl;
3986 oss << "slice_id = " << +sliceParams->slice_id << std::endl;
3987 oss << "luma_weight_flag[0] = " << +sliceParams->luma_weight_flag[0] << std::endl;
3988 oss << "luma_weight_flag[1] = " << +sliceParams->luma_weight_flag[1] << std::endl;
3989 oss << "chroma_weight_flag[0] = " << +sliceParams->chroma_weight_flag[0] << std::endl;
3990 oss << "chroma_weight_flag[1] = " << +sliceParams->chroma_weight_flag[1] << std::endl;
3991
3992 // Parameters not in DDI (Any non-DDI parameters printed should be preceeded by #)
3993 oss << "# Non-DDI Parameters:" << std::endl;
3994
3995 // PicOrder (2 x 32) - Dump in 32 blocks of 2 chunks per line
3996 for (uint16_t i = 0; i < 32; ++i)
3997 {
3998 CODECHAL_DEBUG_CHK_STATUS(DumpEncodePicReorder(
3999 oss,
4000 0,
4001 i,
4002 &(sliceParams->PicOrder[0][i])));
4003 CODECHAL_DEBUG_CHK_STATUS(DumpEncodePicReorder(
4004 oss,
4005 1,
4006 i,
4007 &(sliceParams->PicOrder[1][i])));
4008 }
4009
4010 oss << "# colour_plane_id = " << +sliceParams->colour_plane_id << std::endl;
4011 oss << "# frame_num = " << +sliceParams->frame_num << std::endl;
4012 oss << "# field_pic_flag = " << std::hex << +sliceParams->field_pic_flag << std::endl;
4013 oss << "# bottom_field_flag = " << std::hex << +sliceParams->bottom_field_flag << std::endl;
4014 oss << "# redundant_pic_cnt = " << std::dec << +sliceParams->redundant_pic_cnt << std::endl;
4015 oss << "# sp_for_switch_flag = " << std::hex << +sliceParams->sp_for_switch_flag << std::endl;
4016 oss << "# slice_qs_delta = " << std::dec << +sliceParams->slice_qs_delta << std::endl;
4017 oss << "# ref_pic_list_reordering_flag_l0 = " << std::hex << +sliceParams->ref_pic_list_reordering_flag_l0 << std::endl;
4018 oss << "# ref_pic_list_reordering_flag_l1 = " << std::hex << +sliceParams->ref_pic_list_reordering_flag_l1 << std::endl;
4019 oss << "# no_output_of_prior_pics_flag = " << std::hex << +sliceParams->no_output_of_prior_pics_flag << std::endl;
4020 oss << "# adaptive_ref_pic_marking_mode_flag = " << std::hex << +sliceParams->adaptive_ref_pic_marking_mode_flag << std::endl;
4021 oss << "# MaxFrameNum = " << std::dec << +sliceParams->MaxFrameNum << std::endl;
4022 oss << "# NumReorder = " << std::dec << +sliceParams->NumReorder << std::endl;
4023
4024 const char *fileName = m_debugInterface->CreateFileName(
4025 "_DDIEnc",
4026 CodechalDbgBufferType::bufSlcParams,
4027 CodechalDbgExtType::txt);
4028
4029 std::ofstream ofs(fileName, std::ios::out);
4030 ofs << oss.str();
4031 ofs.close();
4032
4033 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
4034 {
4035 if (!m_debugInterface->m_ddiFileName.empty())
4036 {
4037 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
4038 ofs << "SlcParamFile"
4039 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
4040 ofs.close();
4041 }
4042 }
4043
4044 return MOS_STATUS_SUCCESS;
4045 }
4046
DumpVuiParams(PCODECHAL_ENCODE_AVC_VUI_PARAMS vuiParams)4047 MOS_STATUS CodechalEncodeAvcBase::DumpVuiParams(
4048 PCODECHAL_ENCODE_AVC_VUI_PARAMS vuiParams)
4049 {
4050 CODECHAL_DEBUG_FUNCTION_ENTER;
4051
4052 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrVuiParams))
4053 {
4054 return MOS_STATUS_SUCCESS;
4055 }
4056
4057 CODECHAL_DEBUG_CHK_NULL(vuiParams);
4058
4059 std::ostringstream oss;
4060 oss.setf(std::ios::showbase | std::ios::uppercase);
4061
4062 oss << "# DDI Parameters:" << std::endl;
4063 oss << "aspect_ratio_info_present_flag = " << +vuiParams->aspect_ratio_info_present_flag << std::endl;
4064 oss << "overscan_info_present_flag = " << +vuiParams->overscan_info_present_flag << std::endl;
4065 oss << "overscan_appropriate_flag = " << +vuiParams->overscan_appropriate_flag << std::endl;
4066 oss << "video_signal_type_present_flag = " << +vuiParams->video_signal_type_present_flag << std::endl;
4067 oss << "video_full_range_flag = " << +vuiParams->video_full_range_flag << std::endl;
4068 oss << "colour_description_present_flag = " << +vuiParams->colour_description_present_flag << std::endl;
4069 oss << "chroma_loc_info_present_flag = " << +vuiParams->chroma_loc_info_present_flag << std::endl;
4070 oss << "timing_info_present_flag = " << +vuiParams->timing_info_present_flag << std::endl;
4071 oss << "fixed_frame_rate_flag = " << +vuiParams->fixed_frame_rate_flag << std::endl;
4072 oss << "nal_hrd_parameters_present_flag = " << +vuiParams->nal_hrd_parameters_present_flag << std::endl;
4073 oss << "vcl_hrd_parameters_present_flag = " << +vuiParams->vcl_hrd_parameters_present_flag << std::endl;
4074 oss << "low_delay_hrd_flag = " << +vuiParams->low_delay_hrd_flag << std::endl;
4075 oss << "pic_struct_present_flag = " << +vuiParams->pic_struct_present_flag << std::endl;
4076 oss << "bitstream_restriction_flag = " << +vuiParams->bitstream_restriction_flag << std::endl;
4077 oss << "motion_vectors_over_pic_boundaries_flag = " << +vuiParams->motion_vectors_over_pic_boundaries_flag << std::endl;
4078 oss << "sar_width = " << +vuiParams->sar_width << std::endl;
4079 oss << "sar_height = " << +vuiParams->sar_height << std::endl;
4080 oss << "aspect_ratio_idc = " << +vuiParams->aspect_ratio_idc << std::endl;
4081 oss << "video_format = " << +vuiParams->video_format << std::endl;
4082 oss << "colour_primaries = " << +vuiParams->colour_primaries << std::endl;
4083 oss << "transfer_characteristics = " << +vuiParams->transfer_characteristics << std::endl;
4084 oss << "matrix_coefficients = " << +vuiParams->matrix_coefficients << std::endl;
4085 oss << "chroma_sample_loc_type_top_field = " << +vuiParams->chroma_sample_loc_type_top_field << std::endl;
4086 oss << "chroma_sample_loc_type_bottom_field = " << +vuiParams->chroma_sample_loc_type_bottom_field << std::endl;
4087 oss << "max_bytes_per_pic_denom = " << +vuiParams->max_bytes_per_pic_denom << std::endl;
4088 oss << "max_bits_per_mb_denom = " << +vuiParams->max_bits_per_mb_denom << std::endl;
4089 oss << "log2_max_mv_length_horizontal = " << +vuiParams->log2_max_mv_length_horizontal << std::endl;
4090 oss << "log2_max_mv_length_vertical = " << +vuiParams->log2_max_mv_length_vertical << std::endl;
4091 oss << "num_reorder_frames = " << +vuiParams->num_reorder_frames << std::endl;
4092 oss << "num_units_in_tick = " << +vuiParams->num_units_in_tick << std::endl;
4093 oss << "time_scale = " << +vuiParams->time_scale << std::endl;
4094 oss << "max_dec_frame_buffering = " << +vuiParams->max_dec_frame_buffering << std::endl;
4095 oss << "cpb_cnt_minus1 = " << +vuiParams->cpb_cnt_minus1 << std::endl;
4096 oss << "bit_rate_scale = " << +vuiParams->bit_rate_scale << std::endl;
4097 oss << "cpb_size_scale = " << +vuiParams->cpb_size_scale << std::endl;
4098
4099 // bit_rate_value_minus1 (32 in size)
4100 for (uint8_t i = 0; i < 32; ++i)
4101 {
4102 oss << "bit_rate_value_minus1[" << +i << "] = " << +vuiParams->bit_rate_value_minus1[i] << std::endl;
4103 }
4104
4105 // cpb_size_value_minus1 (32 in size)
4106 for (uint8_t i = 0; i < 32; ++i)
4107 {
4108 oss << "cpb_size_value_minus1[" << +i << "] = " << +vuiParams->cpb_size_value_minus1[i] << std::endl;
4109 }
4110
4111 oss << "cbr_flag = " << +vuiParams->cbr_flag << std::endl;
4112 oss << "initial_cpb_removal_delay_length_minus1 = " << +vuiParams->initial_cpb_removal_delay_length_minus1 << std::endl;
4113 oss << "cpb_removal_delay_length_minus1 = " << +vuiParams->cpb_removal_delay_length_minus1 << std::endl;
4114 oss << "dpb_output_delay_length_minus1 = " << +vuiParams->dpb_output_delay_length_minus1 << std::endl;
4115 oss << "time_offset_length = " << +vuiParams->time_offset_length << std::endl;
4116
4117 const char *fileName = m_debugInterface->CreateFileName(
4118 "_DDIEnc",
4119 CodechalDbgBufferType::bufVuiParams,
4120 CodechalDbgExtType::txt);
4121
4122 std::ofstream ofs(fileName, std::ios::out);
4123 ofs << oss.str();
4124 ofs.close();
4125
4126 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
4127 {
4128 if (!m_debugInterface->m_ddiFileName.empty())
4129 {
4130 std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
4131 ofs << "VuiParamFile"
4132 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
4133 ofs.close();
4134 }
4135 }
4136
4137 return MOS_STATUS_SUCCESS;
4138 }
4139
SearchNALHeader(PMHW_VDBOX_AVC_SLICE_STATE sliceState,uint32_t startCode)4140 bool SearchNALHeader(
4141 PMHW_VDBOX_AVC_SLICE_STATE sliceState,
4142 uint32_t startCode)
4143 {
4144 CODECHAL_DEBUG_FUNCTION_ENTER;
4145
4146 for (auto i = 0; i < CODECHAL_ENCODE_AVC_MAX_NAL_TYPE; i++)
4147 {
4148 if (sliceState->ppNalUnitParams[i]->uiSize > 0)
4149 {
4150 uint32_t offset = 0;
4151 uint8_t *dataBase = (uint8_t *)(sliceState->pBsBuffer->pBase + sliceState->ppNalUnitParams[i]->uiOffset);
4152
4153 while (offset < sliceState->ppNalUnitParams[i]->uiSize)
4154 {
4155 uint8_t *dataBuf = dataBase + offset;
4156
4157 if (*dataBuf == 0)
4158 {
4159 uint32_t data = ((*dataBuf) << 24) + ((*(dataBuf + 1)) << 16) + ((*(dataBuf + 2)) << 8) + (*(dataBuf + 3));
4160
4161 if ((data & 0xFFFFFF00) == 0x00000100)
4162 {
4163 if (data == startCode)
4164 {
4165 return true;
4166 }
4167
4168 offset += 4;
4169 }
4170 else
4171 {
4172 offset++;
4173 }
4174 }
4175 else
4176 {
4177 offset++;
4178 }
4179 }
4180 }
4181 }
4182
4183 return false;
4184 }
4185
CreateAvcPar()4186 MOS_STATUS CodechalEncodeAvcBase::CreateAvcPar()
4187 {
4188 CODECHAL_DEBUG_FUNCTION_ENTER;
4189
4190 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
4191
4192 if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
4193 {
4194 CODECHAL_DEBUG_CHK_NULL(m_avcPar = MOS_New(EncodeAvcPar));
4195 MOS_ZeroMemory(m_avcPar, sizeof(EncodeAvcPar));
4196 }
4197
4198 return MOS_STATUS_SUCCESS;
4199 }
4200
DestroyAvcPar()4201 MOS_STATUS CodechalEncodeAvcBase::DestroyAvcPar()
4202 {
4203 CODECHAL_DEBUG_FUNCTION_ENTER;
4204
4205 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSeqParFile());
4206 MOS_Delete(m_avcPar);
4207
4208 return MOS_STATUS_SUCCESS;
4209 }
4210
PopulateConstParam()4211 MOS_STATUS CodechalEncodeAvcBase::PopulateConstParam()
4212 {
4213 CODECHAL_DEBUG_FUNCTION_ENTER;
4214
4215 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
4216
4217 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
4218 {
4219 return MOS_STATUS_SUCCESS;
4220 }
4221
4222 if (m_encodeParState->m_isConstDumped)
4223 {
4224 return MOS_STATUS_SUCCESS;
4225 }
4226
4227 CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateTargetUsage());
4228
4229 std::ostringstream oss;
4230 oss.setf(std::ios::showbase | std::ios::uppercase);
4231
4232 // Constant
4233 oss << "EnableStatistics = 0" << std::endl;
4234 oss << "KernelDumpEnable = 16" << std::endl;
4235 oss << "Kernel = 1" << std::endl;
4236 oss << "StartMB = -1" << std::endl;
4237 oss << "EndMB = -1" << std::endl;
4238 oss << "GOPMode = 0" << std::endl;
4239 oss << "BoxFilter = 1" << std::endl;
4240 oss << "EnableBpyramid = 0" << std::endl;
4241 oss << "EnableIPCM = 1" << std::endl;
4242 oss << "EnableMVUnpacked = 1" << std::endl;
4243 oss << "EnableNewModeCost = 1" << std::endl;
4244 oss << "EnablePAFF = 0" << std::endl;
4245 oss << "EnableSkip = 3" << std::endl;
4246 oss << "EnableSkipBiasAdjustment = 1" << std::endl;
4247 oss << "HierarchicalMEFlag = 3" << std::endl;
4248 oss << "NumRefStartB = 1" << std::endl;
4249 oss << "PAFFThreshold = 10000" << std::endl;
4250 oss << "PicScalingList = 0" << std::endl;
4251 oss << "SeqScalingList = 0" << std::endl;
4252 oss << "SkipChromaCBPDetection = 1" << std::endl;
4253 oss << "IdrInterval = 0" << std::endl;
4254 oss << "AddEoSquenceNAL = 1" << std::endl;
4255 oss << "AddEoStreamNAL = 1" << std::endl;
4256 oss << "CabacZeroWordFlag = 0" << std::endl;
4257 oss << "EncodeFrameSizeTolerance = 0" << std::endl;
4258 oss << "ForceIntraDC = 0" << std::endl;
4259 oss << "HMECoarseShape = 2" << std::endl;
4260 oss << "HMESubPelMode = 3" << std::endl;
4261 oss << "IntraDirectionBias = 1" << std::endl;
4262 oss << "InterSADMeasure = 2" << std::endl;
4263 oss << "IntraSADMeasure = 2" << std::endl;
4264 oss << "CostingFeature = 3" << std::endl;
4265 oss << "CostingType = 1" << std::endl;
4266 oss << "ModeCosting = 1" << std::endl;
4267 oss << "HighQPMvCostEnable = 1" << std::endl;
4268 oss << "HighQPHMECostEnable = 1" << std::endl;
4269 oss << "RefIDCostMode = 0" << std::endl;
4270 oss << "EnableAdaptiveLambdaOffset = 1" << std::endl;
4271
4272 m_encodeParState->m_isConstDumped = true;
4273
4274 const char *fileName = m_debugInterface->CreateFileName(
4275 "EncodeSequence",
4276 "EncodePar",
4277 CodechalDbgExtType::par);
4278
4279 std::ofstream ofs(fileName, std::ios::app);
4280 ofs << oss.str();
4281 ofs.close();
4282
4283 return MOS_STATUS_SUCCESS;
4284 }
4285
PopulateTargetUsage()4286 MOS_STATUS CodechalEncodeAvcBase::PopulateTargetUsage()
4287 {
4288 CODECHAL_DEBUG_FUNCTION_ENTER;
4289
4290 if (m_populateTargetUsage == false)
4291 {
4292 return MOS_STATUS_SUCCESS;
4293 }
4294
4295 const char *fileName = m_debugInterface->CreateFileName(
4296 "EncodeSequence",
4297 "EncodePar",
4298 CodechalDbgExtType::par);
4299
4300 std::ifstream ifs(fileName);
4301 std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
4302 ifs.close();
4303 std::ofstream ofs(fileName, std::ios::trunc);
4304 ofs << "TargetUsage = " << static_cast<uint32_t>(m_avcSeqParam->TargetUsage) << std::endl;
4305 ofs << str;
4306 ofs.close();
4307
4308 return MOS_STATUS_SUCCESS;
4309 }
4310
PopulateDdiParam(PCODEC_AVC_ENCODE_SEQUENCE_PARAMS avcSeqParams,PCODEC_AVC_ENCODE_PIC_PARAMS avcPicParams,PCODEC_AVC_ENCODE_SLICE_PARAMS avcSlcParams)4311 MOS_STATUS CodechalEncodeAvcBase::PopulateDdiParam(
4312 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS avcSeqParams,
4313 PCODEC_AVC_ENCODE_PIC_PARAMS avcPicParams,
4314 PCODEC_AVC_ENCODE_SLICE_PARAMS avcSlcParams)
4315 {
4316 CODECHAL_DEBUG_FUNCTION_ENTER;
4317
4318 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
4319
4320 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
4321 {
4322 return MOS_STATUS_SUCCESS;
4323 }
4324
4325 if (Slice_Type[avcSlcParams->slice_type] == SLICE_I || Slice_Type[avcSlcParams->slice_type] == SLICE_SI)
4326 {
4327 m_avcPar->ProfileIDC = avcSeqParams->Profile;
4328 m_avcPar->LevelIDC = avcSeqParams->Level;
4329 m_avcPar->DisableVUIHeader = !avcSeqParams->vui_parameters_present_flag;
4330 m_avcPar->ChromaFormatIDC = avcSeqParams->chroma_format_idc;
4331 m_avcPar->ChromaQpOffset = avcPicParams->chroma_qp_index_offset;
4332 m_avcPar->SecondChromaQpOffset = avcPicParams->second_chroma_qp_index_offset;
4333
4334 uint8_t pictureCodingType = CodecHal_PictureIsFrame(avcPicParams->CurrOriginalPic) ? 0 : (CodecHal_PictureIsTopField(avcPicParams->CurrOriginalPic) ? 1 : 3);
4335 m_avcPar->PictureCodingType = pictureCodingType;
4336
4337 uint16_t gopP = (avcSeqParams->GopRefDist) ? ((avcSeqParams->GopPicSize - 1) / avcSeqParams->GopRefDist) : 0;
4338 uint16_t gopB = avcSeqParams->GopPicSize - 1 - gopP;
4339 m_avcPar->NumP = gopP;
4340 m_avcPar->NumB = ((gopP > 0) ? (gopB / gopP) : 0);
4341
4342 if ((avcPicParams->NumSlice * m_sliceHeight) >=
4343 (uint32_t)(avcSeqParams->pic_height_in_map_units_minus1 + 1 + m_sliceHeight))
4344 {
4345 m_avcPar->NumSlices = avcPicParams->NumSlice - 1;
4346 }
4347 else
4348 {
4349 m_avcPar->NumSlices = avcPicParams->NumSlice;
4350 }
4351 m_avcPar->SliceHeight = m_sliceHeight;
4352
4353 m_avcPar->NumSuperSlices = m_avcPar->NumSlices;
4354 uint32_t sliceIdx = 0;
4355 for (; sliceIdx < m_avcPar->NumSuperSlices - 1; sliceIdx++)
4356 {
4357 m_avcPar->SuperSliceHeight[sliceIdx] = m_sliceHeight;
4358 }
4359 m_avcPar->SuperSliceHeight[sliceIdx] = avcSeqParams->pic_height_in_map_units_minus1 + 1 - sliceIdx * m_sliceHeight;
4360
4361 m_avcPar->ISliceQP = avcPicParams->QpY + avcSlcParams->slice_qp_delta;
4362 m_avcPar->FrameRateM = ((avcSeqParams->FramesPer100Sec % 100) == 0) ? (avcSeqParams->FramesPer100Sec / 100) : avcSeqParams->FramesPer100Sec;
4363 m_avcPar->FrameRateD = ((avcSeqParams->FramesPer100Sec % 100) == 0) ? 1 : 100;
4364
4365 uint8_t brcMethod = 0;
4366 uint8_t brcType = 0;
4367
4368 if (CodecHalIsRateControlBrc(avcSeqParams->RateControlMethod, CODECHAL_AVC))
4369 {
4370 brcMethod = 2;
4371
4372 switch (avcSeqParams->RateControlMethod)
4373 {
4374 case RATECONTROL_ICQ:
4375 brcMethod = m_vdencEnabled ? 2 : 3;
4376 brcType = 16;
4377 break;
4378 case RATECONTROL_QVBR:
4379 brcMethod = m_vdencEnabled ? 2 : 4;
4380 brcType = 2;
4381 break;
4382 case RATECONTROL_CBR:
4383 brcType = 1;
4384 break;
4385 case RATECONTROL_VBR:
4386 brcType = 2;
4387 break;
4388 case RATECONTROL_VCM:
4389 brcType = m_vdencEnabled ? 4 : 3;
4390 break;
4391 default:
4392 brcMethod = 0;
4393 brcType = 0;
4394 break;
4395 }
4396
4397 if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW)
4398 {
4399 // low delay mode
4400 brcType = 8;
4401 }
4402 }
4403
4404 m_avcPar->BRCMethod = brcMethod;
4405 m_avcPar->BRCType = brcType;
4406
4407 m_avcPar->DeblockingIDC = avcSlcParams->disable_deblocking_filter_idc;
4408 m_avcPar->DeblockingFilterAlpha = avcSlcParams->slice_alpha_c0_offset_div2 << 1;
4409 m_avcPar->DeblockingFilterBeta = avcSlcParams->slice_beta_offset_div2 << 1;
4410 m_avcPar->EntropyCodingMode = avcPicParams->entropy_coding_mode_flag;
4411 m_avcPar->DirectInference = avcSeqParams->direct_8x8_inference_flag;
4412 m_avcPar->Transform8x8Mode = avcPicParams->transform_8x8_mode_flag;
4413 m_avcPar->CRFQualityFactor = avcSeqParams->ICQQualityFactor;
4414 m_avcPar->ConstrainedIntraPred = avcPicParams->constrained_intra_pred_flag;
4415
4416 // This is only for header matching although I frame doesn't have references
4417 if (avcSlcParams->num_ref_idx_active_override_flag)
4418 {
4419 m_avcPar->MaxRefIdxL0 = MOS_MAX(m_avcPar->MaxRefIdxL0, avcSlcParams->num_ref_idx_l0_active_minus1);
4420 m_avcPar->MaxRefIdxL1 = MOS_MAX(m_avcPar->MaxRefIdxL1, avcSlcParams->num_ref_idx_l1_active_minus1);
4421 }
4422 else
4423 {
4424 m_avcPar->MaxRefIdxL0 = MOS_MAX(m_avcPar->MaxRefIdxL0, avcPicParams->num_ref_idx_l0_active_minus1);
4425 m_avcPar->MaxRefIdxL1 = MOS_MAX(m_avcPar->MaxRefIdxL1, avcPicParams->num_ref_idx_l1_active_minus1);
4426 }
4427
4428 if (m_vdencEnabled)
4429 {
4430 m_avcPar->SliceMode = avcSeqParams->EnableSliceLevelRateCtrl ? 2 : 0;
4431 }
4432 }
4433 else if (Slice_Type[avcSlcParams->slice_type] == SLICE_P || Slice_Type[avcSlcParams->slice_type] == SLICE_SP)
4434 {
4435 m_avcPar->PSliceQP = avcPicParams->QpY + avcSlcParams->slice_qp_delta;
4436 m_avcPar->CabacInitIDC = avcSlcParams->cabac_init_idc;
4437
4438 if (avcSlcParams->num_ref_idx_active_override_flag)
4439 {
4440 m_avcPar->MaxRefIdxL0 = MOS_MAX(m_avcPar->MaxRefIdxL0, avcSlcParams->num_ref_idx_l0_active_minus1);
4441 m_avcPar->MaxRefIdxL1 = MOS_MAX(m_avcPar->MaxRefIdxL1, avcSlcParams->num_ref_idx_l1_active_minus1);
4442 }
4443 else
4444 {
4445 m_avcPar->MaxRefIdxL0 = MOS_MAX(m_avcPar->MaxRefIdxL0, avcPicParams->num_ref_idx_l0_active_minus1);
4446 m_avcPar->MaxRefIdxL1 = MOS_MAX(m_avcPar->MaxRefIdxL1, avcPicParams->num_ref_idx_l1_active_minus1);
4447 }
4448
4449 if (m_avcPar->NumB == 0) // There's no B frame
4450 {
4451 m_avcPar->EnableWeightPredictionDetection = avcPicParams->weighted_pred_flag > 0 ? 1 : 0;
4452 }
4453 m_avcPar->WeightedPred = avcPicParams->weighted_pred_flag;
4454 m_avcPar->UseOrigAsRef = avcPicParams->UserFlags.bUseRawPicForRef;
4455 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;
4456
4457 if (m_vdencEnabled)
4458 {
4459 if (m_targetUsage == 1 || m_targetUsage == 2)
4460 {
4461 m_avcPar->StaticFrameZMVPercent = avcPicParams->dwZMvThreshold;
4462 }
4463 else
4464 {
4465 m_avcPar->StaticFrameZMVPercent = 100;
4466 }
4467
4468 if (avcPicParams->bEnableHMEOffset)
4469 {
4470 m_avcPar->hme0XOffset = MOS_CLAMP_MIN_MAX(avcPicParams->HMEOffset[0][0][0], -128, 127);
4471 m_avcPar->hme0YOffset = MOS_CLAMP_MIN_MAX(avcPicParams->HMEOffset[0][0][1], -128, 127);
4472 m_avcPar->hme1XOffset = MOS_CLAMP_MIN_MAX(avcPicParams->HMEOffset[1][0][0], -128, 127);
4473 m_avcPar->hme1YOffset = MOS_CLAMP_MIN_MAX(avcPicParams->HMEOffset[1][0][1], -128, 127);
4474 }
4475 }
4476 }
4477 else if (Slice_Type[avcSlcParams->slice_type] == SLICE_B)
4478 {
4479 m_avcPar->BSliceQP = avcPicParams->QpY + avcSlcParams->slice_qp_delta;
4480
4481 if (avcSlcParams->num_ref_idx_active_override_flag)
4482 {
4483 m_avcPar->MaxBRefIdxL0 = MOS_MAX(m_avcPar->MaxBRefIdxL0, avcSlcParams->num_ref_idx_l0_active_minus1);
4484 }
4485 else
4486 {
4487 m_avcPar->MaxBRefIdxL0 = MOS_MAX(m_avcPar->MaxBRefIdxL0, avcPicParams->num_ref_idx_l0_active_minus1);
4488 }
4489
4490 m_avcPar->EnableWeightPredictionDetection = (avcPicParams->weighted_bipred_idc | avcPicParams->weighted_pred_flag) > 0 ? 1 : 0;
4491 m_avcPar->WeightedBiPred = avcPicParams->weighted_bipred_idc;
4492 m_avcPar->BiWeight = m_biWeight;
4493 }
4494
4495 return MOS_STATUS_SUCCESS;
4496 }
4497
PopulateSliceStateParam(bool adaptiveRoundingInterEnable,PMHW_VDBOX_AVC_SLICE_STATE sliceState)4498 MOS_STATUS CodechalEncodeAvcBase::PopulateSliceStateParam(
4499 bool adaptiveRoundingInterEnable,
4500 PMHW_VDBOX_AVC_SLICE_STATE sliceState)
4501 {
4502 CODECHAL_DEBUG_FUNCTION_ENTER;
4503
4504 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
4505
4506 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
4507 {
4508 return MOS_STATUS_SUCCESS;
4509 }
4510
4511 if (m_pictureCodingType == I_TYPE)
4512 {
4513 m_avcPar->RoundingIntraEnabled = true;
4514 m_avcPar->RoundingIntra = 5;
4515 // Set to 1 first, we don't consider 0 case as we only dump I frame param once
4516 m_avcPar->FrmHdrEncodingFrequency = 1; // 1: picture header in every IDR frame
4517
4518 // Search SEI NAL
4519 m_avcPar->EnableSEI = SearchNALHeader(sliceState, CODECHAL_DEBUG_ENCODE_AVC_NAL_START_CODE_SEI);
4520 }
4521 else if (m_pictureCodingType == P_TYPE)
4522 {
4523 m_avcPar->EnableAdaptiveRounding = adaptiveRoundingInterEnable;
4524 m_avcPar->RoundingInterEnabled = sliceState->bRoundingInterEnable;
4525 m_avcPar->RoundingInter = sliceState->dwRoundingValue;
4526
4527 // Search PPS NAL
4528 m_avcPar->FrmHdrEncodingFrequency =
4529 SearchNALHeader(sliceState, CODECHAL_DEBUG_ENCODE_AVC_NAL_START_CODE_PPS) ? 2 : m_avcPar->FrmHdrEncodingFrequency;
4530 }
4531 else if (m_pictureCodingType == B_TYPE)
4532 {
4533 m_avcPar->RoundingInterB = sliceState->dwRoundingValue;
4534 }
4535
4536 return MOS_STATUS_SUCCESS;
4537 }
4538
PopulateSfdParam(void * cmd)4539 MOS_STATUS CodechalEncodeAvcBase::PopulateSfdParam(
4540 void *cmd)
4541 {
4542 CODECHAL_DEBUG_FUNCTION_ENTER;
4543
4544 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
4545
4546 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
4547 {
4548 return MOS_STATUS_SUCCESS;
4549 }
4550
4551 CODECHAL_ENCODE_AVC_SFD_CURBE_COMMON *curbe = (CODECHAL_ENCODE_AVC_SFD_CURBE_COMMON *)cmd;
4552
4553 if (m_pictureCodingType == P_TYPE)
4554 {
4555 m_avcPar->EnableIntraCostScalingForStaticFrame = curbe->DW0.EnableIntraCostScalingForStaticFrame;
4556 m_avcPar->StaticFrameIntraCostScalingRatioP = 240;
4557 m_avcPar->AdaptiveMvStreamIn = curbe->DW0.EnableAdaptiveMvStreamIn;
4558 m_avcPar->LargeMvThresh = curbe->DW3.LargeMvThresh;
4559 m_avcPar->LargeMvPctThreshold = 1;
4560 }
4561
4562 return MOS_STATUS_SUCCESS;
4563 }
4564 #endif
4565
SetFrameStoreIds(uint8_t frameIdx)4566 MOS_STATUS CodechalEncodeAvcBase::SetFrameStoreIds(uint8_t frameIdx)
4567 {
4568 uint8_t invalidFrame = (m_mode == CODECHAL_DECODE_MODE_AVCVLD) ? 0x7f : 0x1f;
4569
4570 for (uint8_t i = 0; i < m_refList[frameIdx]->ucNumRef; i++)
4571 {
4572 uint8_t index;
4573 index = m_refList[frameIdx]->RefList[i].FrameIdx;
4574 if (m_refList[index]->ucFrameId == invalidFrame)
4575 {
4576 uint8_t j;
4577 for (j = 0; j < CODEC_AVC_MAX_NUM_REF_FRAME; j++)
4578 {
4579 if (!m_avcFrameStoreID[j].inUse)
4580 {
4581 m_refList[index]->ucFrameId = j;
4582 m_avcFrameStoreID[j].inUse = true;
4583 break;
4584 }
4585 }
4586 if (j == CODEC_AVC_MAX_NUM_REF_FRAME)
4587 {
4588 // should never happen, something must be wrong
4589 CODECHAL_PUBLIC_ASSERT(false);
4590 m_refList[index]->ucFrameId = 0;
4591 m_avcFrameStoreID[0].inUse = true;
4592 }
4593 }
4594 }
4595 return MOS_STATUS_SUCCESS;
4596 }
4597