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