1 /*
2 * Copyright (c) 2017-2020, 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_mpeg2_g12.cpp
24 //! \brief    Implements the decode interface extension for MPEG2.
25 //! \details  Implements all functions and constants required by CodecHal for MPEG2 decoding.
26 //!
27 
28 #include "codechal_decoder.h"
29 #include "codechal_decode_mpeg2_g12.h"
30 #include "codechal_secure_decode_interface.h"
31 #include "mhw_vdbox_mfx_g12_X.h"
32 #include "codechal_mmc_decode_mpeg2_g12.h"
33 #include "hal_oca_interface.h"
34 
~CodechalDecodeMpeg2G12()35 CodechalDecodeMpeg2G12::~CodechalDecodeMpeg2G12 ()
36 {
37     CODECHAL_DECODE_FUNCTION_ENTER;
38 
39     if (m_veState != nullptr)
40     {
41         MOS_FreeMemAndSetNull(m_veState);
42         m_veState = nullptr;
43     }
44 }
45 
InitMmcState()46 MOS_STATUS  CodechalDecodeMpeg2G12::InitMmcState()
47 {
48 #ifdef _MMC_SUPPORTED
49     m_mmc = MOS_New(CodechalMmcDecodeMpeg2G12, m_hwInterface, this);
50     CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
51 #endif
52     return MOS_STATUS_SUCCESS;
53 }
54 
SetGpuCtxCreatOption(CodechalSetting * codecHalSetting)55 MOS_STATUS CodechalDecodeMpeg2G12::SetGpuCtxCreatOption(
56     CodechalSetting *codecHalSetting)
57 {
58     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
59 
60     CODECHAL_DECODE_FUNCTION_ENTER;
61 
62     if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
63     {
64         CodechalDecode::SetGpuCtxCreatOption(codecHalSetting);
65     }
66     else
67     {
68         m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED);
69         bool sfcInUse    = (codecHalSetting->sfcInUseHinted && codecHalSetting->downsamplingHinted
70                             && (MEDIA_IS_SKU(m_skuTable, FtrSFCPipe) && !MEDIA_IS_SKU(m_skuTable, FtrDisableVDBox2SFC)));
71         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_ConstructParmsForGpuCtxCreation(
72             m_veState,
73             (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt,
74             sfcInUse));
75         m_videoContext = MOS_GPU_CONTEXT_VIDEO;
76     }
77 
78     return eStatus;
79 }
80 
SetFrameStates()81 MOS_STATUS CodechalDecodeMpeg2G12::SetFrameStates ()
82 {
83     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
84 
85     CODECHAL_DECODE_FUNCTION_ENTER;
86 
87     CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeMpeg2::SetFrameStates());
88 
89     if (MOS_VE_SUPPORTED(m_osInterface) && !MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
90     {
91         MOS_VIRTUALENGINE_SET_PARAMS  vesetParams;
92 
93         MOS_ZeroMemory(&vesetParams, sizeof(vesetParams));
94         vesetParams.bSFCInUse                   = false;
95         vesetParams.bNeedSyncWithPrevious       = true;
96         vesetParams.bSameEngineAsLastSubmission = false;
97         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_SetHintParams(m_veState, &vesetParams));
98     }
99 
100     return eStatus;
101 }
102 
DecodeStateLevel()103 MOS_STATUS CodechalDecodeMpeg2G12::DecodeStateLevel()
104 {
105     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
106 
107     CODECHAL_DECODE_FUNCTION_ENTER;
108 #ifdef _MMC_SUPPORTED
109     // To WA invalid aux data caused HW issue when MMC on
110     // Add disable Clear CCS WA due to green corruption issue
111     if (m_mmc->IsMmcEnabled() && !Mos_ResourceIsNull(&m_destSurface.OsResource) &&
112         m_destSurface.OsResource.bConvertedFromDDIResource)
113     {
114         if (MEDIA_IS_WA(m_waTable, Wa_1408785368) || MEDIA_IS_WA(m_waTable, Wa_22010493002) && (!MEDIA_IS_WA(m_waTable, WaDisableClearCCS)))
115         {
116             CODECHAL_DECODE_VERBOSEMESSAGE("Clear CCS by VE resolve before frame %d submission", m_frameNum);
117             CODECHAL_DECODE_CHK_STATUS_RETURN(static_cast<CodecHalMmcStateG12 *>(m_mmc)->ClearAuxSurf(
118                 this, m_miInterface, &m_destSurface.OsResource, m_veState));
119         }
120     }
121 #endif
122 
123     uint8_t fwdRefIdx = (uint8_t)m_picParams->m_forwardRefIdx;
124     uint8_t bwdRefIdx = (uint8_t)m_picParams->m_backwardRefIdx;
125 
126     // Do not use data that has not been initialized
127     if (CodecHal_PictureIsInvalid(m_mpeg2RefList[fwdRefIdx]->RefPic))
128     {
129         fwdRefIdx = m_picParams->m_currPic.FrameIdx;
130     }
131     if (CodecHal_PictureIsInvalid(m_mpeg2RefList[bwdRefIdx]->RefPic))
132     {
133         bwdRefIdx = m_picParams->m_currPic.FrameIdx;
134     }
135 
136     MOS_COMMAND_BUFFER cmdBuffer;
137     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
138 
139     auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
140     HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
141 
142     MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams;
143     MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS));
144     forceWakeupParams.bMFXPowerWellControl = true;
145     forceWakeupParams.bMFXPowerWellControlMask = true;
146     forceWakeupParams.bHEVCPowerWellControl = false;
147     forceWakeupParams.bHEVCPowerWellControlMask = true;
148     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd(
149         &cmdBuffer,
150         &forceWakeupParams));
151 
152     MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
153     pipeModeSelectParams.Mode                  = m_mode;
154     pipeModeSelectParams.bStreamOutEnabled     = m_streamOutEnabled;
155     pipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled;
156     pipeModeSelectParams.bPreDeblockOutEnable  = !m_deblockingEnabled;
157 
158     MHW_VDBOX_SURFACE_PARAMS surfaceParams;
159     MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
160     surfaceParams.Mode                      = m_mode;
161     surfaceParams.psSurface                 = &m_destSurface;
162 
163     MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
164     pipeBufAddrParams.Mode                      = m_mode;
165     if (m_deblockingEnabled)
166     {
167         pipeBufAddrParams.psPostDeblockSurface = &m_destSurface;
168     }
169     else
170     {
171         pipeBufAddrParams.psPreDeblockSurface = &m_destSurface;
172     }
173 
174 #ifdef _MMC_SUPPORTED
175     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams));
176 #endif
177 
178     // when there is not a forward or backward reference,
179     // the index is set to the destination frame index
180     m_presReferences[CodechalDecodeFwdRefTop] =
181         m_presReferences[CodechalDecodeFwdRefBottom] =
182             m_presReferences[CodechalDecodeBwdRefTop] =
183                 m_presReferences[CodechalDecodeBwdRefBottom] = &m_destSurface.OsResource;
184 
185     if (fwdRefIdx < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
186     {
187         m_presReferences[CodechalDecodeFwdRefTop] =
188             m_presReferences[CodechalDecodeFwdRefBottom] = &m_mpeg2RefList[fwdRefIdx]->resRefPic;
189     }
190     if (bwdRefIdx < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
191     {
192         m_presReferences[CodechalDecodeBwdRefTop] =
193             m_presReferences[CodechalDecodeBwdRefBottom] = &m_mpeg2RefList[bwdRefIdx]->resRefPic;
194     }
195 
196     // special case for second fields
197     if (m_picParams->m_secondField && m_picParams->m_pictureCodingType == P_TYPE)
198     {
199         if (m_picParams->m_topFieldFirst)
200         {
201             m_presReferences[CodechalDecodeFwdRefTop] =
202                 &m_destSurface.OsResource;
203         }
204         else
205         {
206             m_presReferences[CodechalDecodeFwdRefBottom] =
207                 &m_destSurface.OsResource;
208         }
209     }
210 
211     // set all ref pic addresses to valid addresses for error concealment purpose
212     for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
213     {
214         if (m_presReferences[i] == nullptr &&
215             MEDIA_IS_WA(m_waTable, WaDummyReference) &&
216             !Mos_ResourceIsNull(&m_dummyReference.OsResource))
217         {
218             m_presReferences[i] = &m_dummyReference.OsResource;
219         }
220     }
221 
222     CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
223         pipeBufAddrParams.presReferences,
224         sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC,
225         m_presReferences,
226         sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC));
227 
228     pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
229         &m_resMfdDeblockingFilterRowStoreScratchBuffer;
230 
231     if (m_streamOutEnabled)
232     {
233         pipeBufAddrParams.presStreamOutBuffer =
234             &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
235     }
236 
237 #ifdef _MMC_SUPPORTED
238     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&pipeBufAddrParams));
239 
240     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode));
241 #endif
242 
243     CODECHAL_DEBUG_TOOL(
244         for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
245         {
246             if (pipeBufAddrParams.presReferences[i])
247             {
248                 MOS_SURFACE dstSurface;
249 
250                 MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
251                 dstSurface.Format     = Format_NV12;
252                 dstSurface.OsResource = *(pipeBufAddrParams.presReferences[i]);
253                 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
254                     m_osInterface,
255                     &dstSurface));
256 
257                 m_debugInterface->m_refIndex = (uint16_t)i;
258                 std::string refSurfName      = "RefSurf[" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex)) + "]";
259                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
260                     &dstSurface,
261                     CodechalDbgAttr::attrDecodeReferenceSurfaces,
262                     refSurfName.data()));
263             }
264         }
265     )
266 
267     //set correctly indirect BSD object base address.
268     PMOS_RESOURCE indObjBase;
269     if (m_copiedDataBufferInUse)
270     {
271         indObjBase = &m_resCopiedDataBuffer[m_currCopiedData];
272     }
273     else
274     {
275         indObjBase = &m_resDataBuffer;
276     }
277 
278     MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
279     MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
280     indObjBaseAddrParams.Mode               = m_mode;
281     indObjBaseAddrParams.dwDataSize =
282         m_copiedDataBufferInUse ? m_copiedDataBufferSize : m_dataSize;
283     indObjBaseAddrParams.presDataBuffer     = indObjBase;
284 
285     MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams;
286     MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
287     bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer;
288 
289     MHW_VDBOX_MPEG2_PIC_STATE mpeg2PicState;
290     mpeg2PicState.Mode                                  = m_mode;
291     mpeg2PicState.pMpeg2PicParams                       = m_picParams;
292     mpeg2PicState.bDeblockingEnabled                    = m_deblockingEnabled;
293     mpeg2PicState.dwMPEG2ISliceConcealmentMode          = m_mpeg2ISliceConcealmentMode;
294     mpeg2PicState.dwMPEG2PBSliceConcealmentMode         = m_mpeg2PbSliceConcealmentMode;
295     mpeg2PicState.dwMPEG2PBSlicePredBiDirMVTypeOverride = m_mpeg2PbSlicePredBiDirMvTypeOverride;
296     mpeg2PicState.dwMPEG2PBSlicePredMVOverride          = m_mpeg2PbSlicePredMvOverride;
297 
298     MHW_VDBOX_QM_PARAMS qmParams;
299     qmParams.Standard                       = CODECHAL_MPEG2;
300     qmParams.pMpeg2IqMatrix                 = m_iqMatrixBuffer;
301 
302     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
303         &cmdBuffer, true));
304 
305     if (m_statusQueryReportingEnabled)
306     {
307         CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(
308             &cmdBuffer));
309     }
310 
311     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(
312         &cmdBuffer,
313         &pipeModeSelectParams));
314 
315 #ifdef _MMC_SUPPORTED
316     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceState(&surfaceParams));
317 #endif
318     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(
319         &cmdBuffer,
320         &surfaceParams));
321 
322     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(
323         &cmdBuffer,
324         &pipeBufAddrParams));
325 
326     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(
327         &cmdBuffer,
328         &indObjBaseAddrParams));
329 
330     if (CodecHalIsDecodeModeVLD(m_mode))
331     {
332         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(
333             &cmdBuffer,
334             &bspBufBaseAddrParams));
335     }
336 
337     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxMpeg2PicCmd(
338         &cmdBuffer,
339         &mpeg2PicState));
340 
341     if (CodecHalIsDecodeModeVLD(m_mode))
342     {
343         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(
344             &cmdBuffer,
345             &qmParams));
346     }
347 
348     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
349 
350     return eStatus;
351 }
352 
SliceLevel()353 MOS_STATUS CodechalDecodeMpeg2G12::SliceLevel()
354 {
355     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
356 
357     CODECHAL_DECODE_FUNCTION_ENTER;
358 
359     if ((m_decodePhantomMbs) || (m_incompletePicture))
360     {
361         if (m_bbInUsePerFrame >= m_bbAllocated / CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP)
362         {
363             m_bbAllocated += CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP;
364             if (m_bbAllocated >= CODECHAL_DECODE_MPEG2_MAXIMUM_BATCH_BUFFERS)
365             {
366                 CODECHAL_DECODE_ASSERTMESSAGE(
367                     "The number of MPEG2 second level batch buffer is not big enough to hold the whole frame.");
368                 return MOS_STATUS_EXCEED_MAX_BB_SIZE;
369             }
370 
371             for (uint32_t i = 0; i < CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP; i++)
372             {
373                 uint32_t j = m_bbAllocated - i - 1;
374                 MOS_ZeroMemory(&m_mediaObjectBatchBuffer[j], sizeof(MHW_BATCH_BUFFER));
375 
376                 uint32_t u32Size = m_standardDecodeSizeNeeded * m_picWidthInMb * m_picHeightInMb +
377                                    m_hwInterface->m_sizeOfCmdBatchBufferEnd;
378 
379                 CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
380                     m_osInterface,
381                     &m_mediaObjectBatchBuffer[j],
382                     nullptr,
383                     u32Size));
384                 m_mediaObjectBatchBuffer[j].bSecondLevel = true;
385             }
386         }
387     }
388 
389     CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
390 
391     MOS_COMMAND_BUFFER cmdBuffer;
392     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
393         m_osInterface,
394         &cmdBuffer,
395         0));
396 
397     MHW_BATCH_BUFFER batchBuffer = m_mediaObjectBatchBuffer[m_bbInUse];
398 
399     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
400         &cmdBuffer,
401         &batchBuffer));
402 
403     CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_LockBb(
404         m_osInterface,
405         &batchBuffer));
406 
407     if (m_decodePhantomMbs)
408     {
409         CODECHAL_DECODE_CHK_STATUS_RETURN(InsertDummySlices(
410             &batchBuffer,
411             m_lastMbAddress,
412             m_picWidthInMb * m_picHeightInMb));
413     }
414     else
415     {
416         CodecDecodeMpeg2SliceParams *slc = m_sliceParams;
417 
418         uint16_t prevSliceMBEnd = m_lastMbAddress;
419 
420         for (uint16_t slcCount = 0; slcCount < m_numSlices; slcCount++)
421         {
422             if (!m_vldSliceRecord[slcCount].dwSkip)
423             {
424                 if (prevSliceMBEnd != m_vldSliceRecord[slcCount].dwSliceStartMbOffset)
425                 {
426                     CODECHAL_DECODE_CHK_STATUS_RETURN(InsertDummySlices(
427                         &batchBuffer,
428                         prevSliceMBEnd,
429                         (uint16_t)m_vldSliceRecord[slcCount].dwSliceStartMbOffset));
430                 }
431 
432                 if (m_vldSliceRecord[slcCount].bIsLastSlice)
433                 {
434                     uint16_t expectedFinalMb = m_picWidthInMb * m_picHeightInMb;
435 
436                     m_lastMbAddress =
437                         (uint16_t)(m_vldSliceRecord[slcCount].dwSliceStartMbOffset +
438                                    slc->m_numMbsForSlice);
439 
440                     if (m_lastMbAddress < expectedFinalMb)
441                     {
442                         m_incompletePicture                = true;
443                         m_vldSliceRecord[slcCount].bIsLastSlice = false;
444                     }
445                     else
446                     {
447                         //Indicate It's complete picture now
448                         m_incompletePicture                = false;
449                     }
450                 }
451 
452                 // static MPEG2 slice parameters
453                 MHW_VDBOX_MPEG2_SLICE_STATE mpeg2SliceState;
454                 mpeg2SliceState.presDataBuffer          = &m_resDataBuffer;
455                 mpeg2SliceState.wPicWidthInMb           = m_picWidthInMb;
456                 mpeg2SliceState.wPicHeightInMb          = m_picHeightInMb;
457                 mpeg2SliceState.pMpeg2SliceParams       = slc;
458                 mpeg2SliceState.dwLength                = m_vldSliceRecord[slcCount].dwLength;
459                 mpeg2SliceState.dwOffset =
460                     m_vldSliceRecord[slcCount].dwOffset + m_copiedDataOffset;
461                 mpeg2SliceState.dwSliceStartMbOffset = m_vldSliceRecord[slcCount].dwSliceStartMbOffset;
462                 mpeg2SliceState.bLastSlice           = m_vldSliceRecord[slcCount].bIsLastSlice;
463 
464                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdMpeg2BsdObject(
465                     nullptr,
466                     &batchBuffer,
467                     &mpeg2SliceState));
468 
469                 prevSliceMBEnd =
470                     (uint16_t)(m_vldSliceRecord[slcCount].dwSliceStartMbOffset +
471                                slc->m_numMbsForSlice);
472             }
473 
474             slc++;
475         }
476     }
477 
478     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
479         nullptr,
480         &batchBuffer));
481 
482     CODECHAL_DEBUG_TOOL(
483         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
484             &batchBuffer,
485             CODECHAL_NUM_MEDIA_STATES,
486             "_DEC"));
487     )
488 
489     CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_UnlockBb(
490         m_osInterface,
491         &batchBuffer,
492         true));
493 
494     m_bbInUse = (m_bbInUse + 1) % m_bbAllocated;
495     m_bbInUsePerFrame++;
496 
497     if (!m_incompletePicture)
498     {
499         // Check if destination surface needs to be synchronized
500         MOS_SYNC_PARAMS syncParams          = g_cInitSyncParams;
501         syncParams.GpuContext               = m_videoContext;
502         syncParams.presSyncResource         = &m_destSurface.OsResource;
503         syncParams.bReadOnly                = false;
504         syncParams.bDisableDecodeSyncLock   = m_disableDecodeSyncLock;
505         syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
506 
507         if (!CodecHal_PictureIsField(m_picParams->m_currPic) ||
508             !m_picParams->m_secondField)
509         {
510             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(
511                 m_osInterface,
512                 &syncParams));
513             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(
514                 m_osInterface,
515                 &syncParams));
516 
517             // Update the resource tag (s/w tag) for On-Demand Sync
518             m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
519         }
520 
521         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
522         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
523 
524         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
525             &cmdBuffer,
526             &flushDwParams));
527 
528         // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
529         if (m_osInterface->bTagResourceSync &&
530             (!CodecHal_PictureIsField(m_picParams->m_currPic) || m_picParams->m_secondField))
531         {
532             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
533                 &cmdBuffer,
534                 &syncParams));
535         }
536 
537         if (m_statusQueryReportingEnabled)
538         {
539             CodechalDecodeStatusReport decodeStatusReport;
540 
541             decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
542             decodeStatusReport.m_currDecodedPic     = m_picParams->m_currPic;
543             decodeStatusReport.m_currDeblockedPic   = m_picParams->m_currPic;
544             decodeStatusReport.m_codecStatus        = CODECHAL_STATUS_UNAVAILABLE;
545             decodeStatusReport.m_currDecodedPicRes  = m_mpeg2RefList[m_picParams->m_currPic.FrameIdx]->resRefPic;
546 
547             CODECHAL_DEBUG_TOOL(
548                 decodeStatusReport.m_secondField = m_picParams->m_secondField ? true : false;
549                 decodeStatusReport.m_frameType   = m_perfType;)
550 
551             CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(
552                 decodeStatusReport,
553                 &cmdBuffer));
554         }
555 
556 #if (_DEBUG || _RELEASE_INTERNAL)
557         uint32_t curIdx         = (GetDecodeStatusBuf()->m_currIndex + CODECHAL_DECODE_STATUS_NUM - 1) % CODECHAL_DECODE_STATUS_NUM;
558         uint32_t frameCrcOffset = curIdx * sizeof(CodechalDecodeStatus) + GetDecodeStatusBuf()->m_decFrameCrcOffset + sizeof(uint32_t) * 2;
559         std::vector<MOS_RESOURCE> vSemaResource{GetDecodeStatusBuf()->m_statusBuffer};
560         m_debugInterface->DetectCorruptionHw(m_hwInterface, &m_frameCountTypeBuf, curIdx, frameCrcOffset, vSemaResource, &cmdBuffer, m_frameNum);
561 #endif
562 
563         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
564             &cmdBuffer,
565             nullptr));
566 
567         m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
568 
569         CODECHAL_DEBUG_TOOL(
570             CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
571                 &cmdBuffer,
572                 CODECHAL_NUM_MEDIA_STATES,
573                 "_DEC"));
574 
575             //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
576             //    m_debugInterface,
577             //    &cmdBuffer));
578         )
579 
580         //Sync up complete frame
581         syncParams                      = g_cInitSyncParams;
582         syncParams.GpuContext           = m_videoContextForWa;
583         syncParams.presSyncResource     = &m_resSyncObjectWaContextInUse;
584 
585         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
586 
587         syncParams                      = g_cInitSyncParams;
588         syncParams.GpuContext           = m_videoContext;
589         syncParams.presSyncResource     = &m_resSyncObjectWaContextInUse;
590 
591         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
592 
593         if ( MOS_VE_SUPPORTED(m_osInterface))
594         {
595             CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false);
596         }
597 
598         HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
599 
600         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
601             m_osInterface,
602             &cmdBuffer,
603             m_videoContextUsesNullHw));
604 
605         CODECHAL_DEBUG_TOOL(
606             m_mmc->UpdateUserFeatureKey(&m_destSurface);)
607 
608         if (m_statusQueryReportingEnabled)
609         {
610             CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(
611                 m_videoContextUsesNullHw));
612         }
613 
614         // Needs to be re-set for Linux buffer re-use scenarios
615         m_mpeg2RefList[m_picParams->m_currPic.FrameIdx]->resRefPic =
616             m_destSurface.OsResource;
617 
618         // Send the signal to indicate decode completion, in case On-Demand Sync is not present
619         if (!CodecHal_PictureIsField(m_picParams->m_currPic) || m_picParams->m_secondField)
620         {
621             syncParams                      = g_cInitSyncParams;
622             syncParams.GpuContext           = m_videoContext;
623             syncParams.presSyncResource     = &m_destSurface.OsResource;
624 
625             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
626         }
627     }
628     else
629     {
630         m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
631     }
632 
633     return eStatus;
634 }
635 
AllocateStandard(CodechalSetting * settings)636 MOS_STATUS CodechalDecodeMpeg2G12::AllocateStandard (
637     CodechalSetting *          settings)
638 {
639     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
640 
641     CODECHAL_DECODE_FUNCTION_ENTER;
642 
643     CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeMpeg2::AllocateStandard(
644         settings));
645 
646 #ifdef _MMC_SUPPORTED
647     // To WA invalid aux data caused HW issue when MMC on
648     // Add disable Clear CCS WA due to green corruption issue
649     if (m_mmc->IsMmcEnabled())
650     {
651         if (MEDIA_IS_WA(m_waTable, Wa_1408785368) || MEDIA_IS_WA(m_waTable, Wa_22010493002) && (!MEDIA_IS_WA(m_waTable, WaDisableClearCCS)))
652         {
653             MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
654 
655             //Add HUC STATE Commands
656             m_hwInterface->GetHucStateCommandSize(
657                 CODECHAL_DECODE_MODE_MPEG2VLD,
658                 &m_HucStateCmdBufferSizeNeeded,
659                 &m_HucPatchListSizeNeeded,
660                 &stateCmdSizeParams);
661         }
662     }
663 #endif
664 
665     if ( MOS_VE_SUPPORTED(m_osInterface))
666     {
667         static_cast<MhwVdboxMfxInterfaceG12*>(m_mfxInterface)->DisableScalabilitySupport();
668 
669         //single pipe VE initialize
670         m_veState = (PCODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE));
671         CODECHAL_DECODE_CHK_NULL_RETURN(m_veState);
672         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_InitInterface(m_osInterface, m_veState));
673     }
674 
675     return eStatus;
676 }
677 
CodechalDecodeMpeg2G12(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)678 CodechalDecodeMpeg2G12::CodechalDecodeMpeg2G12 (
679     CodechalHwInterface   *hwInterface,
680     CodechalDebugInterface* debugInterface,
681     PCODECHAL_STANDARD_INFO standardInfo) :
682     CodechalDecodeMpeg2(hwInterface, debugInterface, standardInfo)
683 {
684     CODECHAL_DECODE_FUNCTION_ENTER;
685 
686     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
687 
688     m_osInterface->pfnVirtualEngineSupported(m_osInterface, true, true);
689 }
690 
CalcRequestedSpace(uint32_t & requestedSize,uint32_t & additionalSizeNeeded,uint32_t & requestedPatchListSize)691 void CodechalDecodeMpeg2G12::CalcRequestedSpace(
692     uint32_t &requestedSize,
693     uint32_t &additionalSizeNeeded,
694     uint32_t &requestedPatchListSize)
695 {
696     CODECHAL_DECODE_FUNCTION_ENTER;
697 
698     requestedSize = m_commandBufferSizeNeeded + m_HucStateCmdBufferSizeNeeded +
699                     (m_standardDecodeSizeNeeded * (m_decodeParams.m_numSlices + 1));
700     requestedPatchListSize = m_commandPatchListSizeNeeded + m_HucPatchListSizeNeeded +
701                              (m_standardDecodePatchListSizeNeeded * (m_decodeParams.m_numSlices + 1));
702     additionalSizeNeeded = COMMAND_BUFFER_RESERVED_SPACE;
703 }
704 
705