1 /*
2 * Copyright (c) 2011-2024, 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_decode_avc.cpp
24 //! \brief     This modules implements Render interface layer for AVC decoding to be used on all operating systems/DDIs, across CODECHAL components.
25 //!
26 
27 #include "codechal_decoder.h"
28 #include "codechal_decode_avc.h"
29 #include "codechal_decode_sfc_avc.h"
30 #include "codechal_mmc_decode_avc.h"
31 #include "codechal_secure_decode_interface.h"
32 #include "hal_oca_interface.h"
33 #if USE_CODECHAL_DEBUG_TOOL
34 #include "codechal_debug.h"
35 #endif
36 
37 //Check whether interview prediction is used through POC
38 #define CodecHalAVC_IsInterviewPred(currPic, currPoc, avcRefListIdx) ( ((avcRefListIdx)!=(currPic).FrameIdx) &&              \
39     (!CodecHal_PictureIsTopField(currPic)    && (pAvcRefList[avcRefListIdx]->iFieldOrderCnt[1] == (currPoc)[1]) ||       \
40      !CodecHal_PictureIsBottomField(currPic) && (pAvcRefList[avcRefListIdx]->iFieldOrderCnt[0] == (currPoc)[0])) &&      \
41     ((currPic).FrameIdx != 0x7f) )
42 
SendSlice(PMHW_VDBOX_AVC_SLICE_STATE avcSliceState,PMOS_COMMAND_BUFFER cmdBuffer)43 MOS_STATUS CodechalDecodeAvc::SendSlice(
44     PMHW_VDBOX_AVC_SLICE_STATE      avcSliceState,
45     PMOS_COMMAND_BUFFER             cmdBuffer)
46 {
47 
48     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
49 
50     CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
51     CODECHAL_DECODE_CHK_NULL_RETURN(avcSliceState);
52     CODECHAL_DECODE_CHK_NULL_RETURN(avcSliceState->pAvcPicIdx);
53     CODECHAL_DECODE_CHK_NULL_RETURN(avcSliceState->pAvcPicParams);
54     CODECHAL_DECODE_CHK_NULL_RETURN(avcSliceState->pAvcSliceParams);
55 
56     PCODEC_AVC_PIC_PARAMS avcPicParams = avcSliceState->pAvcPicParams;
57     PCODEC_AVC_SLICE_PARAMS slc = avcSliceState->pAvcSliceParams;
58 
59     avcSliceState->ucDisableDeblockingFilterIdc = slc->disable_deblocking_filter_idc;
60     avcSliceState->ucSliceBetaOffsetDiv2 = slc->slice_beta_offset_div2;
61     avcSliceState->ucSliceAlphaC0OffsetDiv2 = slc->slice_alpha_c0_offset_div2;
62 
63     if (avcSliceState->bShortFormatInUse)
64     {
65         // send slice address except last one
66         if (!avcSliceState->bLastSlice)
67         {
68             CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdAvcSliceAddrCmd(
69                 cmdBuffer,
70                 avcSliceState));
71         }
72     }
73     else
74     {
75         MHW_VDBOX_AVC_REF_IDX_PARAMS refIdxParams;
76         MOS_ZeroMemory(&refIdxParams, sizeof(MHW_VDBOX_AVC_REF_IDX_PARAMS));
77 
78         if (!m_mfxInterface->IsAvcISlice(slc->slice_type))
79         {
80             refIdxParams.CurrPic = avcPicParams->CurrPic;
81             refIdxParams.uiList = LIST_0;
82             refIdxParams.uiNumRefForList[LIST_0] = slc->num_ref_idx_l0_active_minus1 + 1;
83 
84             CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(
85                 &refIdxParams.RefPicList,
86                 sizeof(refIdxParams.RefPicList),
87                 &slc->RefPicList,
88                 sizeof(slc->RefPicList)),
89                 "Failed to copy memory");
90 
91             refIdxParams.pAvcPicIdx = avcSliceState->pAvcPicIdx;
92             refIdxParams.avcRefList = (void**)m_avcRefList;
93             refIdxParams.bIntelEntrypointInUse = avcSliceState->bIntelEntrypointInUse;
94             refIdxParams.bPicIdRemappingInUse = avcSliceState->bPicIdRemappingInUse;
95 
96             CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcRefIdx(cmdBuffer, nullptr, &refIdxParams));
97 
98             MHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS weightOffsetParams;
99 
100             if (m_mfxInterface->IsAvcPSlice(slc->slice_type) &&
101                 avcPicParams->pic_fields.weighted_pred_flag == 1)
102             {
103                 weightOffsetParams.uiList = 0;
104                 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(
105                     &weightOffsetParams.Weights,
106                     sizeof(weightOffsetParams.Weights),
107                     &slc->Weights,
108                     sizeof(slc->Weights)),
109                     "Failed to copy memory");
110 
111                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcWeightOffset(cmdBuffer, nullptr, &weightOffsetParams));
112             }
113 
114             if (m_mfxInterface->IsAvcBSlice(slc->slice_type))
115             {
116                 refIdxParams.uiList = LIST_1;
117                 refIdxParams.uiNumRefForList[LIST_1] = slc->num_ref_idx_l1_active_minus1 + 1;
118                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcRefIdx(cmdBuffer, nullptr, &refIdxParams));
119 
120                 if (avcPicParams->pic_fields.weighted_bipred_idc == 1)
121                 {
122                     weightOffsetParams.uiList = 0;
123                     CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(
124                         &weightOffsetParams.Weights,
125                         sizeof(weightOffsetParams.Weights),
126                         &slc->Weights,
127                         sizeof(slc->Weights)),
128                         "Failed to copy memory");
129 
130                     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcWeightOffset(cmdBuffer, nullptr, &weightOffsetParams));
131                     weightOffsetParams.uiList = 1;
132                     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcWeightOffset(cmdBuffer, nullptr, &weightOffsetParams));
133                 }
134             }
135         }
136         else if (MEDIA_IS_WA(m_waTable, WaDummyReference) && !m_osInterface->bSimIsActive)
137         {
138             MHW_VDBOX_AVC_REF_IDX_PARAMS refIdxParams;
139             MOS_ZeroMemory(&refIdxParams, sizeof(MHW_VDBOX_AVC_REF_IDX_PARAMS));
140             refIdxParams.bDummyReference = true;
141             CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcRefIdx(cmdBuffer, nullptr, &refIdxParams));
142         }
143 
144         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcSlice(cmdBuffer, nullptr, avcSliceState));
145     }
146 
147     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdAvcBsdObjectCmd(
148         cmdBuffer,
149         avcSliceState));
150 
151     return eStatus;
152 }
153 
FormatAvcMonoPicture(PMOS_SURFACE surface)154 MOS_STATUS CodechalDecodeAvc::FormatAvcMonoPicture(PMOS_SURFACE surface)
155 {
156     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
157 
158     PCODEC_AVC_PIC_PARAMS picParams = (PCODEC_AVC_PIC_PARAMS)m_avcPicParams;
159     if (picParams->seq_fields.chroma_format_idc != avcChromaFormatMono)
160     {
161         return MOS_STATUS_SUCCESS;
162     }
163 
164     MOS_SURFACE dstSurface;
165     MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
166     dstSurface.Format = Format_NV12;
167     if(surface != nullptr && !Mos_ResourceIsNull(&surface->OsResource))
168     {
169        dstSurface.OsResource = surface->OsResource;
170     }
171     else
172     {
173        CODECHAL_DECODE_ASSERTMESSAGE("Surface pointer is NULL!");
174        return MOS_STATUS_INVALID_PARAMETER;
175     }
176     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &dstSurface));
177 
178     uint32_t height = dstSurface.dwHeight;
179     uint32_t pitch = dstSurface.dwPitch;
180     uint32_t chromaHeight = height / 2;
181     uint32_t frameHeight = MOS_ALIGN_CEIL(height, 16);
182     uint32_t alignedFrameHeight = MOS_ALIGN_CEIL(frameHeight, MOS_YTILE_H_ALIGNMENT);
183     uint32_t alignedChromaHeight = MOS_ALIGN_CEIL(chromaHeight, MOS_YTILE_H_ALIGNMENT);
184     uint32_t frameSize = pitch * MOS_ALIGN_CEIL((frameHeight + chromaHeight), MOS_YTILE_H_ALIGNMENT);
185     uint32_t chromaBufSize = MOS_ALIGN_CEIL(pitch * alignedChromaHeight, MHW_PAGE_SIZE);
186 
187     if (Mos_ResourceIsNull(&m_resMonoPictureChromaBuffer))
188     {
189         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
190                                                       &m_resMonoPictureChromaBuffer,
191                                                       chromaBufSize,
192                                                       "MonoPictureChromaBuffer",
193                                                       true,
194                                                       CODECHAL_DECODE_AVC_MONOPIC_CHROMA_DEFAULT),
195             "Failed to allocate MonoPicture Chroma Buffer.");
196     }
197 
198     MOS_COMMAND_BUFFER cmdBuffer;
199     CodechalHucStreamoutParams hucStreamOutParams;
200     if (!m_hwInterface->m_noHuC)
201     {
202         m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContextForWa);
203         m_osInterface->pfnResetOsStates(m_osInterface);
204 
205         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
206 
207         CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, false));
208 
209         // use huc stream out to do clear to clear copy
210 
211         MOS_ZeroMemory(&hucStreamOutParams, sizeof(hucStreamOutParams));
212         hucStreamOutParams.dataBuffer            = &m_resMonoPictureChromaBuffer;
213         hucStreamOutParams.streamOutObjectBuffer = &surface->OsResource;
214     }
215 
216     uint32_t uvblockHeight = CODECHAL_MACROBLOCK_HEIGHT;
217     uint32_t uvrowSize = pitch * uvblockHeight * 2;
218 
219     uint32_t dstOffset = 0, x = 0, uvsize = 0;
220     if (frameHeight % MOS_YTILE_H_ALIGNMENT)
221     {
222         dstOffset = LinearToYTiledAddress(x, frameHeight, pitch);
223 
224         if (m_hwInterface->m_noHuC)
225         {
226             CodechalDataCopyParams dataCopyParams;
227             MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
228             dataCopyParams.srcResource = &m_resMonoPictureChromaBuffer;
229             dataCopyParams.srcSize     = uvrowSize;
230             dataCopyParams.srcOffset   = 0;
231             dataCopyParams.dstResource = &surface->OsResource;
232             dataCopyParams.dstSize     = frameSize;
233             dataCopyParams.dstOffset   = dstOffset;
234 
235             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams));
236         }
237         else
238         {
239             CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
240                 &cmdBuffer,                                 // pCmdBuffer
241                 &m_resMonoPictureChromaBuffer,              // presSrc
242                 &surface->OsResource,                      // presDst
243                 uvrowSize,                                  // u32CopyLength
244                 0,                                          // u32CopyInputOffset
245                 dstOffset));                                // u32CopyOutputOffset
246         }
247     }
248 
249     dstOffset = dstSurface.UPlaneOffset.iSurfaceOffset;
250     uvsize    = frameSize - pitch * alignedFrameHeight;
251 
252     if (m_hwInterface->m_noHuC)
253     {
254         CodechalDataCopyParams dataCopyParams;
255         MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
256         dataCopyParams.srcResource     = &m_resMonoPictureChromaBuffer;
257         dataCopyParams.srcSize         = uvsize;
258         dataCopyParams.srcOffset       = 0;
259         dataCopyParams.dstResource     = &surface->OsResource;
260         dataCopyParams.dstSize         = frameSize;
261         dataCopyParams.dstOffset       = dstOffset;
262 
263         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams));
264     }
265     else
266     {
267         CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
268             &cmdBuffer,                                 // pCmdBuffer
269             &m_resMonoPictureChromaBuffer,              // presSrc
270             &surface->OsResource,                      // presDst
271             uvsize,                                     // u32CopyLength
272             0,                                          // u32CopyInputOffset
273             dstOffset));                                // u32CopyOutputOffset
274 
275         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
276         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
277         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
278 
279         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
280 
281         m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
282 
283         MOS_SYNC_PARAMS syncParams;
284 
285         syncParams = g_cInitSyncParams;
286         syncParams.GpuContext = m_videoContext;
287         syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
288 
289         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
290 
291         syncParams = g_cInitSyncParams;
292         syncParams.GpuContext = m_videoContextForWa;
293         syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
294 
295         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
296 
297         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
298 
299         m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext);
300     }
301 
302     return eStatus;
303 }
304 
AllocateInvalidRefBuffer()305 MOS_STATUS CodechalDecodeAvc::AllocateInvalidRefBuffer()
306 {
307     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
308 
309     //AlloctateResource
310     if (Mos_ResourceIsNull(&m_resInvalidRefBuffer))
311     {
312         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &m_destSurface));
313 
314         MOS_MEMCOMP_STATE mmcMode = MOS_MEMCOMP_DISABLED;
315 #ifdef _MMC_SUPPORTED
316         if(m_mmc != nullptr && m_mmc->IsMmcEnabled())
317         {
318             CODECHAL_DECODE_CHK_STATUS_RETURN(
319             m_osInterface->pfnGetMemoryCompressionMode(
320                 m_osInterface,
321                 &m_destSurface.OsResource,
322                 &mmcMode));
323         }
324 #endif
325 
326         MOS_SURFACE surface;
327         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateSurface(
328                                                       &surface,
329                                                       m_destSurface.dwPitch,
330                                                       m_destSurface.dwHeight,
331                                                       "InvalidRefBuffer",
332                                                       Format_NV12,
333                                                       mmcMode != MOS_MEMCOMP_DISABLED ? true : false),
334             "Failed to allocate invalid reference buffer.");
335         m_resInvalidRefBuffer = surface.OsResource;
336 
337         // set all the pixels to 1<<(BitDepth-1) according to the AVC spec
338         CodechalResLock ResourceLock(m_osInterface, &m_resInvalidRefBuffer);
339         auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
340         CODECHAL_DECODE_CHK_NULL_RETURN(data);
341 
342         uint32_t size = m_destSurface.dwPitch * m_destSurface.dwHeight * 3 / 2;
343         MOS_FillMemory(data, size, CODECHAL_DECODE_AVC_INVALID_REFPIC_VALUE);  //INVALID_REFPIC_VALUE = 1<<(8-1): Intel Graphic only support 8bit AVC output now.
344     }
345 
346     return eStatus;
347 }
348 
SetAndAllocateDmvBufferIndex(PCODEC_AVC_DMV_LIST avcMVBufList,bool usedForRef,uint8_t frameIdx,uint32_t avcDmvBufferSize,uint8_t * dmvIdx,MOS_RESOURCE * avcDmvBuffers)349 MOS_STATUS CodechalDecodeAvc::SetAndAllocateDmvBufferIndex(
350     PCODEC_AVC_DMV_LIST         avcMVBufList,
351     bool                        usedForRef,
352     uint8_t                     frameIdx,
353     uint32_t                    avcDmvBufferSize,
354     uint8_t                     *dmvIdx,
355     MOS_RESOURCE                *avcDmvBuffers)
356 {
357     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
358 
359     CODECHAL_DECODE_CHK_NULL_RETURN(avcMVBufList);
360     CODECHAL_DECODE_CHK_NULL_RETURN(dmvIdx);
361     CODECHAL_DECODE_CHK_NULL_RETURN(avcDmvBuffers);
362 
363     uint8_t index = 0;
364     if (usedForRef)
365     {
366         uint8_t i;
367         for (i = 0; i < CODEC_AVC_NUM_REF_DMV_BUFFERS; i++)
368         {
369             if (!avcMVBufList[i].bInUse)
370             {
371                 index = i;
372                 avcMVBufList[i].bInUse = true;
373                 avcMVBufList[i].ucFrameId = frameIdx;
374                 break;
375             }
376         }
377         if (i == CODEC_AVC_NUM_REF_DMV_BUFFERS)
378         {
379             // Should never happen, something must be wrong
380             CODECHAL_DECODE_ASSERTMESSAGE("No DMV Buffer found.");
381             eStatus = MOS_STATUS_INVALID_PARAMETER;
382             return eStatus;
383         }
384     }
385     else
386     {
387         index = CODEC_AVC_NUM_REF_DMV_BUFFERS;
388     }
389 
390     if (Mos_ResourceIsNull(&avcDmvBuffers[index]))
391     {
392         // Allocate DMV buffer if it has not been allocated already.
393         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
394             &avcDmvBuffers[index],
395             avcDmvBufferSize,
396             "MvBuffer",
397             true),
398             "Failed to allocate MV Buffer.");
399     }
400 
401     *dmvIdx = index;
402     return eStatus;
403 }
404 
405 
SetAndAllocateDmvBufferIndexMismatched(uint8_t frameIdx,uint32_t avcDmvBufferSize,uint8_t * dmvIdx,MOS_RESOURCE * avcDmvBuffers)406 MOS_STATUS CodechalDecodeAvc::SetAndAllocateDmvBufferIndexMismatched(
407     uint8_t             frameIdx,
408     uint32_t            avcDmvBufferSize,
409     uint8_t            *dmvIdx,
410     MOS_RESOURCE       *avcDmvBuffers)
411 {
412     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
413 
414     CODECHAL_DECODE_CHK_NULL_RETURN(dmvIdx);
415     CODECHAL_DECODE_CHK_NULL_RETURN(avcDmvBuffers);
416 
417     uint8_t index = frameIdx;
418 
419     if (Mos_ResourceIsNull(&avcDmvBuffers[index]))
420     {
421         // Allocate DMV buffer if it has not been allocated already.
422         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
423                                                       &avcDmvBuffers[index],
424                                                       avcDmvBufferSize,
425                                                       "MvBuffer",
426                                                       true),
427             "Failed to allocate MV Buffer.");
428     }
429 
430     *dmvIdx = index;
431     return eStatus;
432 }
433 
InitMvcDummyDmvBuffer(uint32_t * mvcWaDummyDmvBuf,uint32_t size,PMOS_RESOURCE mvcDummyDmvBuffer)434 MOS_STATUS CodechalDecodeAvc::InitMvcDummyDmvBuffer(
435     uint32_t                    *mvcWaDummyDmvBuf,
436     uint32_t                    size,
437     PMOS_RESOURCE               mvcDummyDmvBuffer)
438 {
439     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
440 
441     CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
442         mvcDummyDmvBuffer,
443         size,
444         "MvBuffer"),
445         "Failed to allocate WA Mvc Dummy DMV Buffer.");
446 
447     uint8_t *dummyDmvBuffer = nullptr, *mbDmvBuffer = nullptr;
448     CODECHAL_DECODE_CHK_NULL_RETURN(dummyDmvBuffer = (uint8_t*)MOS_AllocAndZeroMemory(size));
449     mbDmvBuffer = dummyDmvBuffer;
450 
451     uint32_t i, numMBs = size / 64;
452     for (i = 0; i<numMBs; i++)
453     {
454         eStatus = (MOS_STATUS)MOS_SecureMemcpy(mbDmvBuffer, 64, mvcWaDummyDmvBuf, 64);
455         if (eStatus != MOS_STATUS_SUCCESS)
456         {
457             MOS_SafeFreeMemory(dummyDmvBuffer);
458             CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
459         }
460         mbDmvBuffer += 64;
461     }
462 
463     CodechalResLock ResourceLock(m_osInterface, mvcDummyDmvBuffer);
464     auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
465 
466     if (data  == nullptr)
467     {
468         MOS_FreeMemory(dummyDmvBuffer);
469         CODECHAL_DECODE_CHK_NULL_RETURN(nullptr);
470     }
471 
472     eStatus = (MOS_STATUS)MOS_SecureMemcpy(data, size, (void*)dummyDmvBuffer, size);
473     if (eStatus != MOS_STATUS_SUCCESS)
474     {
475         MOS_SafeFreeMemory(dummyDmvBuffer);
476         CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
477     }
478 
479     MOS_FreeMemAndSetNull(dummyDmvBuffer);
480     return eStatus;
481 }
482 
SetPictureStructs()483 MOS_STATUS CodechalDecodeAvc::SetPictureStructs()
484 {
485     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
486 
487     CODECHAL_DECODE_FUNCTION_ENTER;
488 
489     PCODEC_AVC_PIC_PARAMS picParams = m_avcPicParams;
490     CODEC_PICTURE         prevPic   = m_currPic;
491     CODEC_PICTURE currPic = picParams->CurrPic;
492 
493     uint8_t i, ii;
494     if (picParams->pic_fields.field_pic_flag)
495     {
496         // Note: The AVC criteria of second field following first field is not compatible with MVC.
497         // For MVC compatibility, a buffer of 16 frame indexes are used to store
498         // the consecutive first fiels of different views in the same Acess Unit.
499         ii = CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS;
500         // Find if the current field is a second field (no matching first field)
501         for (i = 0; i < CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS; i++)
502         {
503             if (m_firstFieldIdxList[i] == currPic.FrameIdx)
504             {
505                 break;
506             }
507             // At the same time, find the first empty entrance to store the frame index.
508             // Used when the current field is a first field.
509             ii = (m_firstFieldIdxList[i] == CODECHAL_DECODE_AVC_INVALID_FRAME_IDX && ii == CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS) ? i : ii;
510         }
511 
512         if ((prevPic.PicFlags != currPic.PicFlags) || (prevPic.FrameIdx != currPic.FrameIdx) || (currPic.PicFlags == PICTURE_INVALID))
513         {
514             if (i < CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS)
515             {
516                 m_isSecondField = true;
517                 m_firstFieldIdxList[i] = CODECHAL_DECODE_AVC_INVALID_FRAME_IDX;
518                 while (i > 0) // Clear all smaller indexes in case there are missing fields.
519                 {
520                     m_firstFieldIdxList[--i] = CODECHAL_DECODE_AVC_INVALID_FRAME_IDX;
521                 }
522             }
523             else
524             {
525                 m_isSecondField = false;
526                 if (ii == CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS)
527                 {
528                     ii = 0;
529                 }
530                 else
531                 {
532                     m_firstFieldIdxList[ii++] = currPic.FrameIdx;
533                 }
534                 // Clear all larger indexes in case there are missing fields.
535                 while (ii < CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS)
536                 {
537                     m_firstFieldIdxList[ii++] = CODECHAL_DECODE_AVC_INVALID_FRAME_IDX;
538                 }
539             }
540         }
541 
542         m_height =
543             MOS_ALIGN_CEIL(m_height, MOS_YTILE_H_ALIGNMENT);
544     }
545     else
546     {
547         for (i = 0; i < CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS; i++)
548         {
549             m_firstFieldIdxList[i] = CODECHAL_DECODE_AVC_INVALID_FRAME_IDX;
550         }
551         m_isSecondField = false;
552     }
553 
554     m_statusReportFeedbackNumber = picParams->StatusReportFeedbackNumber;
555     m_currPic                                 = currPic;
556     m_avcRefList[currPic.FrameIdx]->RefPic    = m_currPic;
557     m_avcRefList[currPic.FrameIdx]->resRefPic = m_destSurface.OsResource;
558 
559     // Override reference list with ref surface passed from DDI
560     uint8_t surfCount = 0;
561     uint8_t surfIndex = 0;
562     if (m_osInterface->pfnIsMismatchOrderProgrammingSupported())
563     {
564         while (surfIndex < CODEC_AVC_NUM_UNCOMPRESSED_SURFACE)
565         {
566             if (!Mos_ResourceIsNull(&m_refFrameSurface[surfIndex].OsResource))
567             {
568                 m_avcRefList[surfIndex]->resRefPic = m_refFrameSurface[surfIndex].OsResource;
569             }
570             surfIndex++;
571         }
572     }
573     else
574     {
575         while (surfCount < m_refSurfaceNum && surfIndex < CODEC_AVC_NUM_UNCOMPRESSED_SURFACE)
576         {
577             if (!Mos_ResourceIsNull(&m_refFrameSurface[surfIndex].OsResource))
578             {
579                 m_avcRefList[surfIndex]->resRefPic = m_refFrameSurface[surfIndex].OsResource;
580                 surfCount++;
581             }
582             surfIndex++;
583         }
584     }
585 
586     uint8_t index, duplicatedIdx;
587     for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
588     {
589         if (!CodecHal_PictureIsInvalid(picParams->RefFrameList[i]))
590         {
591             index = picParams->RefFrameList[i].FrameIdx;
592             m_avcRefList[index]->sFrameNumber = picParams->FrameNumList[i];
593         }
594     }
595 
596     PCODEC_AVC_DMV_LIST avcMVBufList = &m_avcDmvList[0];
597     uint8_t dmvidx;
598     if (!CodecHal_PictureIsInvalid(prevPic))
599     {
600         for (i = 0; i < CODEC_AVC_NUM_REF_DMV_BUFFERS; i++)
601         {
602             avcMVBufList[i].bInUse = false;
603         }
604         for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
605         {
606             if (!CodecHal_PictureIsInvalid(picParams->RefFrameList[i]))
607             {
608                 index = picParams->RefFrameList[i].FrameIdx;
609                 avcMVBufList[m_avcRefList[index]->ucDMVIdx[0]].bInUse = true;
610                 avcMVBufList[m_avcRefList[index]->ucDMVIdx[1]].bInUse = true;
611             }
612         }
613     }
614     else if (m_avcRefList[currPic.FrameIdx]->bUsedAsRef && !m_isSecondField)
615     {
616         dmvidx = m_avcRefList[currPic.FrameIdx]->ucFrameId;
617         if (m_avcFrameStoreId[dmvidx].reUse)
618         {
619             m_avcFrameStoreId[dmvidx].reUse = false;
620         }
621         else
622         {
623             m_avcFrameStoreId[dmvidx].inUse = false;
624         }
625 
626         dmvidx = m_avcRefList[currPic.FrameIdx]->ucDMVIdx[0];
627         if (m_avcDmvList[dmvidx].bReUse)
628         {
629             m_avcDmvList[dmvidx].bReUse = false;
630         }
631         else
632         {
633             m_avcDmvList[dmvidx].bInUse = false;
634         }
635         dmvidx = m_avcRefList[currPic.FrameIdx]->ucDMVIdx[1];
636         if (m_avcDmvList[dmvidx].bReUse)
637         {
638             m_avcDmvList[dmvidx].bReUse = false;
639         }
640         else
641         {
642             m_avcDmvList[dmvidx].bInUse = false;
643         }
644     }
645 
646     if (picParams->pic_fields.reference_pic_flag)
647     {
648         if (!m_isSecondField)
649         {
650             m_avcRefList[currPic.FrameIdx]->bUsedAsRef = true;
651         }
652     }
653     else
654     {
655         m_avcRefList[currPic.FrameIdx]->bUsedAsRef = false;
656     }
657 
658     if (!m_isSecondField)
659     {
660         if (m_osInterface->pfnIsMismatchOrderProgrammingSupported())
661         {
662             for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
663             {
664                 auto frameIdx = picParams->RefFrameList[i].FrameIdx;
665                 if (frameIdx != CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC)
666                 {
667                     CODECHAL_DECODE_CHK_STATUS_RETURN(SetAndAllocateDmvBufferIndexMismatched(
668                         frameIdx,
669                         m_avcDmvBufferSize,
670                         &m_avcMvBufferIndex,
671                         m_resAvcDmvBuffers));
672                     dmvidx = m_avcMvBufferIndex;
673                     m_avcRefList[frameIdx]->ucDMVIdx[0] = dmvidx;
674                     m_avcRefList[frameIdx]->ucDMVIdx[1] = dmvidx;
675                 }
676             }
677             CODECHAL_DECODE_CHK_STATUS_RETURN(SetAndAllocateDmvBufferIndexMismatched(
678                 currPic.FrameIdx,
679                 m_avcDmvBufferSize,
680                 &m_avcMvBufferIndex,
681                 m_resAvcDmvBuffers));
682             dmvidx = m_avcMvBufferIndex;
683 
684             //first and second field will use the same DMV buffer in field mode
685             m_avcRefList[currPic.FrameIdx]->ucDMVIdx[0] = dmvidx;
686             m_avcRefList[currPic.FrameIdx]->ucDMVIdx[1] = dmvidx;
687         }
688         else
689         {
690             CODECHAL_DECODE_CHK_STATUS_RETURN(SetAndAllocateDmvBufferIndex(
691                 &m_avcDmvList[0],
692                 (bool)picParams->pic_fields.reference_pic_flag,
693                 currPic.FrameIdx,
694                 m_avcDmvBufferSize,
695                 &m_avcMvBufferIndex,
696                 m_resAvcDmvBuffers));
697 
698             dmvidx = m_avcMvBufferIndex;
699 
700             //first and second field will use the same DMV buffer in field mode
701             m_avcRefList[currPic.FrameIdx]->ucDMVIdx[0] = dmvidx;
702             m_avcRefList[currPic.FrameIdx]->ucDMVIdx[1] = dmvidx;
703         }
704     }
705     else
706     {
707         dmvidx             = m_avcRefList[currPic.FrameIdx]->ucDMVIdx[1];
708         m_avcMvBufferIndex = dmvidx;
709     }
710 
711     m_avcDmvList[dmvidx].ucFrameId = currPic.FrameIdx;
712 
713     for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
714     {
715         m_avcFrameStoreId[i].inUse = false;
716     }
717 
718     PCODEC_PIC_ID picIdx     = &m_avcPicIdx[0];
719     bool invalidRef = false;
720     for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
721     {
722         picIdx[i].bValid = false;
723         index = picParams->RefFrameList[i].FrameIdx;
724 
725         if (!CodecHal_PictureIsInvalid(picParams->RefFrameList[i]))
726         {
727             if (Mos_ResourceIsNull(&(m_avcRefList[index]->resRefPic)))
728             {
729                 // when I picture has invalid reference pictures, reallocate resource for the referecnce pictures.
730                 if (picParams->pic_fields.IntraPicFlag)
731                 {
732                     eStatus = AllocateInvalidRefBuffer();
733                     if (eStatus != MOS_STATUS_SUCCESS)
734                     {
735                         invalidRef = true;
736                         CODECHAL_DECODE_ASSERTMESSAGE("Can not allocate Invalid Ref Buffer.");
737                         continue;
738                     }
739 
740                     m_avcRefList[index]->RefPic      = picParams->RefFrameList[i];
741                     m_avcRefList[index]->resRefPic   = m_resInvalidRefBuffer;
742                     m_avcRefList[index]->bUsedAsRef  = true;
743                     m_avcRefList[index]->ucDMVIdx[0] = m_avcRefList[currPic.FrameIdx]->ucDMVIdx[0];
744                     m_avcRefList[index]->ucDMVIdx[1] = m_avcRefList[currPic.FrameIdx]->ucDMVIdx[1];
745                 }
746                 else
747                 {
748                     invalidRef = false;
749                     CODECHAL_DECODE_ASSERTMESSAGE("Found Invalid Ref.");
750                     continue;
751                 }
752             }
753 
754             duplicatedIdx = 0;
755             for (ii = 0; ii < i; ii++)
756             {
757                 if (picIdx[ii].bValid && index == picParams->RefFrameList[ii].FrameIdx)
758                 {
759                     duplicatedIdx = 1;
760                     break;
761                 }
762             }
763             if (duplicatedIdx)
764             {
765                 continue;
766             }
767 
768             m_avcRefList[index]->RefPic.PicFlags =
769                 CodecHal_CombinePictureFlags(m_avcRefList[index]->RefPic, picParams->RefFrameList[i]);
770             m_avcRefList[index]->iFieldOrderCnt[0] = picParams->FieldOrderCntList[i][0];
771             m_avcRefList[index]->iFieldOrderCnt[1] = picParams->FieldOrderCntList[i][1];
772 
773             picIdx[i].bValid = true;
774             picIdx[i].ucPicIdx = index;
775 
776             if (!CodecHal_PictureIsInvalid(prevPic) && !m_osInterface->pfnIsMismatchOrderProgrammingSupported())
777             {
778                 for (ii = 0; ii < m_avcRefList[prevPic.FrameIdx]->ucNumRef; ii++)
779                 {
780                     if (index == m_avcRefList[prevPic.FrameIdx]->RefList[ii].FrameIdx)
781                     {
782                         if (m_avcRefList[index]->ucFrameId == 0x7f)
783                         {
784                             // Should never happen, something must be wrong
785                             CODECHAL_DECODE_ASSERTMESSAGE("Invaid Ref Frame Id Found");
786                             m_avcRefList[index]->ucFrameId = 0;
787                         }
788                         m_avcFrameStoreId[m_avcRefList[index]->ucFrameId].inUse = true;
789                         break;
790                     }
791                 }
792                 if (ii == m_avcRefList[prevPic.FrameIdx]->ucNumRef)
793                 {
794                     m_avcRefList[index]->ucFrameId = 0x7f;
795                 }
796             }
797             else
798             {
799                 m_avcDmvList[m_avcRefList[index]->ucDMVIdx[0]].ucFrameId =
800                     m_avcDmvList[m_avcRefList[index]->ucDMVIdx[1]].ucFrameId =
801                         m_avcRefList[index]->ucFrameId;
802             }
803             picIdx[i].ucDMVOffset[0] = m_avcRefList[index]->ucDMVIdx[0];
804             picIdx[i].ucDMVOffset[1] = m_avcRefList[index]->ucDMVIdx[1];
805         }
806     }
807 
808     // Save the current RefList and corresponding reference frame flags
809     ii = 0;
810     uint16_t nonExistingFrameFlags = 0;
811     uint32_t usedForReferenceFlags = 0;
812     for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
813     {
814         if (picIdx[i].bValid)
815         {
816             m_avcRefList[currPic.FrameIdx]->RefList[ii] = picParams->RefFrameList[i];
817             nonExistingFrameFlags |= ((picParams->NonExistingFrameFlags >> i) & 1) << ii;
818             usedForReferenceFlags |= ((picParams->UsedForReferenceFlags >> (i * 2)) & 3) << (ii * 2);
819             ii++;
820         }
821     }
822     m_avcRefList[currPic.FrameIdx]->ucNumRef                = ii;
823     m_avcRefList[currPic.FrameIdx]->usNonExistingFrameFlags = nonExistingFrameFlags;
824     m_avcRefList[currPic.FrameIdx]->uiUsedForReferenceFlags = usedForReferenceFlags;
825 
826     if (m_osInterface->pfnIsMismatchOrderProgrammingSupported())
827     {
828         for (uint32_t ii = 0; ii < CODEC_AVC_NUM_UNCOMPRESSED_SURFACE; ii++)
829         {
830             m_avcRefList[ii]->ucFrameId = 0x7f;
831         }
832     }
833 
834     SetFrameStoreIds(currPic.FrameIdx);
835 
836     // Store CurrFieldOrderCnt
837     if (CodecHal_PictureIsBottomField(currPic))
838     {
839         m_avcRefList[currPic.FrameIdx]->iFieldOrderCnt[1] = picParams->CurrFieldOrderCnt[1];
840     }
841     else
842     {
843         m_avcRefList[currPic.FrameIdx]->iFieldOrderCnt[0] = picParams->CurrFieldOrderCnt[0];
844         if (CodecHal_PictureIsFrame(currPic))
845         {
846             m_avcRefList[currPic.FrameIdx]->iFieldOrderCnt[1] = picParams->CurrFieldOrderCnt[1];
847         }
848     }
849 
850     //MVC related inter-view reference
851     m_avcRefList[currPic.FrameIdx]->bUsedAsInterViewRef = false;
852     if (m_mvcExtPicParams)
853     {
854         if (m_mvcExtPicParams->inter_view_flag)
855         {
856             m_avcRefList[currPic.FrameIdx]->bUsedAsInterViewRef = true;
857         }
858     }
859 
860     if (invalidRef)
861     {
862         // There was an invalid reference, do not process the picture.
863         return MOS_STATUS_UNKNOWN;
864     }
865     else
866     {
867         return MOS_STATUS_SUCCESS;
868     }
869 }
870 
AllocateResourcesVariableSizes()871 MOS_STATUS CodechalDecodeAvc::AllocateResourcesVariableSizes()
872 {
873     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
874 
875     CODECHAL_DECODE_FUNCTION_ENTER;
876 
877     PCODEC_AVC_PIC_PARAMS picParam = m_avcPicParams;
878     uint32_t numMacroblocks, numSliceRecords;
879     uint16_t picWidthInMB, picHeightInMB;
880     bool invalidSliceNum = false;
881     picWidthInMB                          = MOS_MAX(m_picWidthInMbLastMaxAlloced, (picParam->pic_width_in_mbs_minus1 + 1));
882     picHeightInMB                         = MOS_MAX(m_picHeightInMbLastMaxAlloced, (picParam->pic_height_in_mbs_minus1 + 1));
883     numMacroblocks = picWidthInMB * picHeightInMB;
884 
885     numSliceRecords = numMacroblocks;
886     if (m_numSlices > numMacroblocks)
887     {
888         invalidSliceNum = true;
889         numSliceRecords = m_numSlices;
890     }
891 
892     if ((numSliceRecords > (uint32_t)m_picWidthInMbLastMaxAlloced * m_picHeightInMbLastMaxAlloced) ||
893         (m_vldSliceRecord == nullptr))
894     {
895         if (m_vldSliceRecord != nullptr)
896         {
897             MOS_FreeMemory(m_vldSliceRecord);
898         }
899         m_vldSliceRecord =
900             (PCODECHAL_VLD_SLICE_RECORD)MOS_AllocAndZeroMemory(numSliceRecords * sizeof(CODECHAL_VLD_SLICE_RECORD));
901         if (m_vldSliceRecord == nullptr)
902         {
903             CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate memory.");
904             eStatus = MOS_STATUS_NO_SPACE;
905             return eStatus;
906         }
907     }
908 
909     if (invalidSliceNum == true)
910     {
911         for (uint32_t i = 0; i < numSliceRecords; i++)
912         {
913             m_vldSliceRecord[i].dwSkip = true;
914         }
915     }
916 
917     if ((picWidthInMB > m_picWidthInMbLastMaxAlloced) ||
918         Mos_ResourceIsNull(&m_resMfdDeblockingFilterRowStoreScratchBuffer))
919     {
920         if (!Mos_ResourceIsNull(&m_resMfdDeblockingFilterRowStoreScratchBuffer))
921         {
922             m_osInterface->pfnFreeResource(
923                 m_osInterface,
924                 &m_resMfdDeblockingFilterRowStoreScratchBuffer);
925         }
926 
927         // Deblocking Filter Row Store Scratch buffer
928         //(Num MacroBlock Width) * (Num Cachlines) * (Cachline size)
929         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
930                                                       &m_resMfdDeblockingFilterRowStoreScratchBuffer,
931                                                       picWidthInMB * 4 * CODECHAL_CACHELINE_SIZE,
932                                                       "DeblockingScratchBuffer"),
933             "Failed to allocate Deblocking Filter Row Store Scratch Buffer.");
934     }
935 
936     if (m_mfxInterface->IsBsdMpcRowstoreCacheEnabled() == false)
937     {
938         uint16_t  tempBsdMpcRowStoreScratchBufferPicWidthInMB;
939         tempBsdMpcRowStoreScratchBufferPicWidthInMB = MOS_MAX(m_bsdMpcRowStoreScratchBufferPicWidthInMb, (picParam->pic_width_in_mbs_minus1 + 1));
940 
941         if ((tempBsdMpcRowStoreScratchBufferPicWidthInMB > m_bsdMpcRowStoreScratchBufferPicWidthInMb) ||
942             Mos_ResourceIsNull(&m_resBsdMpcRowStoreScratchBuffer))
943         {
944             if (!Mos_ResourceIsNull(&m_resBsdMpcRowStoreScratchBuffer))
945             {
946                 m_osInterface->pfnFreeResource(
947                     m_osInterface,
948                     &m_resBsdMpcRowStoreScratchBuffer);
949             }
950             // BSD/MPC Row Store Scratch buffer
951             // (FrameWidth in MB) * (2) * (CacheLine size per MB)
952             CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
953                                                           &m_resBsdMpcRowStoreScratchBuffer,
954                                                           tempBsdMpcRowStoreScratchBufferPicWidthInMB * 2 * CODECHAL_CACHELINE_SIZE,
955                                                           "MpcScratchBuffer"),
956                 "Failed to allocate BSD/MPC Row Store Scratch Buffer.");
957         }
958 
959         //record the width and height used for allocation internal resources.
960         m_bsdMpcRowStoreScratchBufferPicWidthInMb = tempBsdMpcRowStoreScratchBufferPicWidthInMB;
961     }
962 
963     if (m_mfxInterface->IsIntraRowstoreCacheEnabled() == false)
964     {
965         uint16_t  tempMfdIntraRowStoreScratchBufferPicWidthInMB;
966         tempMfdIntraRowStoreScratchBufferPicWidthInMB = MOS_MAX(m_mfdIntraRowStoreScratchBufferPicWidthInMb, (picParam->pic_width_in_mbs_minus1 + 1));
967 
968         if ((tempMfdIntraRowStoreScratchBufferPicWidthInMB > m_mfdIntraRowStoreScratchBufferPicWidthInMb) ||
969             Mos_ResourceIsNull(&m_resMfdIntraRowStoreScratchBuffer))
970         {
971             if (!Mos_ResourceIsNull(&m_resMfdIntraRowStoreScratchBuffer))
972             {
973                 m_osInterface->pfnFreeResource(
974                     m_osInterface,
975                     &m_resMfdIntraRowStoreScratchBuffer);
976             }
977             // Intra Row Store Scratch buffer
978             // (FrameWidth in MB) * (CacheLine size per MB)
979             CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
980                                                           &m_resMfdIntraRowStoreScratchBuffer,
981                                                           tempMfdIntraRowStoreScratchBufferPicWidthInMB * CODECHAL_CACHELINE_SIZE,
982                                                           "IntraScratchBuffer"),
983                 "Failed to allocate AVC BSD Intra Row Store Scratch Buffer.");
984         }
985 
986         //record the width and height used for allocation internal resources.
987         m_mfdIntraRowStoreScratchBufferPicWidthInMb = tempMfdIntraRowStoreScratchBufferPicWidthInMB;
988     }
989 
990     if (m_mfxInterface->IsMprRowstoreCacheEnabled() == false)
991     {
992         uint16_t  tempMprRowStoreScratchBufferPicWidthInMB;
993         tempMprRowStoreScratchBufferPicWidthInMB = MOS_MAX(m_mprRowStoreScratchBufferPicWidthInMb, (picParam->pic_width_in_mbs_minus1 + 1));
994 
995         if ((tempMprRowStoreScratchBufferPicWidthInMB > m_mprRowStoreScratchBufferPicWidthInMb) ||
996             Mos_ResourceIsNull(&m_resMprRowStoreScratchBuffer))
997         {
998             if (!Mos_ResourceIsNull(&m_resMprRowStoreScratchBuffer))
999             {
1000                 m_osInterface->pfnFreeResource(
1001                     m_osInterface,
1002                     &m_resMprRowStoreScratchBuffer);
1003             }
1004             // MPR Row Store Scratch buffer
1005             // (FrameWidth in MB) * (CacheLine size per MB) * 2
1006             // IVB+ platforms need to have double MPR size for MBAFF
1007             CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
1008                                                           &m_resMprRowStoreScratchBuffer,
1009                                                           tempMprRowStoreScratchBufferPicWidthInMB * CODECHAL_CACHELINE_SIZE * 2,
1010                                                           "MprScratchBuffer"),
1011                 "Failed to allocate AVC BSD MPR Row Store Scratch Buffer.");
1012         }
1013 
1014         //record the width and height used for allocation internal resources.
1015         m_mprRowStoreScratchBufferPicWidthInMb = tempMprRowStoreScratchBufferPicWidthInMB;
1016     }
1017 
1018     uint32_t ctr;
1019     if ((picWidthInMB > m_picWidthInMbLastMaxAlloced) ||
1020         (picHeightInMB > m_picHeightInMbLastMaxAlloced) ||
1021         (m_avcDmvBufferSize == 0))
1022     {
1023         uint32_t maxMvBuf = m_osInterface->pfnIsMismatchOrderProgrammingSupported() ?
1024             CODEC_AVC_NUM_UNCOMPRESSED_SURFACE :
1025             CODEC_AVC_NUM_DMV_BUFFERS;
1026         for (ctr = 0; ctr < maxMvBuf; ctr++)
1027         {
1028             if (!Mos_ResourceIsNull(&m_resAvcDmvBuffers[ctr]))
1029             {
1030                 m_osInterface->pfnFreeResource(
1031                     m_osInterface,
1032                     &m_resAvcDmvBuffers[ctr]);
1033             }
1034         }
1035 
1036         // AVC MV buffer, 64 bytes per MB
1037         m_avcDmvBufferSize =
1038             64 * picWidthInMB * (uint32_t)(MOS_ALIGN_CEIL(picHeightInMB, 2));
1039 
1040         for (ctr = 0; ctr < 4; ctr++)
1041         {
1042             // Allocate first 3 ref DMV buffers and then grow as needed, always
1043             // allocate the last DMV buffer which is used for non referenced pictures.
1044             if (ctr == 3)
1045             {
1046                 ctr = CODEC_AVC_NUM_DMV_BUFFERS - 1;
1047             }
1048 
1049             CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
1050                                                           &m_resAvcDmvBuffers[ctr],
1051                                                           m_avcDmvBufferSize,
1052                                                           "MvBuffer",
1053                                                           true),
1054                 "Failed to allocate Linux WA AVC BSD MV Buffer.");
1055         }
1056     }
1057 
1058     if (m_secureDecoder)
1059     {
1060         CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->AllocateResource(this));
1061     }
1062 
1063     //record the width and height used for allocation internal resources.
1064     m_picWidthInMbLastMaxAlloced  = picWidthInMB;
1065     m_picHeightInMbLastMaxAlloced = picHeightInMB;
1066 
1067     return eStatus;
1068 }
1069 
AllocateResourcesFixedSizes()1070 MOS_STATUS CodechalDecodeAvc::AllocateResourcesFixedSizes()
1071 {
1072     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1073 
1074     CODECHAL_DECODE_FUNCTION_ENTER;
1075 
1076     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
1077         m_osInterface,
1078         &m_resSyncObjectWaContextInUse));
1079 
1080     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
1081         m_osInterface,
1082         &m_resSyncObjectVideoContextInUse));
1083 
1084     MOS_LOCK_PARAMS lockFlagsWriteOnly;
1085     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
1086     lockFlagsWriteOnly.WriteOnly = 1;
1087 
1088     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalAllocateDataList(
1089         m_avcRefList,
1090         CODEC_AVC_NUM_UNCOMPRESSED_SURFACE));
1091 
1092     m_currPic.PicFlags = PICTURE_INVALID;
1093     m_currPic.FrameIdx = CODEC_AVC_NUM_UNCOMPRESSED_SURFACE;
1094 
1095     return eStatus;
1096 }
1097 
InitMmcState()1098 MOS_STATUS CodechalDecodeAvc::InitMmcState()
1099 {
1100 #ifdef _MMC_SUPPORTED
1101     m_mmc = MOS_New(CodechalMmcDecodeAvc, m_hwInterface, this);
1102     CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
1103 #endif
1104     return MOS_STATUS_SUCCESS;
1105 }
1106 
InitSfcState()1107 MOS_STATUS CodechalDecodeAvc::InitSfcState()
1108 {
1109 #ifdef _DECODE_PROCESSING_SUPPORTED
1110     m_sfcState = MOS_New(CodechalAvcSfcState);
1111     CODECHAL_DECODE_CHK_NULL_RETURN(m_sfcState);
1112     CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->InitializeSfcState(
1113         this,
1114         m_hwInterface,
1115         m_osInterface));
1116 #endif
1117     return MOS_STATUS_SUCCESS;
1118 }
1119 
AllocateStandard(CodechalSetting * settings)1120 MOS_STATUS CodechalDecodeAvc::AllocateStandard(
1121     CodechalSetting *settings)
1122 {
1123     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1124 
1125     CODECHAL_DECODE_FUNCTION_ENTER;
1126 
1127     CODECHAL_DECODE_CHK_NULL_RETURN(settings);
1128 
1129     CODECHAL_DECODE_CHK_STATUS_RETURN(InitMmcState());
1130 
1131     if (settings->downsamplingHinted)
1132     {
1133         bool isComputeContextEnabled = false;
1134         MOS_GPUCTX_CREATOPTIONS createOption;
1135 
1136 #if (_DEBUG || _RELEASE_INTERNAL)
1137         MOS_USER_FEATURE_VALUE_DATA userFeatureData;
1138         MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1139         MOS_UserFeature_ReadValue_ID(
1140             nullptr,
1141             __MEDIA_USER_FEATURE_VALUE_DECODE_ENABLE_COMPUTE_CONTEXT_ID,
1142             &userFeatureData,
1143             m_osInterface->pOsContext);
1144         isComputeContextEnabled = (userFeatureData.u32Data) ? true : false;
1145 #endif
1146 
1147         if (!MEDIA_IS_SKU(m_skuTable, FtrCCSNode))
1148         {
1149             isComputeContextEnabled = false;
1150         }
1151 
1152         if (isComputeContextEnabled)
1153         {
1154             // Create Render Context for field scaling
1155             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
1156                 m_osInterface,
1157                 MOS_GPU_CONTEXT_COMPUTE,
1158                 MOS_GPU_NODE_COMPUTE,
1159                 &createOption));
1160             m_renderContext = MOS_GPU_CONTEXT_COMPUTE;
1161         }
1162         else
1163         {
1164             // Create Render Context for field scaling
1165             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
1166                 m_osInterface,
1167                 MOS_GPU_CONTEXT_RENDER,
1168                 MOS_GPU_NODE_3D,
1169                 &createOption));
1170             m_renderContext = MOS_GPU_CONTEXT_RENDER;
1171         }
1172     }
1173 
1174     m_intelEntrypointInUse = (settings->intelEntrypointInUse) ? true : false;
1175     m_width = settings->width;
1176     m_height = settings->height;
1177     m_picWidthInMb         = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_width);
1178     m_picHeightInMb        = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_height);
1179     m_shortFormatInUse     = (settings->shortFormatInUse) ? true : false;
1180 
1181     CODECHAL_DECODE_CHK_STATUS_RETURN(InitSfcState());
1182 
1183     for (uint8_t i = 0; i < CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS; i++)
1184     {
1185         m_firstFieldIdxList[i] = CODECHAL_DECODE_AVC_INVALID_FRAME_IDX;
1186     }
1187 
1188     // Picture Level Commands
1189     m_hwInterface->GetMfxStateCommandsDataSize(
1190         CODECHAL_DECODE_MODE_AVCVLD,
1191         &m_commandBufferSizeNeeded,
1192         &m_commandPatchListSizeNeeded,
1193         m_shortFormatInUse);
1194 
1195     // Slice Level Commands (cannot be placed in 2nd level batch)
1196     m_hwInterface->GetMfxPrimitiveCommandsDataSize(
1197         CODECHAL_DECODE_MODE_AVCVLD,
1198         &m_standardDecodeSizeNeeded,
1199         &m_standardDecodePatchListSizeNeeded,
1200         m_shortFormatInUse);
1201 
1202     CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResourcesFixedSizes());
1203 
1204     return eStatus;
1205 }
1206 
~CodechalDecodeAvc()1207 CodechalDecodeAvc::~CodechalDecodeAvc()
1208 {
1209     CODECHAL_DECODE_FUNCTION_ENTER;
1210 
1211     CodecHalFreeDataList(m_avcRefList, CODEC_AVC_NUM_UNCOMPRESSED_SURFACE);
1212 
1213     m_osInterface->pfnDestroySyncResource(
1214         m_osInterface,
1215         &m_resSyncObjectWaContextInUse);
1216 
1217     m_osInterface->pfnDestroySyncResource(
1218         m_osInterface,
1219         &m_resSyncObjectVideoContextInUse);
1220 
1221     MOS_FreeMemory(m_vldSliceRecord);
1222 
1223     m_osInterface->pfnFreeResource(
1224         m_osInterface,
1225         &m_resMfdDeblockingFilterRowStoreScratchBuffer);
1226 
1227     m_osInterface->pfnFreeResource(
1228         m_osInterface,
1229         &m_resBsdMpcRowStoreScratchBuffer);
1230 
1231     m_osInterface->pfnFreeResource(
1232         m_osInterface,
1233         &m_resMfdIntraRowStoreScratchBuffer);
1234 
1235     m_osInterface->pfnFreeResource(
1236         m_osInterface,
1237         &m_resMprRowStoreScratchBuffer);
1238 
1239     if (!Mos_ResourceIsNull(&m_resMonoPictureChromaBuffer))
1240     {
1241         m_osInterface->pfnFreeResource(
1242             m_osInterface,
1243             &m_resMonoPictureChromaBuffer);
1244     }
1245 
1246     uint32_t maxMvBuf = m_osInterface->pfnIsMismatchOrderProgrammingSupported() ?
1247         CODEC_AVC_NUM_UNCOMPRESSED_SURFACE :
1248         CODEC_AVC_NUM_DMV_BUFFERS;
1249     for (uint32_t ctr = 0; ctr < maxMvBuf; ctr++)
1250     {
1251         m_osInterface->pfnFreeResource(
1252             m_osInterface,
1253             &m_resAvcDmvBuffers[ctr]);
1254     }
1255 
1256     if (!Mos_ResourceIsNull(&m_resInvalidRefBuffer))
1257     {
1258         m_osInterface->pfnFreeResource(
1259             m_osInterface,
1260             &m_resInvalidRefBuffer);
1261     }
1262 
1263 #ifdef _DECODE_PROCESSING_SUPPORTED
1264     if (m_sfcState)
1265     {
1266         MOS_Delete(m_sfcState);
1267         m_sfcState = nullptr;
1268     }
1269 #endif
1270 
1271     return;
1272 }
1273 
SetFrameStates()1274 MOS_STATUS CodechalDecodeAvc::SetFrameStates()
1275 {
1276     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1277 
1278     CODECHAL_DECODE_FUNCTION_ENTER;
1279 
1280     CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_destSurface);
1281 
1282     m_dataSize          = m_decodeParams.m_dataSize;
1283     m_dataOffset        = m_decodeParams.m_dataOffset;
1284     m_numSlices         = m_decodeParams.m_numSlices;
1285     m_avcPicParams      = (PCODEC_AVC_PIC_PARAMS)m_decodeParams.m_picParams;
1286     m_mvcExtPicParams   = (PCODEC_MVC_EXT_PIC_PARAMS)m_decodeParams.m_extPicParams;
1287     m_avcSliceParams    = (PCODEC_AVC_SLICE_PARAMS)m_decodeParams.m_sliceParams;
1288     m_avcIqMatrixParams = (PCODEC_AVC_IQ_MATRIX_PARAMS)m_decodeParams.m_iqMatrixBuffer;
1289     m_destSurface       = *(m_decodeParams.m_destSurface);
1290     m_refFrameSurface   = m_decodeParams.m_refFrameSurface;
1291     m_refSurfaceNum     = m_decodeParams.m_refSurfaceNum;
1292     CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_dataBuffer);
1293     m_resDataBuffer       = *(m_decodeParams.m_dataBuffer);
1294     m_picIdRemappingInUse = (m_decodeParams.m_picIdRemappingInUse) ? true : false;
1295 
1296     m_cencBuf = m_decodeParams.m_cencBuf;
1297     m_fullFrameData = m_decodeParams.m_bFullFrameData;
1298 
1299     CODECHAL_DECODE_CHK_NULL_RETURN(m_avcPicParams);
1300     CODECHAL_DECODE_CHK_NULL_RETURN(m_avcIqMatrixParams);
1301 
1302     m_width             = (m_avcPicParams->pic_width_in_mbs_minus1 + 1) * CODECHAL_MACROBLOCK_WIDTH;
1303     m_height            = (m_avcPicParams->pic_height_in_mbs_minus1 + 1) * CODECHAL_MACROBLOCK_HEIGHT;
1304     m_deblockingEnabled = false;
1305 
1306     if (m_shortFormatInUse)
1307     {
1308         // When HW parses the slice_header, disable_deblocking_filter_idc is not yet known,
1309         // so always enable ILDB in this case.
1310         m_deblockingEnabled = true;
1311     }
1312     else
1313     {
1314         for (uint32_t i = 0; i < m_numSlices; i++)
1315         {
1316             if (m_avcSliceParams[i].disable_deblocking_filter_idc != 1)
1317             {
1318                 m_deblockingEnabled = true;
1319                 break;
1320             }
1321         }
1322     }
1323 
1324     if (m_mfxInterface->IsRowStoreCachingSupported())
1325     {
1326         MHW_VDBOX_ROWSTORE_PARAMS rowstoreParams;
1327         MOS_ZeroMemory(&rowstoreParams, sizeof(rowstoreParams));
1328         rowstoreParams.Mode = CODECHAL_DECODE_MODE_AVCVLD;
1329         rowstoreParams.bMbaff     = m_avcPicParams->seq_fields.mb_adaptive_frame_field_flag;
1330         rowstoreParams.bIsFrame   = m_avcPicParams->seq_fields.frame_mbs_only_flag;
1331         rowstoreParams.dwPicWidth = m_width;
1332         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->SetRowstoreCachingOffsets(&rowstoreParams));
1333     }
1334 
1335     CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResourcesVariableSizes());
1336 
1337     CODECHAL_DECODE_CHK_STATUS_RETURN(SetPictureStructs());
1338 
1339     CODECHAL_DECODE_CHK_STATUS_RETURN(FormatAvcMonoPicture(m_decodeParams.m_destSurface));
1340 
1341     if (m_avcPicParams->pic_fields.IntraPicFlag)
1342     {
1343         m_perfType = I_TYPE;
1344     }
1345     else
1346     {
1347         // Not possible to determine whether P or B is used for short format.
1348         // For long format iterating through all of the slices to determine P vs
1349         // B, so in order to avoid this, declare all other pictures MIXED_TYPE.
1350         m_perfType = MIXED_TYPE;
1351     }
1352 #ifdef _DECODE_PROCESSING_SUPPORTED
1353     auto decProcessingParams = (DecodeProcessingParams *)m_decodeParams.m_procParams;
1354     if (decProcessingParams != nullptr)
1355     {
1356         if (!decProcessingParams->m_isReferenceOnlyPattern && m_downsamplingHinted)
1357         {
1358             CODECHAL_DECODE_CHK_NULL_RETURN(m_fieldScalingInterface);
1359         }
1360 
1361         CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->CheckAndInitialize(
1362             decProcessingParams,
1363             m_avcPicParams,
1364             m_width,
1365             m_height,
1366             m_deblockingEnabled));
1367 
1368         if (!((!CodecHal_PictureIsFrame(m_avcPicParams->CurrPic) ||
1369              m_avcPicParams->seq_fields.mb_adaptive_frame_field_flag) &&
1370              (m_downsamplingHinted && m_fieldScalingInterface->IsFieldScalingSupported(decProcessingParams))) &&
1371              m_sfcState->m_sfcPipeOut == false &&
1372             !decProcessingParams->m_isReferenceOnlyPattern)
1373         {
1374             m_vdSfcSupported = false;
1375         }
1376         else
1377         {
1378             m_vdSfcSupported = true;
1379         }
1380     }
1381 #endif
1382     m_crrPic = m_avcPicParams->CurrPic;
1383 
1384     if(m_fullFieldsFrame == (PICTURE_BOTTOM_FIELD | PICTURE_TOP_FIELD))
1385     {
1386         m_fullFieldsFrame = 0;
1387     }
1388 
1389     m_secondField = false;
1390 
1391     if(CodecHal_PictureIsField(m_avcPicParams->CurrPic))
1392     {
1393        if(CodecHal_PictureIsTopField(m_avcPicParams->CurrPic))
1394        {
1395            m_fullFieldsFrame |= PICTURE_TOP_FIELD;
1396        }
1397        if (CodecHal_PictureIsBottomField(m_avcPicParams->CurrPic))
1398        {
1399            m_fullFieldsFrame |= PICTURE_BOTTOM_FIELD;
1400        }
1401     }
1402     else
1403     {
1404         m_fullFieldsFrame = 0;
1405     }
1406 
1407     if(m_fullFieldsFrame == (PICTURE_BOTTOM_FIELD | PICTURE_TOP_FIELD))
1408     {
1409         m_secondField = true;
1410     }
1411 
1412     if (m_pCodechalOcaDumper)
1413     {
1414         m_pCodechalOcaDumper->SetAvcDecodeParam(
1415             m_avcPicParams,
1416             m_avcSliceParams,
1417             m_numSlices);
1418     }
1419 
1420     CODECHAL_DEBUG_TOOL(
1421         m_debugInterface->m_currPic     = m_crrPic;
1422         m_debugInterface->m_secondField = m_secondField;
1423         m_debugInterface->m_frameType   = m_perfType;
1424 
1425         if (m_avcPicParams) {
1426             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpPicParams(
1427                 m_avcPicParams));
1428         }
1429 
1430         if (m_avcIqMatrixParams) {
1431             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpIQParams(
1432                 m_avcIqMatrixParams));
1433         }
1434 
1435         if (m_mvcExtPicParams) {
1436             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpMvcExtPicParams(
1437                 m_mvcExtPicParams));
1438         }
1439 
1440         if (m_avcSliceParams) {
1441             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpSliceParams(
1442                 m_avcSliceParams,
1443                 m_numSlices));
1444         })
1445 
1446     return eStatus;
1447 }
1448 
InitPicMhwParams(PIC_MHW_PARAMS * picMhwParams)1449 MOS_STATUS CodechalDecodeAvc::InitPicMhwParams(
1450     PIC_MHW_PARAMS              *picMhwParams)
1451 {
1452      MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1453 
1454     CODECHAL_DECODE_FUNCTION_ENTER;
1455     PMOS_RESOURCE firstValidFrame = nullptr;
1456 
1457     if (MEDIA_IS_WA(m_waTable, WaDummyReference) && !Mos_ResourceIsNull(&m_dummyReference.OsResource))
1458     {
1459         firstValidFrame = &m_dummyReference.OsResource;
1460     }
1461     else
1462     {
1463         firstValidFrame = &m_destSurface.OsResource;
1464     }
1465 
1466     CODECHAL_DECODE_CHK_NULL_RETURN(picMhwParams);
1467 
1468     picMhwParams->PipeModeSelectParams = {};
1469     picMhwParams->PipeBufAddrParams = {};
1470     picMhwParams->ImgParams = {};
1471     MOS_ZeroMemory(&picMhwParams->SurfaceParams,
1472         sizeof(picMhwParams->SurfaceParams));
1473     MOS_ZeroMemory(&picMhwParams->IndObjBaseAddrParams,
1474         sizeof(picMhwParams->IndObjBaseAddrParams));
1475     MOS_ZeroMemory(&picMhwParams->BspBufBaseAddrParams,
1476         sizeof(picMhwParams->BspBufBaseAddrParams));
1477     MOS_ZeroMemory(&picMhwParams->QmParams,
1478         sizeof(picMhwParams->QmParams));
1479     MOS_ZeroMemory(&picMhwParams->PicIdParams,
1480         sizeof(picMhwParams->PicIdParams));
1481     MOS_ZeroMemory(&picMhwParams->AvcDirectmodeParams,
1482         sizeof(picMhwParams->AvcDirectmodeParams));
1483 
1484     picMhwParams->PipeModeSelectParams.Mode = CODECHAL_DECODE_MODE_AVCVLD;
1485     //enable decodestreamout if either app or codechal dump need it
1486     picMhwParams->PipeModeSelectParams.bStreamOutEnabled     =
1487         m_decodeParams.m_streamOutEnabled || m_streamOutEnabled;
1488     picMhwParams->PipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled;
1489     picMhwParams->PipeModeSelectParams.bPreDeblockOutEnable  = !m_deblockingEnabled;
1490     picMhwParams->PipeModeSelectParams.bShortFormatInUse     = m_shortFormatInUse;
1491 
1492     picMhwParams->SurfaceParams.Mode = CODECHAL_DECODE_MODE_AVCVLD;
1493     picMhwParams->SurfaceParams.psSurface = &m_destSurface;
1494 
1495     picMhwParams->PipeBufAddrParams.Mode = CODECHAL_DECODE_MODE_AVCVLD;
1496     if (m_deblockingEnabled)
1497     {
1498         picMhwParams->PipeBufAddrParams.psPostDeblockSurface = &m_destSurface;
1499     }
1500     else
1501     {
1502         picMhwParams->PipeBufAddrParams.psPreDeblockSurface = &m_destSurface;
1503     }
1504 
1505 #ifdef _MMC_SUPPORTED
1506     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&picMhwParams->PipeBufAddrParams));
1507 #endif
1508 
1509     picMhwParams->PipeBufAddrParams.presMfdIntraRowStoreScratchBuffer =
1510         &m_resMfdIntraRowStoreScratchBuffer;
1511     picMhwParams->PipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
1512         &m_resMfdDeblockingFilterRowStoreScratchBuffer;
1513 
1514     //Do not support export decode streamout to app buffer and codechal_dump simultenously
1515     //which can lead to extra memory copy
1516     //decode streamout to application
1517     if (m_decodeParams.m_streamOutEnabled)
1518     {
1519         picMhwParams->PipeBufAddrParams.presStreamOutBuffer = m_decodeParams.m_externalStreamOutBuffer;
1520     }
1521     //decode streamout to codechal_dump
1522     else if (m_streamOutEnabled)
1523     {
1524         picMhwParams->PipeBufAddrParams.presStreamOutBuffer =
1525             &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
1526 
1527         CODECHAL_DEBUG_TOOL(
1528             // mark the buffer as in-use
1529             m_streamOutCurrStatusIdx[m_streamOutCurrBufIdx] = 0;
1530         )
1531     }
1532 
1533     MOS_SURFACE dstSurface;
1534     uint8_t firstValidFrameId = CODEC_AVC_MAX_NUM_REF_FRAME;
1535     uint8_t activeFrameCnt = 0;
1536     uint8_t picIdx, frameId, i;
1537     MOS_ZeroMemory(m_presReferences, (sizeof(PMOS_RESOURCE) * CODEC_AVC_MAX_NUM_REF_FRAME));
1538     for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
1539     {
1540         if (m_avcPicIdx[i].bValid)
1541         {
1542             activeFrameCnt++;
1543             picIdx = m_avcPicIdx[i].ucPicIdx;
1544             frameId =
1545                 (m_picIdRemappingInUse) ? i : m_avcRefList[picIdx]->ucFrameId;
1546 
1547             m_presReferences[frameId] =
1548                 &(m_avcRefList[picIdx]->resRefPic);
1549 
1550             CODECHAL_DEBUG_TOOL(
1551                 MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
1552                 dstSurface.Format     = Format_NV12;
1553                 dstSurface.OsResource = *(m_presReferences[frameId]);
1554                 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1555                     m_osInterface,
1556                     &dstSurface));
1557 
1558                 m_debugInterface->m_refIndex = frameId;
1559                 std::string refSurfName      = "RefSurf[" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex)) + "]";
1560                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
1561                     &dstSurface,
1562                     CodechalDbgAttr::attrDecodeReferenceSurfaces,
1563                     refSurfName.data()));)
1564 
1565             if (frameId < firstValidFrameId)
1566             {
1567                 firstValidFrameId = frameId;
1568                 firstValidFrame   = m_presReferences[frameId];
1569             }
1570         }
1571     }
1572 
1573     for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
1574     {
1575         // error concealment for the unset reference addresses
1576         if (!m_presReferences[i])
1577         {
1578             m_presReferences[i] = firstValidFrame;
1579         }
1580     }
1581 
1582 #ifdef _MMC_SUPPORTED
1583     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&picMhwParams->PipeBufAddrParams));
1584 
1585     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode));
1586 #endif
1587 
1588     CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(picMhwParams->PipeBufAddrParams.presReferences, sizeof(PMOS_RESOURCE) * CODEC_AVC_MAX_NUM_REF_FRAME, m_presReferences, sizeof(PMOS_RESOURCE) * CODEC_AVC_MAX_NUM_REF_FRAME));
1589 
1590     picMhwParams->IndObjBaseAddrParams.Mode           = CODECHAL_DECODE_MODE_AVCVLD;
1591     picMhwParams->IndObjBaseAddrParams.presDataBuffer = &m_resDataBuffer;
1592     picMhwParams->IndObjBaseAddrParams.dwDataSize     = m_dataSize;
1593     picMhwParams->IndObjBaseAddrParams.dwDataOffset   = m_dataOffset;
1594 
1595     if (m_secureDecoder)
1596     {
1597         CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->SetBitstreamBuffer(&picMhwParams->IndObjBaseAddrParams));
1598     }
1599 
1600     picMhwParams->BspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer;
1601     picMhwParams->BspBufBaseAddrParams.presMprRowStoreScratchBuffer    = &m_resMprRowStoreScratchBuffer;
1602 
1603     picMhwParams->QmParams.Standard     = CODECHAL_AVC;
1604     picMhwParams->QmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIqMatrixParams;
1605 
1606     picMhwParams->PicIdParams.bPicIdRemappingInUse = m_picIdRemappingInUse;
1607     picMhwParams->PicIdParams.pAvcPicIdx           = &(m_avcPicIdx[0]);
1608 
1609     picMhwParams->ImgParams.pAvcPicParams    = m_avcPicParams;
1610     picMhwParams->ImgParams.pMvcExtPicParams = m_mvcExtPicParams;
1611     picMhwParams->ImgParams.ucActiveFrameCnt = activeFrameCnt;
1612 
1613     picMhwParams->AvcDirectmodeParams.CurrPic                 = m_currPic;
1614     picMhwParams->AvcDirectmodeParams.uiUsedForReferenceFlags = m_avcPicParams->UsedForReferenceFlags;
1615     picMhwParams->AvcDirectmodeParams.presAvcDmvBuffers       = &(m_resAvcDmvBuffers[0]);
1616     picMhwParams->AvcDirectmodeParams.ucAvcDmvIdx             = m_avcMvBufferIndex;
1617     picMhwParams->AvcDirectmodeParams.pAvcDmvList             = &(m_avcDmvList[0]);
1618     picMhwParams->AvcDirectmodeParams.pAvcPicIdx              = &(m_avcPicIdx[0]);
1619     picMhwParams->AvcDirectmodeParams.avcRefList              = (void**)m_avcRefList;
1620     picMhwParams->AvcDirectmodeParams.bPicIdRemappingInUse    = m_picIdRemappingInUse;
1621     picMhwParams->AvcDirectmodeParams.presMvcDummyDmvBuffer   = &(m_resMvcDummyDmvBuffer[(m_avcPicParams->seq_fields.direct_8x8_inference_flag) ? 1 : 0]);
1622 
1623     CODECHAL_DEBUG_TOOL(
1624 
1625         CODEC_REF_LIST * *refList;
1626         MHW_MI_CHK_NULL(refList = (CODEC_REF_LIST **)picMhwParams->AvcDirectmodeParams.avcRefList);
1627 
1628         for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME; i++)
1629         {
1630             if (picMhwParams->AvcDirectmodeParams.pAvcPicIdx[i].bValid)
1631             {
1632                 uint8_t idx   = picMhwParams->AvcDirectmodeParams.pAvcPicIdx[i].ucPicIdx;
1633                 uint8_t picID = picMhwParams->AvcDirectmodeParams.bPicIdRemappingInUse ? i : refList[idx]->ucFrameId;
1634                 uint8_t mvIdx = refList[idx]->ucDMVIdx[0];
1635 
1636                 // dump Reference mvdata
1637                 std::string mvBufDumpName = "_DEC_Ref_MV_" + std::to_string(i);
1638                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1639                     &picMhwParams->AvcDirectmodeParams.presAvcDmvBuffers[mvIdx],
1640                     CodechalDbgAttr::attrMvData,
1641                     mvBufDumpName.c_str(),
1642                     m_avcDmvBufferSize));
1643             }
1644         }
1645 
1646         // dump Current mvdata
1647         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1648         &picMhwParams->AvcDirectmodeParams.presAvcDmvBuffers[picMhwParams->AvcDirectmodeParams.ucAvcDmvIdx],
1649             CodechalDbgAttr::attrMvData,
1650             "DEC_Cur_MV_",
1651             m_avcDmvBufferSize));
1652         );
1653 
1654     return eStatus;
1655 }
1656 
AddPictureCmds(PMOS_COMMAND_BUFFER cmdBuf,PIC_MHW_PARAMS * picMhwParams)1657 MOS_STATUS CodechalDecodeAvc::AddPictureCmds(
1658     PMOS_COMMAND_BUFFER         cmdBuf,
1659     PIC_MHW_PARAMS              *picMhwParams)
1660 {
1661     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1662 
1663     CODECHAL_DECODE_FUNCTION_ENTER;
1664 
1665     CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuf);
1666     CODECHAL_DECODE_CHK_NULL_RETURN(picMhwParams);
1667 
1668     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(cmdBuf, &picMhwParams->PipeModeSelectParams));
1669 
1670 #ifdef _DECODE_PROCESSING_SUPPORTED
1671     CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->AddSfcCommands(cmdBuf));
1672 #endif
1673 
1674     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(cmdBuf, &picMhwParams->SurfaceParams));
1675 
1676     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(cmdBuf, &picMhwParams->PipeBufAddrParams));
1677 
1678     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(cmdBuf, &picMhwParams->IndObjBaseAddrParams));
1679 
1680     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(cmdBuf, &picMhwParams->BspBufBaseAddrParams));
1681 
1682     if (m_shortFormatInUse)
1683     {
1684         MHW_VDBOX_AVC_DPB_PARAMS dpbParams;
1685         MOS_ZeroMemory(&dpbParams, sizeof(dpbParams));
1686         dpbParams.pAvcPicParams        = m_avcPicParams;
1687         dpbParams.pMvcExtPicParams     = m_mvcExtPicParams;
1688         dpbParams.ppAvcRefList         = &(m_avcRefList[0]);
1689         dpbParams.pAvcPicIdx           = &(m_avcPicIdx[0]);
1690         dpbParams.bPicIdRemappingInUse = m_picIdRemappingInUse;
1691 
1692         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdAvcDpbCmd(cmdBuf, &dpbParams));
1693     }
1694 
1695     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdAvcPicidCmd(cmdBuf, &picMhwParams->PicIdParams));
1696 
1697     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgCmd(cmdBuf, nullptr, &picMhwParams->ImgParams));
1698 
1699     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(cmdBuf, &picMhwParams->QmParams));
1700 
1701     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcDirectmodeCmd(cmdBuf, &picMhwParams->AvcDirectmodeParams));
1702 
1703     return eStatus;
1704 }
1705 
DecodeStateLevel()1706 MOS_STATUS CodechalDecodeAvc::DecodeStateLevel()
1707 {
1708     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1709 
1710     CODECHAL_DECODE_FUNCTION_ENTER;
1711 
1712     if (m_secureDecoder)
1713     {
1714         CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->Execute(this));
1715     }
1716 
1717     MOS_COMMAND_BUFFER cmdBuffer;
1718     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1719 
1720     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
1721         &cmdBuffer, true));
1722 
1723     PIC_MHW_PARAMS picMhwParams;
1724     CODECHAL_DECODE_CHK_STATUS_RETURN(InitPicMhwParams(&picMhwParams));
1725 
1726     auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
1727     HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
1728 
1729     if (m_cencBuf && m_cencBuf->checkStatusRequired)
1730     {
1731         CODECHAL_DECODE_COND_ASSERTMESSAGE((m_vdboxIndex > m_hwInterface->GetMfxInterface()->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum");
1732 
1733         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetCpInterface()->CheckStatusReportNum(
1734             mmioRegisters,
1735             m_cencBuf->bufIdx,
1736             m_cencBuf->resStatus,
1737             &cmdBuffer));
1738     }
1739 
1740     if (m_statusQueryReportingEnabled)
1741     {
1742         CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer));
1743     }
1744 
1745     CODECHAL_DECODE_CHK_STATUS_RETURN(AddPictureCmds(&cmdBuffer, &picMhwParams));
1746 
1747     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1748 
1749     return eStatus;
1750 }
1751 
ParseSlice(PMOS_COMMAND_BUFFER cmdBuf)1752 MOS_STATUS CodechalDecodeAvc::ParseSlice(
1753     PMOS_COMMAND_BUFFER         cmdBuf)
1754 {
1755     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1756     CODECHAL_DECODE_FUNCTION_ENTER;
1757 
1758     PCODEC_AVC_SLICE_PARAMS slc        = m_avcSliceParams;
1759     uint16_t                frameInMbs = (m_avcPicParams->pic_height_in_mbs_minus1 + 1) * (m_avcPicParams->pic_width_in_mbs_minus1 + 1);
1760 
1761     CODECHAL_DECODE_CHK_NULL_RETURN(m_vldSliceRecord);
1762     CODECHAL_DECODE_CHK_NULL_RETURN(slc);
1763 
1764     // Setup static slice state parameters
1765     MHW_VDBOX_AVC_SLICE_STATE avcSliceState;
1766     MOS_ZeroMemory(&avcSliceState, sizeof(avcSliceState));
1767     avcSliceState.bIntelEntrypointInUse = m_intelEntrypointInUse;
1768     avcSliceState.bPicIdRemappingInUse  = m_picIdRemappingInUse;
1769     avcSliceState.bShortFormatInUse     = m_shortFormatInUse;
1770     avcSliceState.presDataBuffer        = &m_resDataBuffer;
1771     avcSliceState.pAvcPicParams         = m_avcPicParams;
1772     avcSliceState.pMvcExtPicParams      = m_mvcExtPicParams;
1773     avcSliceState.pAvcPicIdx            = &(m_avcPicIdx[0]);
1774     avcSliceState.bPhantomSlice = false;
1775     avcSliceState.dwTotalBytesConsumed = 0;
1776 
1777     uint32_t length = 0, slcCount = 0;
1778     uint32_t offset = 0;
1779     uint32_t lastValidSlice = 0;
1780     bool firstValidSlice = true;
1781     bool invalidSlicePresent = false;
1782     for (slcCount = 0; slcCount < m_numSlices; slcCount++)
1783     {
1784 
1785         if (invalidSlicePresent == true)
1786         {
1787             break;
1788         }
1789 
1790         if (m_vldSliceRecord[slcCount].dwSkip)
1791         {
1792             continue;
1793         }
1794 
1795         length = slc->slice_data_size;
1796 
1797         if (slcCount < m_numSlices - 1)
1798         {
1799             // Skip remaining slices if the number of MBs already reaches the total before the last slice or slice overlap occurs.
1800             if ((!m_shortFormatInUse) &&
1801                 ((slc->first_mb_in_slice + slc->NumMbsForSlice >= frameInMbs) ||
1802                     ((slc + 1)->first_mb_in_slice <= slc->first_mb_in_slice)))
1803             {
1804                 uint32_t count = slcCount + 1;
1805 
1806                 slc->first_mb_in_next_slice = 0;
1807                 invalidSlicePresent = true;
1808 
1809                 while (count < m_numSlices)
1810                 {
1811                     m_vldSliceRecord[count++].dwSkip = true;
1812                 }
1813             }
1814             else
1815             {
1816                 slc->first_mb_in_next_slice = (slc + 1)->first_mb_in_slice;
1817             }
1818         }
1819         else
1820         {
1821             slc->first_mb_in_next_slice = 0;
1822         }
1823 
1824         // error handling for garbage data
1825         if (((uint64_t)(slc->slice_data_offset) + length) > m_dataSize)
1826         {
1827             slc++;
1828             m_vldSliceRecord[slcCount].dwSkip = true;
1829             continue;
1830         }
1831 
1832         if (!m_shortFormatInUse)
1833         {
1834             offset = (slc->slice_data_bit_offset >> 3) + m_osInterface->dwNumNalUnitBytesIncluded;
1835 
1836             if (offset > length)
1837             {
1838                 slc++;
1839                 m_vldSliceRecord[slcCount].dwSkip = true;
1840                 continue;
1841             }
1842 
1843             // For first slice, first_mb_in_slice must be 0, otherwise it is corrupted
1844             // Skip slice when  first_mb_in_slice is corrupted.
1845             if ((0 == slcCount && slc->first_mb_in_slice) ||
1846                 (slc->first_mb_in_slice >= frameInMbs) ||
1847                 (m_avcPicParams->seq_fields.mb_adaptive_frame_field_flag &&
1848                     !m_avcPicParams->pic_fields.field_pic_flag &&
1849                     (slc->first_mb_in_slice >= frameInMbs / 2)))
1850             {
1851                 slc++;
1852                 m_vldSliceRecord[slcCount].dwSkip = true;
1853                 continue;
1854             }
1855 
1856             if (firstValidSlice && slc->first_mb_in_slice)
1857             {
1858 
1859                 uint16_t usStartMbNum, usNextStartMbNum;
1860 
1861                 // ensure that slc->first_mb_in_next_slice is always non-zero for this phantom slice
1862 
1863                 usNextStartMbNum = slc->first_mb_in_next_slice;
1864                 usStartMbNum = slc->first_mb_in_slice;
1865                 slc->first_mb_in_slice = 0;
1866                 slc->first_mb_in_next_slice = usStartMbNum;
1867 
1868                 avcSliceState.pAvcSliceParams = slc;
1869                 avcSliceState.dwOffset = 0;
1870                 avcSliceState.dwLength = slc->slice_data_offset;
1871                 avcSliceState.dwNextOffset = slc->slice_data_offset;
1872                 avcSliceState.dwNextLength = slc->slice_data_size;
1873 
1874                 CODECHAL_DECODE_CHK_STATUS_RETURN(SendSlice(&avcSliceState, cmdBuf));
1875 
1876                 slc->first_mb_in_slice = usStartMbNum;
1877                 slc->first_mb_in_next_slice = usNextStartMbNum;
1878             }
1879         }
1880 
1881         firstValidSlice = false;
1882         lastValidSlice = slcCount;
1883         length -= offset;
1884         m_vldSliceRecord[slcCount].dwLength = length;
1885         m_vldSliceRecord[slcCount].dwOffset = offset;
1886         slc++;
1887     }
1888     slc = m_avcSliceParams;
1889 
1890     uint32_t skippedSlc = 0;
1891     for (slcCount = 0; slcCount < m_numSlices; slcCount++)
1892     {
1893         if (m_vldSliceRecord[slcCount].dwSkip)
1894         {
1895             //For DECE clear bytes calculation: Total bytes in the bit-stream consumed so far
1896             avcSliceState.dwTotalBytesConsumed = slc->slice_data_offset + slc->slice_data_size;
1897 
1898             slc++;
1899             skippedSlc++;
1900             continue;
1901         }
1902 
1903         if (slcCount < lastValidSlice)
1904         {
1905             offset = (slc + 1)->slice_data_offset;
1906             length = (slc + 1)->slice_data_size;
1907         }
1908         avcSliceState.pAvcSliceParams = slc;
1909         avcSliceState.dwOffset        = m_vldSliceRecord[slcCount].dwOffset;
1910         avcSliceState.dwLength        = m_vldSliceRecord[slcCount].dwLength;
1911         avcSliceState.dwNextOffset = offset;
1912         avcSliceState.dwNextLength = length;
1913         avcSliceState.dwSliceIndex = slcCount;
1914         avcSliceState.bLastSlice = (slcCount == lastValidSlice);
1915         avcSliceState.bFullFrameData = m_fullFrameData;
1916 
1917         CODECHAL_DECODE_CHK_STATUS_RETURN(SendSlice(&avcSliceState, cmdBuf));
1918 
1919         //For DECE clear bytes calculation: Total bytes in the bit-stream consumed so far
1920         avcSliceState.dwTotalBytesConsumed = slc->slice_data_offset + slc->slice_data_size;
1921 
1922         slc++;
1923     }
1924 
1925     MOS_ZeroMemory(m_vldSliceRecord, (m_numSlices * sizeof(CODECHAL_VLD_SLICE_RECORD)));
1926 
1927     return eStatus;
1928 }
1929 
DecodePrimitiveLevel()1930 MOS_STATUS CodechalDecodeAvc::DecodePrimitiveLevel()
1931 {
1932     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1933     CODECHAL_DECODE_FUNCTION_ENTER;
1934 
1935     CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
1936     CODECHAL_DECODE_CHK_NULL_RETURN(m_avcPicParams);
1937 
1938     MOS_COMMAND_BUFFER cmdBuffer;
1939     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1940 
1941     if (m_cencBuf)
1942     {
1943         CODECHAL_DECODE_CHK_STATUS_RETURN(SetCencBatchBuffer(&cmdBuffer));
1944     }
1945     else
1946     {
1947         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseSlice(&cmdBuffer));
1948     }
1949 
1950     // Check if destination surface needs to be synchronized
1951     MOS_SYNC_PARAMS syncParams;
1952     syncParams = g_cInitSyncParams;
1953     syncParams.GpuContext = m_videoContext;
1954     syncParams.presSyncResource         = &m_destSurface.OsResource;
1955     syncParams.bReadOnly = false;
1956     syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
1957     syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1958 
1959     if (!CodecHal_PictureIsField(m_avcPicParams->CurrPic) ||
1960         !m_isSecondField)
1961     {
1962         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
1963         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1964 
1965         // Update the resource tag (s/w tag) for On-Demand Sync
1966         m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1967     }
1968 
1969     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1970     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1971 
1972     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1973         &cmdBuffer,
1974         &flushDwParams));
1975 
1976     // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
1977     if (m_osInterface->bTagResourceSync &&
1978         (!CodecHal_PictureIsField(m_avcPicParams->CurrPic) || m_isSecondField))
1979     {
1980         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
1981     }
1982 
1983     if (m_statusQueryReportingEnabled)
1984     {
1985         CodechalDecodeStatusReport decodeStatusReport;
1986 
1987         decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
1988         decodeStatusReport.m_currDecodedPic     = m_avcPicParams->CurrPic;
1989         decodeStatusReport.m_currDeblockedPic   = m_avcPicParams->CurrPic;
1990         decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
1991         decodeStatusReport.m_currDecodedPicRes  = m_avcRefList[m_avcPicParams->CurrPic.FrameIdx]->resRefPic;
1992 
1993         CODECHAL_DEBUG_TOOL(
1994             if (m_streamOutEnabled) {
1995                 // add current streamout buffer to the report and move onto the next one
1996                 decodeStatusReport.m_streamOutBuf = &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
1997                 decodeStatusReport.m_streamoutIdx = m_streamOutCurrBufIdx;
1998                 if (++m_streamOutCurrBufIdx >= CODECHAL_DECODE_NUM_STREAM_OUT_BUFFERS)
1999                 {
2000                     m_streamOutCurrBufIdx = 0;
2001                 }
2002                 // check next buffer in the list is free.
2003                 if (m_streamOutCurrStatusIdx[m_streamOutCurrBufIdx] != CODECHAL_DECODE_STATUS_NUM)
2004                 {
2005                     // We've run out of buffers. Temporarily lock the next one down to force a wait. Then mark it as free.
2006                     CodechalResLock ResourceLock(m_osInterface, &(m_streamOutBuffer[m_streamOutCurrBufIdx]));
2007                     ResourceLock.Lock(CodechalResLock::readOnly);
2008 
2009                     m_streamOutCurrStatusIdx[m_streamOutCurrBufIdx] = CODECHAL_DECODE_STATUS_NUM;
2010                 }
2011             }
2012 
2013             decodeStatusReport.m_secondField = m_secondField;
2014             decodeStatusReport.m_frameType   = m_perfType;)
2015 
2016         CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
2017     }
2018 
2019     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
2020 
2021     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
2022 
2023     bool syncCompleteFrame = (m_avcPicParams->seq_fields.chroma_format_idc == avcChromaFormatMono && !m_hwInterface->m_noHuC);
2024     if (syncCompleteFrame)
2025     {
2026         syncParams = g_cInitSyncParams;
2027         syncParams.GpuContext = m_videoContextForWa;
2028         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
2029 
2030         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
2031 
2032         syncParams = g_cInitSyncParams;
2033         syncParams.GpuContext = m_videoContext;
2034         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
2035 
2036         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
2037     }
2038 
2039     CODECHAL_DEBUG_TOOL(
2040         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
2041             &cmdBuffer,
2042             CODECHAL_NUM_MEDIA_STATES,
2043             "_DEC"));
2044 
2045     //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
2046     //    m_debugInterface,
2047     //    &cmdBuffer));
2048     )
2049 
2050     HalOcaInterface::DumpCodechalParam(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, m_pCodechalOcaDumper, CODECHAL_AVC);
2051     HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
2052 
2053     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
2054 
2055     CODECHAL_DEBUG_TOOL(
2056         m_mmc->UpdateUserFeatureKey(&m_destSurface);)
2057 
2058 #ifdef _DECODE_PROCESSING_SUPPORTED
2059     auto decProcessingParams = (DecodeProcessingParams *)m_decodeParams.m_procParams;
2060     if (decProcessingParams != nullptr && !m_sfcState->m_sfcPipeOut && (m_isSecondField || m_avcPicParams->seq_fields.mb_adaptive_frame_field_flag))
2061     {
2062         CODECHAL_DECODE_CHK_STATUS_RETURN(m_fieldScalingInterface->DoFieldScaling(
2063             decProcessingParams,
2064             m_renderContext,
2065             m_disableDecodeSyncLock,
2066             m_disableLockForTranscode));
2067     }
2068     else
2069 #endif
2070     {
2071         if (m_statusQueryReportingEnabled)
2072         {
2073             CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
2074         }
2075     }
2076 
2077     // Needs to be re-set for Linux buffer re-use scenarios
2078     m_avcRefList[m_avcPicParams->CurrPic.FrameIdx]->resRefPic =
2079         m_destSurface.OsResource;
2080 
2081     // Send the signal to indicate decode completion, in case On-Demand Sync is not present
2082     if (!CodecHal_PictureIsField(m_avcPicParams->CurrPic) || m_isSecondField)
2083     {
2084         syncParams = g_cInitSyncParams;
2085         syncParams.GpuContext = m_videoContext;
2086         syncParams.presSyncResource = &m_destSurface.OsResource;
2087 
2088         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
2089 #ifdef _DECODE_PROCESSING_SUPPORTED
2090         if (decProcessingParams && !m_sfcState->m_sfcPipeOut)
2091         {
2092             syncParams = g_cInitSyncParams;
2093             syncParams.GpuContext = m_renderContext;
2094             syncParams.presSyncResource = &decProcessingParams->m_outputSurface->OsResource;
2095 
2096             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
2097         }
2098 #endif
2099     }
2100 #ifdef _DECODE_PROCESSING_SUPPORTED
2101     CODECHAL_DEBUG_TOOL(
2102         // Dump out downsampling result
2103         if (decProcessingParams && decProcessingParams->m_outputSurface)
2104         {
2105             MOS_SURFACE dstSurface;
2106             MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
2107             dstSurface.Format = Format_NV12;
2108             dstSurface.OsResource = decProcessingParams->m_outputSurface->OsResource;
2109 
2110             CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
2111                 m_osInterface,
2112                 &dstSurface));
2113 
2114             CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
2115                 &dstSurface,
2116                 CodechalDbgAttr::attrSfcOutputSurface,
2117                 "SfcDstSurf"));
2118         }
2119     )
2120 #endif
2121     return eStatus;
2122 }
2123 
CalcDownsamplingParams(void * picParams,uint32_t * refSurfWidth,uint32_t * refSurfHeight,MOS_FORMAT * format,uint8_t * frameIdx)2124 MOS_STATUS CodechalDecodeAvc::CalcDownsamplingParams(
2125     void                        *picParams,
2126     uint32_t                    *refSurfWidth,
2127     uint32_t                    *refSurfHeight,
2128     MOS_FORMAT                  *format,
2129     uint8_t                     *frameIdx)
2130 {
2131     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2132 
2133     CODECHAL_DECODE_CHK_NULL_RETURN(picParams);
2134     CODECHAL_DECODE_CHK_NULL_RETURN(refSurfWidth);
2135     CODECHAL_DECODE_CHK_NULL_RETURN(refSurfHeight);
2136     CODECHAL_DECODE_CHK_NULL_RETURN(format);
2137     CODECHAL_DECODE_CHK_NULL_RETURN(frameIdx);
2138 
2139     PCODEC_AVC_PIC_PARAMS avcPicParams = (PCODEC_AVC_PIC_PARAMS)picParams;
2140 
2141     *refSurfWidth = 0;
2142     *refSurfHeight = 0;
2143     *format = Format_NV12;
2144     *frameIdx = avcPicParams->CurrPic.FrameIdx;
2145 
2146     *refSurfWidth = (avcPicParams->pic_width_in_mbs_minus1 + 1) * CODECHAL_MACROBLOCK_WIDTH;
2147     *refSurfHeight = (avcPicParams->pic_height_in_mbs_minus1 + 1) * CODECHAL_MACROBLOCK_HEIGHT;
2148 
2149 
2150     return eStatus;
2151 }
2152 
CodechalDecodeAvc(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)2153 CodechalDecodeAvc::CodechalDecodeAvc(
2154     CodechalHwInterface *hwInterface,
2155     CodechalDebugInterface* debugInterface,
2156     PCODECHAL_STANDARD_INFO standardInfo) :
2157     CodechalDecode(hwInterface, debugInterface, standardInfo)
2158 {
2159     m_mmc = nullptr;
2160     m_hwInterface = hwInterface;
2161     // Parameters passed by application
2162     m_picWidthInMb                = 0;
2163     m_picHeightInMb               = 0;
2164     m_picWidthInMbLastMaxAlloced  = 0;
2165     m_picHeightInMbLastMaxAlloced = 0;
2166     m_intelEntrypointInUse        = false;
2167     m_shortFormatInUse            = false;
2168     m_picIdRemappingInUse         = false;
2169     m_dataSize                    = 0;
2170     m_dataOffset                  = 0;
2171     m_numSlices                   = 0;
2172     m_refSurfaceNum               = 0;
2173     m_avcPicParams                = nullptr;
2174     m_mvcExtPicParams             = nullptr;
2175     m_avcSliceParams              = nullptr;
2176     m_avcIqMatrixParams           = nullptr;
2177 
2178     MOS_ZeroMemory(m_presReferences, (sizeof(PMOS_RESOURCE) * CODEC_AVC_MAX_NUM_REF_FRAME));
2179     MOS_ZeroMemory(&m_resDataBuffer, sizeof(MOS_RESOURCE));
2180     MOS_ZeroMemory(&m_resMonoPictureChromaBuffer, sizeof(MOS_RESOURCE));
2181     MOS_ZeroMemory(&m_resMfdIntraRowStoreScratchBuffer, sizeof(MOS_RESOURCE));
2182     MOS_ZeroMemory(&m_resMfdDeblockingFilterRowStoreScratchBuffer, sizeof(MOS_RESOURCE));
2183     MOS_ZeroMemory(&m_resBsdMpcRowStoreScratchBuffer, sizeof(MOS_RESOURCE));
2184     MOS_ZeroMemory(&m_resMprRowStoreScratchBuffer, sizeof(MOS_RESOURCE));
2185     MOS_ZeroMemory(&m_resAvcDmvBuffers, (sizeof(MOS_RESOURCE) * CODEC_AVC_NUM_UNCOMPRESSED_SURFACE));
2186     MOS_ZeroMemory(&m_resInvalidRefBuffer, sizeof(MOS_RESOURCE));
2187     MOS_ZeroMemory(&m_resMvcDummyDmvBuffer, (sizeof(MOS_RESOURCE) * 2));
2188     MOS_ZeroMemory(&m_destSurface, sizeof(MOS_SURFACE));
2189     MOS_ZeroMemory(&m_resSyncObjectWaContextInUse, sizeof(MOS_RESOURCE));
2190     MOS_ZeroMemory(&m_resSyncObjectVideoContextInUse, sizeof(MOS_RESOURCE));
2191     m_refFrameSurface = nullptr;
2192 
2193     m_vldSliceRecord = nullptr;
2194 
2195     m_bsdMpcRowStoreScratchBufferPicWidthInMb   = 0;
2196     m_mfdIntraRowStoreScratchBufferPicWidthInMb = 0;
2197     m_mprRowStoreScratchBufferPicWidthInMb      = 0;
2198 
2199     MOS_ZeroMemory(m_firstFieldIdxList, (sizeof(uint8_t) * CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS));
2200 
2201     m_isSecondField = false;
2202     m_deblockingEnabled = false;
2203 
2204     // Decode process usage
2205     MOS_ZeroMemory(&m_currPic, sizeof(CODEC_PICTURE));
2206 
2207     MOS_ZeroMemory(&m_avcFrameStoreId, (sizeof(CODEC_AVC_FRAME_STORE_ID) * CODEC_AVC_MAX_NUM_REF_FRAME));
2208 
2209     m_avcMvBufferIndex = 0;
2210     MOS_ZeroMemory(&m_avcDmvList, (sizeof(CODEC_AVC_DMV_LIST) * CODEC_AVC_NUM_DMV_BUFFERS));
2211 
2212     MOS_ZeroMemory(&m_avcPicIdx, (sizeof(CODEC_PIC_ID) * CODEC_AVC_MAX_NUM_REF_FRAME));
2213     MOS_ZeroMemory(m_avcRefList, (sizeof(PCODEC_REF_LIST) * CODEC_AVC_NUM_UNCOMPRESSED_SURFACE));
2214 
2215     m_avcDmvBufferSize = 0;
2216 
2217     //Currently, crc calculation is only supported in AVC decoder
2218     m_reportFrameCrc = true;
2219 
2220     m_fullFrameData = false;
2221 
2222 };
2223 
2224 #if USE_CODECHAL_DEBUG_TOOL
DumpMvcExtPicParams(PCODEC_MVC_EXT_PIC_PARAMS mvcExtPicParams)2225 MOS_STATUS CodechalDecodeAvc::DumpMvcExtPicParams(
2226     PCODEC_MVC_EXT_PIC_PARAMS mvcExtPicParams)
2227 {
2228     CODECHAL_DEBUG_FUNCTION_ENTER;
2229 
2230     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrMvcExtPicParams))
2231     {
2232         return MOS_STATUS_SUCCESS;
2233     }
2234     CODECHAL_DEBUG_CHK_NULL(mvcExtPicParams);
2235 
2236     std::ostringstream oss;
2237     oss.setf(std::ios::showbase | std::ios::uppercase);
2238 
2239     oss << "CurrViewID: " << std::hex << +mvcExtPicParams->CurrViewID << std::endl;
2240     oss << "anchor_pic_flag: " << +mvcExtPicParams->anchor_pic_flag << std::endl;
2241     oss << "inter_view_flag: " << +mvcExtPicParams->inter_view_flag << std::endl;
2242     oss << "NumInterViewRefsL0: " << +mvcExtPicParams->NumInterViewRefsL0 << std::endl;
2243     oss << "NumInterViewRefsL1: " << +mvcExtPicParams->NumInterViewRefsL1 << std::endl;
2244     oss << "bPicFlags: " << +mvcExtPicParams->bPicFlags << std::endl;
2245     oss << "SwitchToAVC: " << +mvcExtPicParams->SwitchToAVC << std::endl;
2246     oss << "Reserved7Bits: " << +mvcExtPicParams->Reserved7Bits << std::endl;
2247     oss << "Reserved8Bits: " << +mvcExtPicParams->Reserved8Bits << std::endl;
2248 
2249     //Dump ViewIDList[16]
2250     for (uint8_t i = 0; i < 16; ++i)
2251     {
2252         oss << "ViewIDList[" << +i << "]: "
2253             << +mvcExtPicParams->ViewIDList[i] << std::endl;
2254     }
2255 
2256     //Dump InterViewRefList[2][16]
2257     for (uint8_t i = 0; i < 16; ++i)
2258     {
2259         oss << "InterViewRefList[0][" << +i << "]: "
2260             << +mvcExtPicParams->InterViewRefList[0][i] << std::endl;
2261         oss << "InterViewRefList[1][" << +i << "]: "
2262             << +mvcExtPicParams->InterViewRefList[1][i] << std::endl;
2263     }
2264 
2265     const char *fileName = m_debugInterface->CreateFileName(
2266         "_DEC",
2267         CodechalDbgBufferType::bufMvcPicParams,
2268         CodechalDbgExtType::txt);
2269 
2270     std::ofstream ofs(fileName, std::ios::out);
2271     ofs << oss.str();
2272     ofs.close();
2273 
2274     return MOS_STATUS_SUCCESS;
2275 }
2276 
DumpPicParams(PCODEC_AVC_PIC_PARAMS picParams)2277 MOS_STATUS CodechalDecodeAvc::DumpPicParams(
2278     PCODEC_AVC_PIC_PARAMS picParams)
2279 {
2280     CODECHAL_DEBUG_FUNCTION_ENTER;
2281 
2282     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
2283     {
2284         return MOS_STATUS_SUCCESS;
2285     }
2286 
2287     CODECHAL_DEBUG_CHK_NULL(picParams);
2288 
2289     std::ostringstream oss;
2290     oss.setf(std::ios::showbase | std::ios::uppercase);
2291 
2292     oss << "CurrPic FrameIdx: " << std::dec << +picParams->CurrPic.FrameIdx << std::endl;
2293     oss << "CurrPic PicFlags: " << std::hex << +picParams->CurrPic.PicFlags << std::endl;
2294 
2295     //Dump RefFrameList[15]
2296     for (uint8_t i = 0; i < 15; ++i)
2297     {
2298         oss << "RefFrameList[" << std::dec << +i << "] FrameIdx:" << +picParams->RefFrameList[i].FrameIdx << std::endl;
2299         oss << "RefFrameList[" << +i << "] PicFlags:" << std::hex << +picParams->RefFrameList[i].PicFlags << std::endl;
2300     }
2301 
2302     oss << "pic_width_in_mbs_minus1: " << std::dec << +picParams->pic_width_in_mbs_minus1 << std::endl;
2303     oss << "pic_height_in_mbs_minus1: " << +picParams->pic_height_in_mbs_minus1 << std::endl;
2304     oss << "bit_depth_luma_minus8: " << +picParams->bit_depth_luma_minus8 << std::endl;
2305     oss << "bit_depth_chroma_minus8: " << +picParams->bit_depth_chroma_minus8 << std::endl;
2306     oss << "num_ref_frames: " << +picParams->num_ref_frames << std::endl;
2307     oss << "CurrFieldOrderCnt: " << +picParams->CurrFieldOrderCnt[0] << std::endl;
2308     oss << "CurrFieldOrderCnt: " << +picParams->CurrFieldOrderCnt[1] << std::endl;
2309 
2310     //Dump FieldOrderCntList (16x2)
2311     for (uint8_t i = 0; i < 2; ++i)
2312     {
2313         oss << "FieldOrderCntList[" << +i << "]:";
2314         for (uint8_t j = 0; j < 16; j++)
2315             oss << +picParams->FieldOrderCntList[j][i] << " ";
2316         oss << std::endl;
2317     }
2318 
2319     //Dump seq_fields
2320     oss << "seq_fields value: " << +picParams->seq_fields.value << std::endl;
2321     oss << "chroma_format_idc: " << +picParams->seq_fields.chroma_format_idc << std::endl;
2322     oss << "residual_colour_transform_flag: " << std::hex << +picParams->seq_fields.residual_colour_transform_flag << std::endl;
2323     oss << "frame_mbs_only_flag: " << std::hex << +picParams->seq_fields.frame_mbs_only_flag << std::endl;
2324     oss << "mb_adaptive_frame_field_flag: " << std::hex << +picParams->seq_fields.mb_adaptive_frame_field_flag << std::endl;
2325     oss << "direct_8x8_inference_flag: " << std::hex << +picParams->seq_fields.direct_8x8_inference_flag << std::endl;
2326     oss << "log2_max_frame_num_minus4: " << std::dec << +picParams->seq_fields.log2_max_frame_num_minus4 << std::endl;
2327     oss << "pic_order_cnt_type: " << +picParams->seq_fields.pic_order_cnt_type << std::endl;
2328     oss << "log2_max_pic_order_cnt_lsb_minus4: " << +picParams->seq_fields.log2_max_pic_order_cnt_lsb_minus4 << std::endl;
2329     oss << "delta_pic_order_always_zero_flag: " << std::hex << +picParams->seq_fields.delta_pic_order_always_zero_flag << std::endl;
2330     oss << "num_slice_groups_minus1:" << std::dec << +picParams->num_slice_groups_minus1 << std::endl;
2331     oss << "slice_group_map_type:" << std::dec << +picParams->slice_group_map_type << std::endl;
2332     oss << "slice_group_change_rate_minus1:" << std::dec << +picParams->slice_group_change_rate_minus1 << std::endl;
2333     oss << "pic_init_qp_minus26:" << std::dec << +picParams->pic_init_qp_minus26 << std::endl;
2334     oss << "chroma_qp_index_offset:" << std::dec << +picParams->chroma_qp_index_offset << std::endl;
2335     oss << "second_chroma_qp_index_offset:" << std::dec << +picParams->second_chroma_qp_index_offset << std::endl;
2336 
2337     //Dump pic_fields
2338     oss << "pic_fields value: " << std::dec << +picParams->pic_fields.value << std::endl;
2339     oss << "entropy_coding_mode_flag: " << std::hex << +picParams->pic_fields.entropy_coding_mode_flag << std::endl;
2340     oss << "weighted_pred_flag: " << std::hex << +picParams->pic_fields.weighted_pred_flag << std::endl;
2341     oss << "weighted_bipred_idc: " << std::dec << +picParams->pic_fields.weighted_bipred_idc << std::endl;
2342     oss << "transform_8x8_mode_flag: " << std::hex << +picParams->pic_fields.transform_8x8_mode_flag << std::endl;
2343     oss << "field_pic_flag: " << std::hex << +picParams->pic_fields.field_pic_flag << std::endl;
2344     oss << "constrained_intra_pred_flag: " << std::hex << +picParams->pic_fields.constrained_intra_pred_flag << std::endl;
2345     oss << "pic_order_present_flag: " << std::hex << +picParams->pic_fields.pic_order_present_flag << std::endl;
2346     oss << "deblocking_filter_control_present_flag: " << std::hex << +picParams->pic_fields.deblocking_filter_control_present_flag << std::endl;
2347     oss << "redundant_pic_cnt_present_flag: " << std::hex << +picParams->pic_fields.redundant_pic_cnt_present_flag << std::endl;
2348     oss << "reference_pic_flag: " << std::hex << +picParams->pic_fields.reference_pic_flag << std::endl;
2349     oss << "IntraPicFlag: " << std::hex << +picParams->pic_fields.IntraPicFlag << std::endl;
2350 
2351     //Dump Short format specific
2352     oss << "num_ref_idx_l0_active_minus1: " << std::dec << +picParams->num_ref_idx_l0_active_minus1 << std::endl;
2353     oss << "num_ref_idx_l1_active_minus1: " << std::dec << +picParams->num_ref_idx_l1_active_minus1 << std::endl;
2354     oss << "NonExistingFrameFlags: " << std::hex << +picParams->NonExistingFrameFlags << std::endl;
2355     oss << "UsedForReferenceFlags: " << std::hex << +picParams->UsedForReferenceFlags << std::endl;
2356     oss << "frame_num: " << std::dec << +picParams->frame_num << std::endl;
2357     oss << "StatusReportFeedbackNumber: " << std::dec << +picParams->StatusReportFeedbackNumber << std::endl;
2358 
2359     //Dump FrameNumList[16]
2360     oss << "scaling_list_present_flag_buffer:";
2361     for (uint8_t i = 0; i < 16; i++)
2362         oss << std::hex << picParams->FrameNumList[i];
2363     oss << std::endl;
2364 
2365     const char *fileName = m_debugInterface->CreateFileName(
2366         "_DEC",
2367         CodechalDbgBufferType::bufPicParams,
2368         CodechalDbgExtType::txt);
2369 
2370     std::ofstream ofs(fileName, std::ios::out);
2371     ofs << oss.str();
2372     ofs.close();
2373     return MOS_STATUS_SUCCESS;
2374 }
2375 
DumpSliceParams(PCODEC_AVC_SLICE_PARAMS sliceParams,uint32_t numSlices)2376 MOS_STATUS CodechalDecodeAvc::DumpSliceParams(
2377     PCODEC_AVC_SLICE_PARAMS sliceParams,
2378     uint32_t                numSlices)
2379 {
2380     CODECHAL_DEBUG_FUNCTION_ENTER;
2381 
2382     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
2383     {
2384         return MOS_STATUS_SUCCESS;
2385     }
2386 
2387     CODECHAL_DEBUG_CHK_NULL(sliceParams);
2388 
2389     PCODEC_AVC_SLICE_PARAMS sliceControl = nullptr;
2390 
2391     std::ostringstream oss;
2392     oss.setf(std::ios::showbase | std::ios::uppercase);
2393 
2394     for (uint16_t j = 0; j < numSlices; j++)
2395     {
2396         sliceControl = &sliceParams[j];
2397 
2398         oss << "Data for Slice number = " << std::dec << +j << std::endl;
2399         oss << "slice_data_size: " << std::dec << +sliceControl->slice_data_size << std::endl;
2400         oss << "slice_data_offset: " << std::dec << +sliceControl->slice_data_offset << std::endl;
2401         //Dump Long format specific
2402         oss << "slice_data_bit_offset: " << std::dec << +sliceControl->slice_data_bit_offset << std::endl;
2403         oss << "first_mb_in_slice: " << std::dec << +sliceControl->first_mb_in_slice << std::endl;
2404         oss << "NumMbsForSlice: " << std::dec << +sliceControl->NumMbsForSlice << std::endl;
2405         oss << "slice_type: " << std::dec << +sliceControl->slice_type << std::endl;
2406         oss << "direct_spatial_mv_pred_flag: " << std::hex << +sliceControl->direct_spatial_mv_pred_flag << std::endl;
2407         oss << "num_ref_idx_l0_active_minus1: " << std::dec << +sliceControl->num_ref_idx_l0_active_minus1 << std::endl;
2408         oss << "num_ref_idx_l1_active_minus1: " << std::dec << +sliceControl->num_ref_idx_l1_active_minus1 << std::endl;
2409         oss << "cabac_init_idc: " << std::dec << +sliceControl->cabac_init_idc << std::endl;
2410         oss << "slice_qp_delta: " << std::dec << +sliceControl->slice_qp_delta << std::endl;
2411         oss << "disable_deblocking_filter_idc: " << std::dec << +sliceControl->disable_deblocking_filter_idc << std::endl;
2412         oss << "slice_alpha_c0_offset_div2: " << std::dec << +sliceControl->slice_alpha_c0_offset_div2 << std::endl;
2413         oss << "slice_beta_offset_div2: " << std::dec << +sliceControl->slice_beta_offset_div2 << std::endl;
2414 
2415         //Dump RefPicList[2][32]
2416         for (uint8_t i = 0; i < 32; ++i)
2417         {
2418             oss << "RefPicList[0][" << std::dec << +i << "] FrameIdx: " << std::dec << +sliceControl->RefPicList[0][i].FrameIdx << std::endl;
2419             oss << "RefPicList[0][" << std::dec << +i << "] PicFlags: " << std::hex << +sliceControl->RefPicList[0][i].PicFlags << std::endl;
2420             oss << "RefPicList[1][" << std::dec << +i << "] FrameIdx: " << std::dec << +sliceControl->RefPicList[1][i].FrameIdx << std::endl;
2421             oss << "RefPicList[1][" << std::dec << +i << "] PicFlags: " << std::hex << +sliceControl->RefPicList[1][i].PicFlags << std::endl;
2422         }
2423 
2424         oss << "luma_log2_weight_denom: " << std::dec << +sliceControl->luma_log2_weight_denom << std::endl;
2425         oss << "chroma_log2_weight_denom: " << std::dec << +sliceControl->chroma_log2_weight_denom << std::endl;
2426         oss << "slice_id: " << std::dec << +sliceControl->slice_id << std::endl;
2427 
2428         //Dump Weights[2][32][3][2]
2429         for (uint8_t i = 0; i < 32; ++i)
2430         {
2431             oss << "Weights[0][" << std::dec << +i << "][0][0]: " << std::hex << +sliceControl->Weights[0][i][0][0] << std::endl;
2432             oss << "Weights[0][" << std::dec << +i << "][0][1]: " << std::hex << +sliceControl->Weights[0][i][0][1] << std::endl;
2433             oss << "Weights[0][" << std::dec << +i << "][1][0]: " << std::hex << +sliceControl->Weights[0][i][1][0] << std::endl;
2434             oss << "Weights[0][" << std::dec << +i << "][1][1]: " << std::hex << +sliceControl->Weights[0][i][1][1] << std::endl;
2435             oss << "Weights[1][" << std::dec << +i << "][0][0]: " << std::hex << +sliceControl->Weights[1][i][0][0] << std::endl;
2436             oss << "Weights[1][" << std::dec << +i << "][0][1]: " << std::hex << +sliceControl->Weights[1][i][0][1] << std::endl;
2437             oss << "Weights[1][" << std::dec << +i << "][1][0]: " << std::hex << +sliceControl->Weights[1][i][1][0] << std::endl;
2438             oss << "Weights[1][" << std::dec << +i << "][1][1]: " << std::hex << +sliceControl->Weights[1][i][1][1] << std::endl;
2439             oss << "Weights[0][" << std::dec << +i << "][2][0]: " << std::hex << +sliceControl->Weights[0][i][2][0] << std::endl;
2440             oss << "Weights[0][" << std::dec << +i << "][2][1]: " << std::hex << +sliceControl->Weights[0][i][2][1] << std::endl;
2441             oss << "Weights[1][" << std::dec << +i << "][2][0]: " << std::hex << +sliceControl->Weights[1][i][2][0] << std::endl;
2442             oss << "Weights[1][" << std::dec << +i << "][2][1]: " << std::hex << +sliceControl->Weights[1][i][2][1] << std::endl;
2443         }
2444 
2445         const char *fileName = m_debugInterface->CreateFileName(
2446             "_DEC",
2447             CodechalDbgBufferType::bufSlcParams,
2448             CodechalDbgExtType::txt);
2449 
2450         std::ofstream ofs;
2451         if (j == 0)
2452         {
2453             ofs.open(fileName, std::ios::out);
2454         }
2455         else
2456         {
2457             ofs.open(fileName, std::ios::app);
2458         }
2459         ofs << oss.str();
2460         ofs.close();
2461     }
2462 
2463     return MOS_STATUS_SUCCESS;
2464 }
2465 
DumpIQParams(PCODEC_AVC_IQ_MATRIX_PARAMS matrixData)2466 MOS_STATUS CodechalDecodeAvc::DumpIQParams(
2467     PCODEC_AVC_IQ_MATRIX_PARAMS matrixData)
2468 {
2469     CODECHAL_DEBUG_FUNCTION_ENTER;
2470 
2471     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams))
2472     {
2473         return MOS_STATUS_SUCCESS;
2474     }
2475 
2476     CODECHAL_DEBUG_CHK_NULL(matrixData);
2477 
2478     std::ostringstream oss;
2479     oss.setf(std::ios::showbase | std::ios::uppercase);
2480 
2481     uint32_t idx, idx2;
2482     // 4x4 block
2483     for (idx2 = 0; idx2 < 6; idx2++)
2484     {
2485         oss << "Qmatrix_H264_ScalingLists4x4[" << std::dec << +idx2 << "]:" << std::endl;
2486         for (idx = 0; idx < 12; idx += 4)
2487         {
2488             oss << "ScalingList4x4[" << std::dec << +idx / 4 << "]:";
2489             oss << std::hex << +matrixData->ScalingList4x4[idx2][idx] << " ";
2490             oss << std::hex << +matrixData->ScalingList4x4[idx2][idx + 1] << " ";
2491             oss << std::hex << +matrixData->ScalingList4x4[idx2][idx + 2] << " ";
2492             oss << std::hex << +matrixData->ScalingList4x4[idx2][idx + 3] << " ";
2493             oss << std::endl;
2494         }
2495         oss << std::endl;
2496     }
2497     // 8x8 block
2498     for (idx2 = 0; idx2 < 2; idx2++)
2499     {
2500         oss << "Qmatrix_H264_ScalingLists8x8[" << std::dec << +idx2 << "]:" << std::endl;
2501         for (idx = 0; idx < 56; idx += 8)
2502         {
2503             oss << "ScalingList8x8[" << std::dec << +idx / 8 << "]:";
2504             oss << std::hex << +matrixData->ScalingList8x8[idx2][idx] << " " ;
2505             oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 1] << " " ;
2506             oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 2] << " " ;
2507             oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 3] << " " ;
2508             oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 4] << " " ;
2509             oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 5] << " " ;
2510             oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 6] << " " ;
2511             oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 7] << " " ;
2512             oss << std::endl;
2513         }
2514         oss << std::endl;
2515     }
2516 
2517     const char *fileName = m_debugInterface->CreateFileName(
2518         "_DEC",
2519         CodechalDbgBufferType::bufIqParams,
2520         CodechalDbgExtType::txt);
2521 
2522     std::ofstream ofs(fileName, std::ios::out);
2523     ofs << oss.str();
2524     ofs.close();
2525 
2526     return MOS_STATUS_SUCCESS;
2527 }
2528 #endif
2529 
SetFrameStoreIds(uint8_t frameIdx)2530 MOS_STATUS CodechalDecodeAvc::SetFrameStoreIds(uint8_t frameIdx)
2531 {
2532     CODECHAL_DECODE_CHK_NULL_RETURN(m_avcFrameStoreId);
2533 
2534     uint8_t invalidFrame = 0x7f;
2535 
2536     for (uint8_t i = 0; i < m_avcRefList[frameIdx]->ucNumRef; i++)
2537     {
2538         uint8_t index;
2539         index = m_avcRefList[frameIdx]->RefList[i].FrameIdx;
2540         if (m_avcRefList[index]->ucFrameId == invalidFrame)
2541         {
2542             uint8_t j;
2543             for (j = 0; j < CODEC_AVC_MAX_NUM_REF_FRAME; j++)
2544             {
2545                 if (!m_avcFrameStoreId[j].inUse)
2546                 {
2547                     m_avcRefList[index]->ucFrameId = j;
2548                     m_avcFrameStoreId[j].inUse     = true;
2549                     break;
2550                 }
2551             }
2552             if (j == CODEC_AVC_MAX_NUM_REF_FRAME)
2553             {
2554                 // should never happen, something must be wrong
2555                 CODECHAL_PUBLIC_ASSERT(false);
2556                 m_avcRefList[index]->ucFrameId = 0;
2557                 m_avcFrameStoreId[0].inUse     = true;
2558             }
2559         }
2560     }
2561     return MOS_STATUS_SUCCESS;
2562 }
2563