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