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