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.h"
30 #include "codechal_secure_decode_interface.h"
31 #include "codechal_mmc_decode_mpeg2.h"
32 #include "hal_oca_interface.h"
33 #if USE_CODECHAL_DEBUG_TOOL
34 #include <sstream>
35 #include <fstream>
36 #include "codechal_debug.h"
37 #endif
38 
39 #define CODECHAL_DECODE_MPEG2_IDCTBLOCK_SIZE   64
40 
41 // One MB size (16x16) intra MB, color = RGB[4, 4, 4]
42 const uint32_t CODECHAL_DECODE_MPEG2_WaDummyBitstream[] =
43 {0x01010000, 0x54e29752, 0x002022a5, //Dummy Slice 0, q_scale_type = 0, intra_vlc_format = 0
44  0x01010000, 0x4de29752, 0x8661341a, //Dummy Slice 1, q_scale_type = 0, intra_vlc_format = 1
45  0x01010000, 0x54e2a772, 0x002022a5, //Dummy Slice 2, q_scale_type = 1, intra_vlc_format = 0
46  0x01010000, 0x4de2a772, 0x8661341a  //Dummy Slice 3, q_scale_type = 1, intra_vlc_format = 1
47 };
48 
49 const uint32_t CODECHAL_DECODE_MPEG2_WaDummySliceLengths[] = {0x8, 0x8, 0x8, 0x8};
50 const uint32_t CODECHAL_DECODE_MPEG2_WaDummySliceOffsets[] = {0x4, 0x10, 0x1c, 0x28};
51 
DetectSliceError(uint16_t slcNum,uint32_t prevSliceMbEnd,bool firstValidSlice)52 bool CodechalDecodeMpeg2::DetectSliceError(
53     uint16_t                        slcNum,
54     uint32_t                        prevSliceMbEnd,
55     bool                            firstValidSlice)
56 {
57     bool                        result         = false;
58     CODECHAL_VLD_SLICE_RECORD   currSliceRecord = m_vldSliceRecord[slcNum];
59 
60     if (currSliceRecord.dwLength == 0 || currSliceRecord.dwLength > (uint32_t)(1 << (sizeof(uint32_t) * 8 - 1)))
61     {
62         result = true;
63     }
64     else if ((m_sliceParams[slcNum].m_sliceDataOffset + currSliceRecord.dwLength) >
65              m_dataSize)
66     {
67         // error handling for garbage data
68         result = true;
69     }
70     else if (m_slicesInvalid)
71     {
72         // If cp copy failed for this interation due to lack of buffer space, cannot use any
73         // slices in this iteration since there is no bitstream data for them
74         result = true;
75     }
76     else if (prevSliceMbEnd > currSliceRecord.dwSliceStartMbOffset ||
77              m_sliceParams[slcNum].m_sliceVerticalPosition >= m_picHeightInMb ||
78              m_sliceParams[slcNum].m_sliceHorizontalPosition >= m_picWidthInMb)
79     {
80         result = true;
81         m_slicesInvalid = true;
82     }
83     else if (!m_sliceParams[slcNum].m_numMbsForSlice)
84     {
85         // For SNB HW will not process BSD objects where the MbCount is 0, and if an invalid
86         // slice start position has been detected or the number of MBs in the current slice
87         // is invalid, the rest of the data may be garbage since SNB does not have
88         // robust error concealment for MPEG2 VLD, skipping these slices prevents HW hangs
89 
90         result = true;
91         m_slicesInvalid = true;
92     }
93     else if (m_sliceParams[slcNum].m_numMbsForSliceOverflow)
94     {
95         // Special case for last slice of an incomplete frame
96         if ((slcNum == m_numSlices - 1) &&
97             !firstValidSlice &&
98             ((currSliceRecord.dwSliceStartMbOffset + m_sliceParams[slcNum].m_numMbsForSlice) <
99                 (uint32_t)(m_picHeightInMb * m_picWidthInMb)))
100         {
101             m_sliceParams[slcNum].m_numMbsForSlice = m_picWidthInMb;
102         }
103         else
104         {
105             result = true;
106             m_slicesInvalid = true;
107         }
108     }
109 
110     return result;
111 }
112 
InsertDummySlices(PMHW_BATCH_BUFFER batchBuffer,uint16_t startMB,uint16_t endMB)113 MOS_STATUS CodechalDecodeMpeg2::InsertDummySlices(
114     PMHW_BATCH_BUFFER               batchBuffer,
115     uint16_t                        startMB,
116     uint16_t                        endMB)
117 {
118     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
119     bool      cpEnable = false;
120 
121     CODECHAL_DECODE_FUNCTION_ENTER;
122 
123     CODECHAL_DECODE_CHK_NULL_RETURN(batchBuffer);
124     CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
125     CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface->osCpInterface);
126 
127     //  A copied data buffer must be present
128     if (m_nextCopiedDataOffset && !m_dummySliceDataPresent)
129     {
130         // slice header uses 4 bytes
131         CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface(
132             sizeof(CODECHAL_DECODE_MPEG2_WaDummyBitstream),
133             m_resMpeg2DummyBistream,
134             &m_resCopiedDataBuffer[m_currCopiedData],
135             &m_dummySliceDataOffset));
136 
137         m_dummySliceDataPresent = true;
138     }
139 
140     // force disable cp for dummy slices
141     cpEnable = m_osInterface->osCpInterface->IsCpEnabled();
142     if (cpEnable)
143     {
144         m_osInterface->osCpInterface->SetCpEnabled(false);
145     }
146 
147     uint16_t intraVLDFormat                = m_picParams->W0.m_intraVlcFormat;
148     uint16_t quantizerScaleType            = m_picParams->W0.m_quantizerScaleType;
149     uint16_t dummySliceIndex               = quantizerScaleType * 2 + intraVLDFormat;
150 
151     MHW_VDBOX_MPEG2_SLICE_STATE         mpeg2SliceState;
152     mpeg2SliceState.presDataBuffer      = nullptr;
153     mpeg2SliceState.wPicWidthInMb       = m_picWidthInMb;
154     mpeg2SliceState.wPicHeightInMb      = m_picHeightInMb;
155     mpeg2SliceState.dwLength            =
156         CODECHAL_DECODE_MPEG2_WaDummySliceLengths[dummySliceIndex];
157     mpeg2SliceState.dwOffset =
158         m_dummySliceDataOffset + CODECHAL_DECODE_MPEG2_WaDummySliceOffsets[dummySliceIndex];
159 
160     bool isLastSlice                   = false;
161     uint16_t expectedEndMB                 = m_picWidthInMb * m_picHeightInMb;
162 
163     CodecDecodeMpeg2SliceParams slc;
164     MOS_ZeroMemory(&slc, sizeof(CodecDecodeMpeg2SliceParams));
165 
166     while (startMB < endMB)
167     {
168         slc.m_macroblockOffset           = 6;
169         slc.m_sliceHorizontalPosition     = startMB % m_picWidthInMb;
170         slc.m_sliceVerticalPosition       = startMB / m_picWidthInMb;
171         slc.m_quantiserScaleCode        = 10;
172         slc.m_numMbsForSlice              = 1;
173 
174         isLastSlice = ((startMB + 1) == expectedEndMB);
175 
176         mpeg2SliceState.pMpeg2SliceParams       = &slc;
177         mpeg2SliceState.dwSliceStartMbOffset    = startMB;
178         mpeg2SliceState.bLastSlice              = isLastSlice;
179 
180         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdMpeg2BsdObject(
181             nullptr,
182             batchBuffer,
183             &mpeg2SliceState));
184 
185         startMB++;
186     }
187 
188     // restore Cp state
189     if (cpEnable)
190     {
191         m_osInterface->osCpInterface->SetCpEnabled(true);
192     }
193 
194     if (isLastSlice)
195     {
196         m_incompletePicture = false;
197     }
198 
199     return eStatus;
200 }
201 
CopyDataSurface(uint32_t dataSize,MOS_RESOURCE sourceSurface,PMOS_RESOURCE copiedSurface,uint32_t * currOffset)202 MOS_STATUS CodechalDecodeMpeg2::CopyDataSurface(
203     uint32_t                        dataSize,
204     MOS_RESOURCE                    sourceSurface,
205     PMOS_RESOURCE                   copiedSurface,
206     uint32_t                        *currOffset)
207 {
208     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
209 
210     CODECHAL_DECODE_FUNCTION_ENTER;
211 
212     if (Mos_ResourceIsNull(copiedSurface))
213     {
214         // Allocate resCopiedDataBuffer if not already allocated.
215         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
216                                                       copiedSurface,
217                                                       m_copiedDataBufferSize,
218                                                       "CopiedDataBuffer"),
219             "Failed to allocate copied residual data buffer.");
220     }
221 
222     if ((m_nextCopiedDataOffset + dataSize) > m_copiedDataBufferSize)
223     {
224         CODECHAL_DECODE_ASSERTMESSAGE("Copied data buffer is not large enough.");
225 
226         m_slicesInvalid = true;
227         return MOS_STATUS_UNKNOWN;
228     }
229 
230     uint32_t size = MOS_ALIGN_CEIL(dataSize, 16); // 16 byte aligned
231 
232     // HuC is not supported on BDW
233     if (m_hwInterface->m_noHuC)
234     {
235         CodechalDataCopyParams dataCopyParams;
236         MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
237         dataCopyParams.srcResource = &sourceSurface;
238         dataCopyParams.srcSize = size;
239         dataCopyParams.srcOffset = 0;
240         dataCopyParams.dstResource = copiedSurface;
241         dataCopyParams.dstSize = size;
242         dataCopyParams.dstOffset   = m_nextCopiedDataOffset;
243 
244         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(
245             &dataCopyParams));
246 
247         *currOffset = m_nextCopiedDataOffset;
248         m_nextCopiedDataOffset += MOS_ALIGN_CEIL(size, MHW_CACHELINE_SIZE);  // 64-byte aligned
249         return MOS_STATUS_SUCCESS;
250     }
251 
252     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
253         m_osInterface,
254         m_videoContextForWa));
255     m_osInterface->pfnResetOsStates(m_osInterface);
256 
257     m_osInterface->pfnSetPerfTag(
258         m_osInterface,
259         (uint16_t)(((m_mode << 4) & 0xF0) | COPY_TYPE));
260     m_osInterface->pfnResetPerfBufferID(m_osInterface);
261 
262     MOS_COMMAND_BUFFER cmdBuffer;
263     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
264         m_osInterface,
265         &cmdBuffer,
266         0));
267 
268     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
269         &cmdBuffer,
270         false));
271 
272     // Use huc stream out to do the copy
273     CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
274         &cmdBuffer,                // pCmdBuffer
275         &sourceSurface,            // presSrc
276         copiedSurface,             // presDst
277         size,                      // u32CopyLength
278         0,                         // u32CopyInputOffset
279         m_nextCopiedDataOffset));  // u32CopyOutputOffset
280 
281     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
282     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
283     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
284         &cmdBuffer,
285         &flushDwParams));
286 
287     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
288         &cmdBuffer,
289         nullptr));
290 
291     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
292 
293     if (!m_incompletePicture)
294     {
295         MOS_SYNC_PARAMS syncParams      = g_cInitSyncParams;
296         syncParams.GpuContext           = m_videoContext;
297         syncParams.presSyncResource     = &m_resSyncObjectVideoContextInUse;
298 
299         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
300 
301         syncParams                      = g_cInitSyncParams;
302         syncParams.GpuContext           = m_videoContextForWa;
303         syncParams.presSyncResource     = &m_resSyncObjectVideoContextInUse;
304 
305         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
306     }
307 
308     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
309         m_osInterface,
310         &cmdBuffer,
311         m_videoContextForWaUsesNullHw));
312 
313     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
314         m_osInterface,
315         m_videoContext));
316 
317     *currOffset = m_nextCopiedDataOffset;
318     m_nextCopiedDataOffset += MOS_ALIGN_CEIL(size, 64);  // offsets are 64-byte aligned
319 
320     return eStatus;
321 }
322 
323 /*--------------------------------------------------------------------------
324 | Name      : CodecHalMpeg2Decode_InitializeBeginFrame
325 | Purpose   : Initialize MPEG2 incomplete frame values in the DecodeBeginFrame
326 | Arguments : IN -> pMpeg2State    : the pointer to mpeg2 state
327 IN -> pDecoder       : the pointer to codechal decoder structure
328 | Returns   : MOS_STATUS_SUCCESS : Function successfully completed its task
329 |             MOS_STATUS_UNKNOWN: Error condition encountered (frame will not be rendered)
330 \---------------------------------------------------------------------------*/
InitializeBeginFrame()331 MOS_STATUS CodechalDecodeMpeg2::InitializeBeginFrame()
332 {
333     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
334 
335     CODECHAL_DECODE_FUNCTION_ENTER;
336 
337     m_incompletePicture  = false;
338     m_copiedDataBufferInUse = false;
339     m_copiedDataOffset      = 0;
340     m_nextCopiedDataOffset  = 0;
341     m_lastMbAddress         = 0;
342     m_slicesInvalid         = false;
343 
344     m_currCopiedData =
345         (m_currCopiedData + 1) % CODECHAL_DECODE_MPEG2_COPIED_SURFACES;
346     m_dummySliceDataPresent = false;
347     m_dummySliceDataOffset  = 0;
348     m_bbInUsePerFrame       = 0;
349 
350     return eStatus;
351 }
352 
AllocateResources()353 MOS_STATUS CodechalDecodeMpeg2::AllocateResources ()
354 {
355     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
356 
357     CODECHAL_DECODE_FUNCTION_ENTER;
358 
359     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
360         m_osInterface,
361         &m_resSyncObjectWaContextInUse));
362     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
363         m_osInterface,
364         &m_resSyncObjectVideoContextInUse));
365 
366     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalAllocateDataList(
367         m_mpeg2RefList,
368         CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2));
369 
370     for (uint32_t i = 0; i < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2; i++)
371     {
372         m_mpeg2RefList[i]->RefPic.PicFlags = PICTURE_INVALID;
373     }
374 
375     uint32_t numMacroblocks = m_picWidthInMb * m_picHeightInMb;
376 
377     if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD)
378     {
379         m_vldSliceRecord =
380             (PCODECHAL_VLD_SLICE_RECORD)MOS_AllocAndZeroMemory(numMacroblocks * sizeof(CODECHAL_VLD_SLICE_RECORD));
381         CODECHAL_DECODE_CHK_NULL_RETURN(m_vldSliceRecord);
382     }
383 
384     for (uint16_t i = 0; i < m_bbAllocated; i++)
385     {
386         MOS_ZeroMemory(&m_mediaObjectBatchBuffer[i], sizeof(MHW_BATCH_BUFFER));
387         uint32_t size = (m_standardDecodeSizeNeeded * numMacroblocks) + m_hwInterface->m_sizeOfCmdBatchBufferEnd;
388         CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
389             m_osInterface,
390             &m_mediaObjectBatchBuffer[i],
391             nullptr,
392             size));
393     }
394 
395     // Deblocking Filter Row Store Scratch buffer
396     //(Num MacroBlock Width) * (Num Cachlines) * (Cachline size)
397     CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
398                                                   &m_resMfdDeblockingFilterRowStoreScratchBuffer,
399                                                   m_picWidthInMb * 7 * CODECHAL_CACHELINE_SIZE,
400                                                   "DeblockingFilterScratch"),
401         "Failed to allocate BSD/MPC Row Store Scratch Buffer.");
402 
403     // MPR Row Store Scratch buffer
404     // (FrameWidth in MB) * (CacheLine size per MB) * 2
405     // IVB+ platforms need to have double MPR size for MBAFF
406     CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
407                                                   &m_resBsdMpcRowStoreScratchBuffer,
408                                                   ((uint32_t)(m_picWidthInMb * CODECHAL_CACHELINE_SIZE)) * 2,
409                                                   "MprScratchBuffer"),
410         "Failed to allocate AVC BSD MPR Row Store Scratch Buffer.");
411 
412     m_consecutiveMbErrorConcealmentInUse = true;
413 
414     // Dummy slice buffer
415     if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD)
416     {
417         uint32_t size = MOS_ALIGN_CEIL(sizeof(CODECHAL_DECODE_MPEG2_WaDummyBitstream), 64);
418         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
419                                                       &m_resMpeg2DummyBistream,
420                                                       size,
421                                                       "Mpeg2DummyBitstream"),
422             "Failed to allocate MPEG2 bitstream buffer for format switching WA.");
423 
424         CodechalResLock DummyBitstreamLock(m_osInterface, &m_resMpeg2DummyBistream);
425         auto data = DummyBitstreamLock.Lock(CodechalResLock::writeOnly);
426 
427         CODECHAL_DECODE_CHK_NULL_RETURN(data);
428 
429         MOS_ZeroMemory(data, size);
430         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(
431             data,
432             size,
433             (void *)CODECHAL_DECODE_MPEG2_WaDummyBitstream,
434             sizeof(CODECHAL_DECODE_MPEG2_WaDummyBitstream)),
435             "Failed to copy memory.");
436 
437     }
438 
439     if (m_mode == CODECHAL_DECODE_MODE_MPEG2IDCT)
440     {
441         // The common indirect IT-COEFF data structure is defined as a uint32_t.
442         m_copiedDataBufferSize = (numMacroblocks + 2) *
443                                  (CODEC_NUM_BLOCK_PER_MB * CODECHAL_DECODE_MPEG2_IDCTBLOCK_SIZE * sizeof(uint32_t));
444     }
445     else
446     {
447         // Bitstream buffer size = height * width + dummy slice + 512 (for padding)
448         m_copiedDataBufferSize =
449             (m_picWidthInMb * m_picHeightInMb * CODECHAL_DECODE_MPEG2_BYTES_PER_MB) +
450             sizeof(CODECHAL_DECODE_MPEG2_WaDummyBitstream) +
451             512;
452     }
453 
454     return eStatus;
455 }
456 
~CodechalDecodeMpeg2()457 CodechalDecodeMpeg2::~CodechalDecodeMpeg2 ()
458 {
459     CODECHAL_DECODE_FUNCTION_ENTER;
460 
461     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
462 
463     m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObjectWaContextInUse);
464     m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObjectVideoContextInUse);
465 
466     CodecHalFreeDataList(m_mpeg2RefList, CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2);
467 
468     MOS_FreeMemory(m_vldSliceRecord);
469 
470     for (uint32_t i = 0; i < m_bbAllocated; i++)
471     {
472         Mhw_FreeBb(m_osInterface, &m_mediaObjectBatchBuffer[i], nullptr);
473     }
474 
475     m_osInterface->pfnFreeResource(
476         m_osInterface,
477         &m_resMfdDeblockingFilterRowStoreScratchBuffer);
478 
479     m_osInterface->pfnFreeResource(
480         m_osInterface,
481         &m_resBsdMpcRowStoreScratchBuffer);
482 
483     // Dummy slice buffer
484     if (!Mos_ResourceIsNull(&m_resMpeg2DummyBistream))
485     {
486         m_osInterface->pfnFreeResource(
487             m_osInterface,
488             &m_resMpeg2DummyBistream);
489     }
490 
491     for (uint32_t i = 0; i < CODECHAL_DECODE_MPEG2_COPIED_SURFACES; i++)
492     {
493         m_osInterface->pfnFreeResource(
494             m_osInterface,
495             &m_resCopiedDataBuffer[i]);
496     }
497 }
498 
SetFrameStates()499 MOS_STATUS CodechalDecodeMpeg2::SetFrameStates ()
500 {
501     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
502 
503     CODECHAL_DECODE_FUNCTION_ENTER;
504 
505     uint32_t totalMBInFrame = 0;
506 
507     CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_destSurface);
508     CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_dataBuffer);
509     CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_picParams);
510 
511     m_dataSize                            = m_decodeParams.m_dataSize;
512     m_dataOffset                          = m_decodeParams.m_dataOffset;
513     m_numSlices                           = m_decodeParams.m_numSlices;
514     m_picParams                           = (CodecDecodeMpeg2PicParams *)m_decodeParams.m_picParams;
515     m_sliceParams                         = (CodecDecodeMpeg2SliceParams *)m_decodeParams.m_sliceParams;
516     m_iqMatrixBuffer                      = (CodecMpeg2IqMatrix *)m_decodeParams.m_iqMatrixBuffer;
517     m_destSurface                         = *m_decodeParams.m_destSurface;
518     m_resDataBuffer                       = *m_decodeParams.m_dataBuffer;
519     m_numMacroblocks                      = m_decodeParams.m_numMacroblocks;
520     m_mbParams                            = (CodecDecodeMpeg2MbParmas *)m_decodeParams.m_macroblockParams;
521     m_mpeg2ISliceConcealmentMode          = m_decodeParams.m_mpeg2ISliceConcealmentMode;
522     m_mpeg2PbSliceConcealmentMode         = m_decodeParams.m_mpeg2PBSliceConcealmentMode;
523     m_mpeg2PbSlicePredBiDirMvTypeOverride = m_decodeParams.m_mpeg2PBSlicePredBiDirMVTypeOverride;
524     m_mpeg2PbSlicePredMvOverride          = m_decodeParams.m_mpeg2PBSlicePredMVOverride;
525 
526     m_picWidthInMb  = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_picParams->m_horizontalSize);
527     m_picHeightInMb = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_picParams->m_verticalSize);
528 
529     // For some corrupted mpeg2 streams, need to use dwHeight or dwWidth because they are updated at decode create time.
530     // Horizontal_size or vertical_size may be different and wrong in first pic parameter.
531     totalMBInFrame = (m_picParams->m_currPic.PicFlags == PICTURE_FRAME) ? (CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_width) * CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_height))
532                                                                         : (CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_width) * CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_height) / 2);
533 
534     if (m_numSlices > totalMBInFrame)
535     {
536         CODECHAL_DECODE_ASSERTMESSAGE("Invalid slice number due to larger than MB number.");
537         return MOS_STATUS_INVALID_PARAMETER;
538     }
539 
540     PCODEC_REF_LIST destEntry = m_mpeg2RefList[m_picParams->m_currPic.FrameIdx];
541     MOS_ZeroMemory(destEntry, sizeof(CODEC_REF_LIST));
542     destEntry->RefPic    = m_picParams->m_currPic;
543     destEntry->resRefPic = m_destSurface.OsResource;
544 
545     m_statusReportFeedbackNumber = m_picParams->m_statusReportFeedbackNumber;
546 
547     MOS_ZeroMemory(m_vldSliceRecord, (m_numSlices * sizeof(CODECHAL_VLD_SLICE_RECORD)));
548 
549     if (IsFirstExecuteCall())
550     {
551         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(InitializeBeginFrame(),
552             "Initial Beginframe in CodecHal failed.");
553     }
554 
555     uint32_t    firstMbAddress       = 0;
556     bool        skippedSlicePresent    = false;
557     bool        invalidFrame           = true;
558     uint32_t    numMBs               = 0;
559 
560     // Determine the number of MBs for MPEG2 VLD
561     if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD)
562     {
563         CODECHAL_DECODE_CHK_NULL_RETURN(m_sliceParams);
564 
565         CodecDecodeMpeg2SliceParams *slc = m_sliceParams;
566 
567         if (m_numSlices == 0)
568         {
569             CODECHAL_DECODE_ASSERTMESSAGE(
570                 "MPEG2 VLD slice data invalid, unable to determine final MB address.");
571             numMBs = m_lastMbAddress = 0;
572             return MOS_STATUS_INVALID_PARAMETER;
573         }
574         else
575         {
576             uint16_t lastSlice       = 0;
577             uint32_t prevSliceMbEnd        = m_lastMbAddress;
578             bool firstValidSlice       = m_incompletePicture ? true : false;
579 
580             for (uint16_t i = 0; i < m_numSlices; i++)
581             {
582                 uint32_t sliceStartMbOffset =
583                     slc->m_sliceHorizontalPosition +
584                     (slc->m_sliceVerticalPosition * m_picWidthInMb);
585 
586                 uint32_t slcLength = ((slc->m_sliceDataSize + 0x0007) >> 3);
587 
588                 // HW limitation and won't be fixed
589                 if (slcLength > 0x1FFE0)
590                 {
591                     slcLength = 0x1FFE0;
592                 }
593 
594                 uint32_t u32Offset = ((slc ->m_macroblockOffset & 0x0000fff8) >> 3); // #of bytes of header data in bitstream buffer (before video data)
595 
596                 slcLength                            -= u32Offset;
597                 m_vldSliceRecord[i].dwLength             = slcLength;
598                 m_vldSliceRecord[i].dwOffset             = u32Offset;
599                 m_vldSliceRecord[i].dwSliceStartMbOffset = sliceStartMbOffset;
600 
601                 if (DetectSliceError(i, prevSliceMbEnd, firstValidSlice))
602                 {
603                     m_vldSliceRecord[i].dwSkip = true;
604                     skippedSlicePresent        = true;
605                 }
606                 else
607                 {
608                     if (firstValidSlice)
609                     {
610                         // First MB Address
611                         firstMbAddress =
612                             slc->m_sliceHorizontalPosition +
613                             (slc->m_sliceVerticalPosition * m_picWidthInMb);
614                     }
615 
616                     lastSlice = i;
617                     firstValidSlice = false;
618                     invalidFrame = false;
619                 }
620 
621                 prevSliceMbEnd =
622                     m_vldSliceRecord[i].dwSliceStartMbOffset +
623                     slc->m_numMbsForSlice;
624 
625                 slc++;
626             }
627 
628             slc -= m_numSlices;
629             m_vldSliceRecord[lastSlice].bIsLastSlice = true;
630 
631             // Last MB Address
632             slc += lastSlice;
633 
634             numMBs =
635                 (uint16_t)(m_vldSliceRecord[lastSlice].dwSliceStartMbOffset +
636                            slc->m_numMbsForSlice);
637         }
638     }
639     else if (m_mode == CODECHAL_DECODE_MODE_MPEG2IDCT)
640     {
641         CODECHAL_DECODE_CHK_NULL_RETURN(m_mbParams);
642         numMBs = m_numMacroblocks;
643     }
644 
645     // It means all slices in the frame are wrong, we just need skip decoding for this frame
646     // and don't insert any dummy slices
647     if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD &&
648         invalidFrame && m_numSlices && !m_incompletePicture)
649     {
650         CODECHAL_DECODE_ASSERTMESSAGE("Current frame is invalid.");
651         return MOS_STATUS_UNKNOWN;
652     }
653 
654     // MPEG2 Error Concealment for Gen6+
655     // Applicable for both IT and VLD modes
656     bool copiedDataNeeded = (m_incompletePicture ||
657                              (numMBs != (m_picWidthInMb * m_picHeightInMb)));
658 
659     if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD)
660     {
661         copiedDataNeeded |= (skippedSlicePresent || firstMbAddress);
662     }
663 
664     if (copiedDataNeeded)
665     {
666         if (m_dataSize)
667         {
668             CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface(
669                 m_dataSize,
670                 m_resDataBuffer,
671                 &m_resCopiedDataBuffer[m_currCopiedData],
672                 &m_copiedDataOffset));
673         }
674 
675         m_copiedDataBufferInUse = true;
676     }
677 
678     m_perfType = (uint16_t)m_picParams->m_pictureCodingType;
679 
680     m_crrPic      = m_picParams->m_currPic;
681     m_secondField = m_picParams->m_secondField ? true : false;
682 
683     CODECHAL_DEBUG_TOOL(
684         CODECHAL_DECODE_CHK_NULL_RETURN(m_debugInterface);
685         m_debugInterface->m_currPic     = m_crrPic;
686         m_debugInterface->m_secondField = m_secondField;
687         m_debugInterface->m_frameType   = m_perfType;
688 
689         if (m_picParams) {
690             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpPicParams(
691                 m_picParams));
692         }
693 
694         if (m_iqMatrixBuffer) {
695             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpIQParams(
696                 m_iqMatrixBuffer));
697         }
698 
699         if (m_sliceParams) {
700             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpSliceParams(
701                 m_sliceParams,
702                 m_numSlices));
703         }
704 
705         if (m_mbParams) {
706             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpMbParams(
707                 m_mbParams));
708         }
709 
710     )
711 
712     return eStatus;
713 }
714 
DecodeStateLevel()715 MOS_STATUS CodechalDecodeMpeg2::DecodeStateLevel()
716 {
717     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
718 
719     CODECHAL_DECODE_FUNCTION_ENTER;
720 
721     uint8_t fwdRefIdx = (uint8_t)m_picParams->m_forwardRefIdx;
722     uint8_t bwdRefIdx = (uint8_t)m_picParams->m_backwardRefIdx;
723 
724     // Do not use data that has not been initialized
725     if (CodecHal_PictureIsInvalid(m_mpeg2RefList[fwdRefIdx]->RefPic))
726     {
727         fwdRefIdx = m_picParams->m_currPic.FrameIdx;
728     }
729     if (CodecHal_PictureIsInvalid(m_mpeg2RefList[bwdRefIdx]->RefPic))
730     {
731         bwdRefIdx = m_picParams->m_currPic.FrameIdx;
732     }
733 
734     MOS_COMMAND_BUFFER cmdBuffer;
735     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
736 
737     auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
738     HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
739 
740     MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
741     pipeModeSelectParams.Mode                  = m_mode;
742     pipeModeSelectParams.bStreamOutEnabled     = m_streamOutEnabled;
743     pipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled;
744     pipeModeSelectParams.bPreDeblockOutEnable  = !m_deblockingEnabled;
745 
746     MHW_VDBOX_SURFACE_PARAMS surfaceParams;
747     MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
748     surfaceParams.Mode                      = m_mode;
749     surfaceParams.psSurface                 = &m_destSurface;
750 
751     MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
752     pipeBufAddrParams.Mode                      = m_mode;
753     if (m_deblockingEnabled)
754     {
755         pipeBufAddrParams.psPostDeblockSurface = &m_destSurface;
756     }
757     else
758     {
759         pipeBufAddrParams.psPreDeblockSurface = &m_destSurface;
760     }
761 
762 #ifdef _MMC_SUPPORTED
763     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams));
764 #endif
765 
766     // when there is not a forward or backward reference,
767     // the index is set to the destination frame index
768     m_presReferences[CodechalDecodeFwdRefTop] =
769         m_presReferences[CodechalDecodeFwdRefBottom] =
770             m_presReferences[CodechalDecodeBwdRefTop] =
771                 m_presReferences[CodechalDecodeBwdRefBottom] = &m_destSurface.OsResource;
772 
773     if (fwdRefIdx < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
774     {
775         m_presReferences[CodechalDecodeFwdRefTop] =
776             m_presReferences[CodechalDecodeFwdRefBottom] = &m_mpeg2RefList[fwdRefIdx]->resRefPic;
777     }
778     if (bwdRefIdx < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
779     {
780         m_presReferences[CodechalDecodeBwdRefTop] =
781             m_presReferences[CodechalDecodeBwdRefBottom] = &m_mpeg2RefList[bwdRefIdx]->resRefPic;
782     }
783 
784     // special case for second fields
785     if (m_picParams->m_secondField && m_picParams->m_pictureCodingType == P_TYPE)
786     {
787         if (m_picParams->m_topFieldFirst)
788         {
789             m_presReferences[CodechalDecodeFwdRefTop] =
790                 &m_destSurface.OsResource;
791         }
792         else
793         {
794             m_presReferences[CodechalDecodeFwdRefBottom] =
795                 &m_destSurface.OsResource;
796         }
797     }
798 
799     // set all ref pic addresses to valid addresses for error concealment purpose
800     for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
801     {
802         if (m_presReferences[i] == nullptr &&
803             MEDIA_IS_WA(m_waTable, WaDummyReference) &&
804             !Mos_ResourceIsNull(&m_dummyReference.OsResource))
805         {
806             m_presReferences[i] = &m_dummyReference.OsResource;
807         }
808     }
809 
810     CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
811         pipeBufAddrParams.presReferences,
812         sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC,
813         m_presReferences,
814         sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC));
815 
816     pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
817         &m_resMfdDeblockingFilterRowStoreScratchBuffer;
818 
819     if (m_streamOutEnabled)
820     {
821         pipeBufAddrParams.presStreamOutBuffer =
822             &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
823     }
824 
825 #ifdef _MMC_SUPPORTED
826     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&pipeBufAddrParams));
827 #endif
828 
829     CODECHAL_DEBUG_TOOL(
830         for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
831         {
832             if (pipeBufAddrParams.presReferences[i])
833             {
834                 MOS_SURFACE dstSurface;
835 
836                 MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
837                 dstSurface.Format     = Format_NV12;
838                 dstSurface.OsResource = *(pipeBufAddrParams.presReferences[i]);
839                 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
840                     m_osInterface,
841                     &dstSurface));
842 
843                 m_debugInterface->m_refIndex = (uint16_t)i;
844                 std::string refSurfName      = "RefSurf" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex));
845                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
846                     &dstSurface,
847                     CodechalDbgAttr::attrReferenceSurfaces,
848                     refSurfName.data()));
849             }
850         }
851     )
852 
853     //set correctly indirect BSD object base address.
854     PMOS_RESOURCE indObjBase;
855     if (m_copiedDataBufferInUse)
856     {
857         indObjBase = &m_resCopiedDataBuffer[m_currCopiedData];
858     }
859     else
860     {
861         indObjBase = &m_resDataBuffer;
862     }
863 
864     MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
865     MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
866     indObjBaseAddrParams.Mode               = m_mode;
867     indObjBaseAddrParams.dwDataSize =
868         m_copiedDataBufferInUse ? m_copiedDataBufferSize : m_dataSize;
869     indObjBaseAddrParams.presDataBuffer     = indObjBase;
870 
871     MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams;
872     MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
873     bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer;
874 
875     MHW_VDBOX_MPEG2_PIC_STATE mpeg2PicState;
876     mpeg2PicState.Mode                                  = m_mode;
877     mpeg2PicState.pMpeg2PicParams                       = m_picParams;
878     mpeg2PicState.bDeblockingEnabled                    = m_deblockingEnabled;
879     mpeg2PicState.dwMPEG2ISliceConcealmentMode          = m_mpeg2ISliceConcealmentMode;
880     mpeg2PicState.dwMPEG2PBSliceConcealmentMode         = m_mpeg2PbSliceConcealmentMode;
881     mpeg2PicState.dwMPEG2PBSlicePredBiDirMVTypeOverride = m_mpeg2PbSlicePredBiDirMvTypeOverride;
882     mpeg2PicState.dwMPEG2PBSlicePredMVOverride          = m_mpeg2PbSlicePredMvOverride;
883 
884     MHW_VDBOX_QM_PARAMS qmParams;
885     qmParams.Standard                       = CODECHAL_MPEG2;
886     qmParams.pMpeg2IqMatrix                 = m_iqMatrixBuffer;
887 
888     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
889         &cmdBuffer, true));
890 
891     if (m_statusQueryReportingEnabled)
892     {
893         CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(
894             &cmdBuffer));
895     }
896 
897     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(
898         &cmdBuffer,
899         &pipeModeSelectParams));
900 
901     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(
902         &cmdBuffer,
903         &surfaceParams));
904 
905     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(
906         &cmdBuffer,
907         &pipeBufAddrParams));
908 
909     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(
910         &cmdBuffer,
911         &indObjBaseAddrParams));
912 
913     if (CodecHalIsDecodeModeVLD(m_mode))
914     {
915         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(
916             &cmdBuffer,
917             &bspBufBaseAddrParams));
918     }
919 
920     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxMpeg2PicCmd(
921         &cmdBuffer,
922         &mpeg2PicState));
923 
924     if (CodecHalIsDecodeModeVLD(m_mode))
925     {
926         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(
927             &cmdBuffer,
928             &qmParams));
929     }
930 
931     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
932 
933     return eStatus;
934 }
935 
DecodePrimitiveLevel()936 MOS_STATUS CodechalDecodeMpeg2::DecodePrimitiveLevel()
937 {
938     if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD)
939     {
940         return SliceLevel();
941     }
942     else
943     {
944         return MacroblockLevel();
945     }
946 }
947 
SliceLevel()948 MOS_STATUS CodechalDecodeMpeg2::SliceLevel()
949 {
950     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
951 
952     CODECHAL_DECODE_FUNCTION_ENTER;
953 
954     if ((m_decodePhantomMbs) || (m_incompletePicture))
955     {
956         if (m_bbInUsePerFrame >= m_bbAllocated / CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP)
957         {
958             m_bbAllocated += CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP;
959             if (m_bbAllocated >= CODECHAL_DECODE_MPEG2_MAXIMUM_BATCH_BUFFERS)
960             {
961                 CODECHAL_DECODE_ASSERTMESSAGE(
962                     "The number of MPEG2 second level batch buffer is not big enough to hold the whole frame.");
963                 return MOS_STATUS_EXCEED_MAX_BB_SIZE;
964             }
965 
966             for (uint32_t i = 0; i < CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP; i++)
967             {
968                 uint32_t j = m_bbAllocated - i - 1;
969                 MOS_ZeroMemory(&m_mediaObjectBatchBuffer[j], sizeof(MHW_BATCH_BUFFER));
970 
971                 uint32_t u32Size = m_standardDecodeSizeNeeded * CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_width) * CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_height) +
972                     m_hwInterface->m_sizeOfCmdBatchBufferEnd;
973 
974                 CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
975                     m_osInterface,
976                     &m_mediaObjectBatchBuffer[j],
977                     nullptr,
978                     u32Size));
979                 m_mediaObjectBatchBuffer[j].bSecondLevel = true;
980             }
981         }
982     }
983 
984     MOS_COMMAND_BUFFER cmdBuffer;
985     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
986         m_osInterface,
987         &cmdBuffer,
988         0));
989 
990     MHW_BATCH_BUFFER batchBuffer = m_mediaObjectBatchBuffer[m_bbInUse];
991 
992     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
993         &cmdBuffer,
994         &batchBuffer));
995 
996     CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_LockBb(
997         m_osInterface,
998         &batchBuffer));
999 
1000     if (m_decodePhantomMbs)
1001     {
1002         CODECHAL_DECODE_CHK_STATUS_RETURN(InsertDummySlices(
1003             &batchBuffer,
1004             m_lastMbAddress,
1005             m_picWidthInMb * m_picHeightInMb));
1006     }
1007     else
1008     {
1009         CodecDecodeMpeg2SliceParams *slc = m_sliceParams;
1010 
1011         uint16_t prevSliceMBEnd = m_lastMbAddress;
1012 
1013         for (uint16_t slcCount = 0; slcCount < m_numSlices; slcCount++)
1014         {
1015             if (!m_vldSliceRecord[slcCount].dwSkip)
1016             {
1017                 if (prevSliceMBEnd != m_vldSliceRecord[slcCount].dwSliceStartMbOffset)
1018                 {
1019                     CODECHAL_DECODE_CHK_STATUS_RETURN(InsertDummySlices(
1020                         &batchBuffer,
1021                         prevSliceMBEnd,
1022                         (uint16_t)m_vldSliceRecord[slcCount].dwSliceStartMbOffset));
1023                 }
1024 
1025                 if (m_vldSliceRecord[slcCount].bIsLastSlice)
1026                 {
1027                     uint16_t expectedFinalMb = m_picWidthInMb * m_picHeightInMb;
1028 
1029                     m_lastMbAddress =
1030                         (uint16_t)(m_vldSliceRecord[slcCount].dwSliceStartMbOffset +
1031                                    slc->m_numMbsForSlice);
1032 
1033                     if (m_lastMbAddress < expectedFinalMb)
1034                     {
1035                         m_incompletePicture              = true;
1036                         m_vldSliceRecord[slcCount].bIsLastSlice = false;
1037                     }
1038                     else
1039                     {
1040                         //Indicate It's complete picture now
1041                         m_incompletePicture              = false;
1042                     }
1043                 }
1044 
1045                 // static MPEG2 slice parameters
1046                 MHW_VDBOX_MPEG2_SLICE_STATE mpeg2SliceState;
1047                 mpeg2SliceState.presDataBuffer          = &m_resDataBuffer;
1048                 mpeg2SliceState.wPicWidthInMb           = m_picWidthInMb;
1049                 mpeg2SliceState.wPicHeightInMb          = m_picHeightInMb;
1050                 mpeg2SliceState.pMpeg2SliceParams       = slc;
1051                 mpeg2SliceState.dwLength                = m_vldSliceRecord[slcCount].dwLength;
1052                 mpeg2SliceState.dwOffset =
1053                     m_vldSliceRecord[slcCount].dwOffset + m_copiedDataOffset;
1054                 mpeg2SliceState.dwSliceStartMbOffset = m_vldSliceRecord[slcCount].dwSliceStartMbOffset;
1055                 mpeg2SliceState.bLastSlice           = m_vldSliceRecord[slcCount].bIsLastSlice;
1056 
1057                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdMpeg2BsdObject(
1058                     nullptr,
1059                     &batchBuffer,
1060                     &mpeg2SliceState));
1061 
1062                 prevSliceMBEnd =
1063                     (uint16_t)(m_vldSliceRecord[slcCount].dwSliceStartMbOffset +
1064                                slc->m_numMbsForSlice);
1065             }
1066 
1067             slc++;
1068         }
1069     }
1070 
1071     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1072         nullptr,
1073         &batchBuffer));
1074 
1075     CODECHAL_DEBUG_TOOL(
1076         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
1077             &batchBuffer,
1078             CODECHAL_NUM_MEDIA_STATES,
1079             "_DEC"));
1080     )
1081 
1082     CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_UnlockBb(
1083         m_osInterface,
1084         &batchBuffer,
1085         true));
1086 
1087     m_bbInUse = (m_bbInUse + 1) % m_bbAllocated;
1088     m_bbInUsePerFrame++;
1089 
1090     if (!m_incompletePicture)
1091     {
1092         // Check if destination surface needs to be synchronized
1093         MOS_SYNC_PARAMS syncParams          = g_cInitSyncParams;
1094         syncParams.GpuContext               = m_videoContext;
1095         syncParams.presSyncResource         = &m_destSurface.OsResource;
1096         syncParams.bReadOnly                = false;
1097         syncParams.bDisableDecodeSyncLock   = m_disableDecodeSyncLock;
1098         syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1099 
1100         if (!CodecHal_PictureIsField(m_picParams->m_currPic) ||
1101             !m_picParams->m_secondField)
1102         {
1103             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(
1104                 m_osInterface,
1105                 &syncParams));
1106             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(
1107                 m_osInterface,
1108                 &syncParams));
1109 
1110             // Update the resource tag (s/w tag) for On-Demand Sync
1111             m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1112         }
1113 
1114         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1115         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1116 
1117         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1118             &cmdBuffer,
1119             &flushDwParams));
1120 
1121         // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
1122         if (m_osInterface->bTagResourceSync &&
1123             (!CodecHal_PictureIsField(m_picParams->m_currPic) || m_picParams->m_secondField))
1124         {
1125             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
1126                 &cmdBuffer,
1127                 &syncParams));
1128         }
1129 
1130         if (m_statusQueryReportingEnabled)
1131         {
1132             CodechalDecodeStatusReport decodeStatusReport;
1133 
1134             decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
1135             decodeStatusReport.m_currDecodedPic     = m_picParams->m_currPic;
1136             decodeStatusReport.m_currDeblockedPic   = m_picParams->m_currPic;
1137             decodeStatusReport.m_codecStatus        = CODECHAL_STATUS_UNAVAILABLE;
1138             decodeStatusReport.m_currDecodedPicRes  = m_mpeg2RefList[m_picParams->m_currPic.FrameIdx]->resRefPic;
1139 
1140             CODECHAL_DEBUG_TOOL(
1141                 decodeStatusReport.m_secondField = m_picParams->m_secondField ? true : false;
1142                 decodeStatusReport.m_frameType   = m_perfType;)
1143 
1144             CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(
1145                 decodeStatusReport,
1146                 &cmdBuffer));
1147         }
1148 
1149         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1150             &cmdBuffer,
1151             nullptr));
1152 
1153         m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1154 
1155         CODECHAL_DEBUG_TOOL(
1156             CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1157                 &cmdBuffer,
1158                 CODECHAL_NUM_MEDIA_STATES,
1159                 "_DEC"));
1160 
1161             //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
1162             //    m_debugInterface,
1163             //    &cmdBuffer));
1164         )
1165 
1166         //Sync up complete frame
1167         syncParams                      = g_cInitSyncParams;
1168         syncParams.GpuContext           = m_videoContextForWa;
1169         syncParams.presSyncResource     = &m_resSyncObjectWaContextInUse;
1170 
1171         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1172 
1173         syncParams                      = g_cInitSyncParams;
1174         syncParams.GpuContext           = m_videoContext;
1175         syncParams.presSyncResource     = &m_resSyncObjectWaContextInUse;
1176 
1177         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1178 
1179         HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
1180 
1181         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
1182             m_osInterface,
1183             &cmdBuffer,
1184             m_videoContextUsesNullHw));
1185 
1186         CODECHAL_DEBUG_TOOL(
1187             m_mmc->UpdateUserFeatureKey(&m_destSurface);)
1188 
1189         if (m_statusQueryReportingEnabled)
1190         {
1191             CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(
1192                 m_videoContextUsesNullHw));
1193         }
1194 
1195         // Needs to be re-set for Linux buffer re-use scenarios
1196         m_mpeg2RefList[m_picParams->m_currPic.FrameIdx]->resRefPic =
1197             m_destSurface.OsResource;
1198 
1199         // Send the signal to indicate decode completion, in case On-Demand Sync is not present
1200         if (!CodecHal_PictureIsField(m_picParams->m_currPic) || m_picParams->m_secondField)
1201         {
1202             syncParams                      = g_cInitSyncParams;
1203             syncParams.GpuContext           = m_videoContext;
1204             syncParams.presSyncResource     = &m_destSurface.OsResource;
1205 
1206             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
1207         }
1208     }
1209     else
1210     {
1211         m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1212     }
1213 
1214     return eStatus;
1215 }
1216 
PackMotionVectors(CODEC_PICTURE_FLAG pic_flag,PMHW_VDBOX_MPEG2_MB_STATE mpeg2MbState)1217 void CodechalDecodeMpeg2::PackMotionVectors(
1218     CODEC_PICTURE_FLAG          pic_flag,
1219     PMHW_VDBOX_MPEG2_MB_STATE   mpeg2MbState)
1220 {
1221     CodecDecodeMpeg2MbParmas *mbParams = mpeg2MbState->pMBParams;
1222 
1223     uint16_t motionType     = mbParams->MBType.m_motionType;
1224     uint16_t intelMotionType = CODECHAL_MPEG2_IMT_NONE;
1225 
1226     //convert to Intel Motion Type
1227     if (pic_flag == PICTURE_FRAME)
1228     {
1229         switch(motionType)
1230         {
1231         case CodechalDecodeMcFrame:
1232             intelMotionType = CODECHAL_MPEG2_IMT_FRAME_FRAME;
1233             break;
1234         case CodechalDecodeMcField:
1235             intelMotionType = CODECHAL_MPEG2_IMT_FRAME_FIELD;
1236             break;
1237         case CodechalDecodeMcDmv:
1238             intelMotionType = CODECHAL_MPEG2_IMT_FRAME_DUAL_PRIME;
1239             break;
1240         default:
1241             break;
1242         }
1243     }
1244     else // must be field picture...
1245     {
1246         switch(motionType)
1247         {
1248         case CodechalDecodeMcField:
1249             intelMotionType = CODECHAL_MPEG2_IMT_FIELD_FIELD;
1250             break;
1251         case CodechalDecodeMcDmv:
1252             intelMotionType = CODECHAL_MPEG2_IMT_FIELD_DUAL_PRIME;
1253             break;
1254         case CodechalDecodeMc16x8:
1255             intelMotionType = CODECHAL_MPEG2_IMT_16X8;
1256             break;
1257         default:
1258             break;
1259         }
1260     }
1261 
1262     int16_t *mv = mbParams->m_motionVectors;
1263 
1264     switch (intelMotionType)
1265     {
1266     case CODECHAL_MPEG2_IMT_16X8:
1267     case CODECHAL_MPEG2_IMT_FIELD_FIELD:
1268     case CODECHAL_MPEG2_IMT_FRAME_FRAME:
1269     case CODECHAL_MPEG2_IMT_FIELD_DUAL_PRIME:
1270         mpeg2MbState->sPackedMVs0[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
1271         mpeg2MbState->sPackedMVs0[1] = (short)mv[CodechalDecodeRstFirstForwVert];
1272         mpeg2MbState->sPackedMVs0[2] = (short)mv[CodechalDecodeRstFirstBackHorz];
1273         mpeg2MbState->sPackedMVs0[3] = (short)mv[CodechalDecodeRstFirstBackVert];
1274         break;
1275 
1276     case CODECHAL_MPEG2_IMT_FRAME_FIELD:
1277     case CODECHAL_MPEG2_IMT_FRAME_DUAL_PRIME:
1278         mpeg2MbState->sPackedMVs0[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
1279         mpeg2MbState->sPackedMVs0[1] = (short)(mv[CodechalDecodeRstFirstForwVert] >> 1) ;
1280         mpeg2MbState->sPackedMVs0[2] = (short)mv[CodechalDecodeRstFirstBackHorz];
1281         mpeg2MbState->sPackedMVs0[3] = (short)(mv[CodechalDecodeRstFirstBackVert] >> 1);
1282         break;
1283 
1284     default:
1285         break;
1286     }
1287 
1288     switch (intelMotionType)
1289     {
1290     case CODECHAL_MPEG2_IMT_16X8:
1291         mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstSecndForwHorz];
1292         mpeg2MbState->sPackedMVs1[1] = (short)mv[CodechalDecodeRstSecndForwVert];
1293         mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
1294         mpeg2MbState->sPackedMVs1[3] = (short)mv[CodechalDecodeRstSecndBackVert];
1295         break;
1296 
1297     case CODECHAL_MPEG2_IMT_FRAME_DUAL_PRIME:
1298         mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
1299         mpeg2MbState->sPackedMVs1[1] = (short)(mv[CodechalDecodeRstFirstForwVert] >> 1);
1300         mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
1301         mpeg2MbState->sPackedMVs1[3] = (short)(mv[CodechalDecodeRstSecndBackVert] >> 1);
1302         break;
1303 
1304     case CODECHAL_MPEG2_IMT_FRAME_FIELD:
1305         mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstSecndForwHorz];
1306         mpeg2MbState->sPackedMVs1[1] = (short)(mv[CodechalDecodeRstSecndForwVert] >> 1);
1307         mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
1308         mpeg2MbState->sPackedMVs1[3] = (short)(mv[CodechalDecodeRstSecndBackVert] >> 1);
1309         break;
1310 
1311     default:
1312         break;
1313     }
1314 }
InsertSkippedMacroblocks(PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_MPEG2_MB_STATE params,uint16_t nextMBStart,uint16_t skippedMBs)1315 MOS_STATUS CodechalDecodeMpeg2::InsertSkippedMacroblocks(
1316     PMHW_BATCH_BUFFER               batchBuffer,
1317     PMHW_VDBOX_MPEG2_MB_STATE       params,
1318     uint16_t                        nextMBStart,
1319     uint16_t                        skippedMBs)
1320 {
1321     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1322 
1323     CODECHAL_DECODE_FUNCTION_ENTER;
1324 
1325     CODECHAL_DECODE_CHK_NULL_RETURN(batchBuffer);
1326     CODECHAL_DECODE_CHK_NULL_RETURN(params);
1327     CODECHAL_DECODE_CHK_NULL_RETURN(params->pMBParams);
1328 
1329     //save the original MB params, and restore the orignal MB params when function exit.
1330     CodechalDecodeRestoreData<CodecDecodeMpeg2MbParmas> MBParamsRestore(params->pMBParams);
1331 
1332     params->dwDCTLength                    = 0;
1333     params->dwITCoffDataAddrOffset         = 0;
1334     params->pMBParams->m_codedBlockPattern  = 0;
1335 
1336     MOS_ZeroMemory(params->sPackedMVs0,sizeof(params->sPackedMVs0));
1337     MOS_ZeroMemory(params->sPackedMVs1,sizeof(params->sPackedMVs1));
1338 
1339     for (uint16_t i = 0; i < skippedMBs; i++)
1340     {
1341         params->pMBParams->m_mbAddr = nextMBStart + i;
1342         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdMpeg2ITObject(
1343             nullptr,
1344             batchBuffer,
1345             params));
1346     }
1347 
1348     return eStatus;
1349 }
1350 
MacroblockLevel()1351 MOS_STATUS CodechalDecodeMpeg2::MacroblockLevel()
1352 {
1353     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1354 
1355     CODECHAL_DECODE_FUNCTION_ENTER;
1356 
1357     if ((m_decodePhantomMbs) || (m_incompletePicture))
1358     {
1359         if (m_bbInUsePerFrame >= m_bbAllocated / CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP)
1360         {
1361             m_bbAllocated += CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP;
1362             if (m_bbAllocated >= CODECHAL_DECODE_MPEG2_MAXIMUM_BATCH_BUFFERS)
1363             {
1364                 CODECHAL_DECODE_ASSERTMESSAGE(
1365                     "The number of MPEG2 second level batch buffer is not big enough to hold the whole frame.");
1366                 return MOS_STATUS_EXCEED_MAX_BB_SIZE;
1367             }
1368 
1369             for (uint32_t i = 0; i < CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP; i++)
1370             {
1371                 uint32_t j = m_bbAllocated - i - 1;
1372                 MOS_ZeroMemory(&m_mediaObjectBatchBuffer[j], sizeof(MHW_BATCH_BUFFER));
1373 
1374                 uint32_t u32Size = m_standardDecodeSizeNeeded * m_picWidthInMb * m_picHeightInMb +
1375                                    m_hwInterface->m_sizeOfCmdBatchBufferEnd;
1376 
1377                 CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
1378                     m_osInterface,
1379                     &m_mediaObjectBatchBuffer[j],
1380                     nullptr,
1381                     u32Size));
1382                 m_mediaObjectBatchBuffer[j].bSecondLevel = true;
1383             }
1384         }
1385     }
1386 
1387     MOS_COMMAND_BUFFER cmdBuffer;
1388     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
1389         m_osInterface,
1390         &cmdBuffer,
1391         0));
1392 
1393     MHW_BATCH_BUFFER batchBuffer = m_mediaObjectBatchBuffer[m_bbInUse];
1394 
1395     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
1396         &cmdBuffer,
1397         &batchBuffer));
1398 
1399     CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_LockBb(m_osInterface, &batchBuffer));
1400 
1401     //static member
1402     MHW_VDBOX_MPEG2_MB_STATE    mpeg2MbState;
1403     mpeg2MbState.wPicWidthInMb  = m_picWidthInMb;
1404     mpeg2MbState.wPicHeightInMb = m_picHeightInMb;
1405     mpeg2MbState.wPicCodingType = (uint16_t)m_picParams->m_pictureCodingType;
1406 
1407     if (m_decodePhantomMbs)
1408     {
1409         uint16_t u16NextMBStart = m_savedMpeg2MbParam.m_mbAddr + 1;  // = 1 + saved last MB's address in this picture.
1410         uint16_t numMBs      = (mpeg2MbState.wPicWidthInMb * mpeg2MbState.wPicHeightInMb) - u16NextMBStart;
1411 
1412         mpeg2MbState.pMBParams = &m_savedMpeg2MbParam;  //use saved last MB param to insert Skipped MBs.
1413         CODECHAL_DECODE_CHK_STATUS_RETURN(InsertSkippedMacroblocks(
1414             &batchBuffer,
1415             &mpeg2MbState,
1416             u16NextMBStart,
1417             numMBs));
1418         m_incompletePicture = false;
1419     }
1420     else
1421     {
1422         uint16_t expectedMBAddress = (m_incompletePicture) ? m_lastMbAddress : 0;
1423 
1424         for (uint16_t mbcount = 0; mbcount < m_numMacroblocks; mbcount++)
1425         {
1426             if (m_mbParams[mbcount].m_mbAddr >= expectedMBAddress)
1427             {
1428                 uint16_t skippedMBs = m_mbParams[mbcount].m_mbAddr - expectedMBAddress;
1429 
1430                 if (skippedMBs)
1431                 {
1432                     //insert skipped Macroblock, use the first available MB params to insert skipped MBs.
1433                     mpeg2MbState.pMBParams = &(m_mbParams[mbcount]);
1434                     CODECHAL_DECODE_CHK_STATUS_RETURN(InsertSkippedMacroblocks(
1435                         &batchBuffer,
1436                         &mpeg2MbState,
1437                         expectedMBAddress,
1438                         skippedMBs));
1439                 }
1440             }
1441 
1442             //common field for MBs in I picture and PB picture .
1443             mpeg2MbState.pMBParams   = &m_mbParams[mbcount];
1444             mpeg2MbState.dwDCTLength = 0;
1445             for (uint32_t i = 0; i < CODEC_NUM_BLOCK_PER_MB; i++)
1446             {
1447                 mpeg2MbState.dwDCTLength += m_mbParams[mbcount].m_numCoeff[i];
1448             }
1449 
1450             mpeg2MbState.dwITCoffDataAddrOffset = m_copiedDataOffset + (m_mbParams[mbcount].m_mbDataLoc << 2);  // byte offset
1451 
1452             //only for MB in PB picture.
1453             if (mpeg2MbState.wPicCodingType != I_TYPE)
1454             {
1455                 bool intraMB = mpeg2MbState.pMBParams->MBType.m_intraMb? true: false;
1456 
1457                 MOS_ZeroMemory(mpeg2MbState.sPackedMVs0,sizeof(mpeg2MbState.sPackedMVs0));
1458                 MOS_ZeroMemory(mpeg2MbState.sPackedMVs1,sizeof(mpeg2MbState.sPackedMVs1));
1459                 if ((!intraMB) && (mpeg2MbState.pMBParams->MBType.m_value &
1460                     (CODECHAL_DECODE_MPEG2_MB_MOTION_BACKWARD | CODECHAL_DECODE_MPEG2_MB_MOTION_FORWARD)))
1461                 {
1462                     PackMotionVectors(m_picParams->m_currPic.PicFlags, &mpeg2MbState);
1463                 }
1464             }
1465 
1466             // add IT OBJECT command for each macroblock
1467             CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdMpeg2ITObject(
1468                 nullptr,
1469                 &batchBuffer,
1470                 &mpeg2MbState));
1471 
1472             if (mpeg2MbState.wPicCodingType != I_TYPE && m_mbParams[mbcount].m_mbSkipFollowing)
1473             {
1474                 uint16_t skippedMBs    = m_mbParams[mbcount].m_mbSkipFollowing;
1475                 uint16_t skippedMBSart = m_mbParams[mbcount].m_mbAddr + 1;
1476 
1477                 // Insert Skipped MBs
1478                 CODECHAL_DECODE_CHK_STATUS_RETURN(InsertSkippedMacroblocks(
1479                     &batchBuffer,
1480                     &mpeg2MbState,
1481                     skippedMBSart,
1482                     skippedMBs));
1483 
1484                 m_mbParams[mbcount].m_mbAddr += skippedMBs;
1485             }
1486 
1487             //save the last MB's parameters for later use to insert skipped MBs.
1488             m_savedMpeg2MbParam = m_mbParams[mbcount];
1489 
1490             expectedMBAddress = m_mbParams[mbcount].m_mbAddr + 1;
1491 
1492             // insert extra MBs to ensure expected number of MBs sent to HW
1493             if (mbcount + 1 == m_numMacroblocks)
1494             {
1495                 uint16_t expectedFinalMB = m_picWidthInMb * m_picHeightInMb;
1496 
1497                 if (expectedMBAddress != expectedFinalMB)
1498                 {
1499                     m_incompletePicture = true;
1500                     m_lastMbAddress     = expectedMBAddress;
1501                 }
1502                 else
1503                 {
1504                     m_incompletePicture = false;
1505                 }
1506             }
1507         }
1508     }
1509 
1510     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1511         nullptr,
1512         &batchBuffer));
1513 
1514     CODECHAL_DEBUG_TOOL(
1515         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
1516             &batchBuffer,
1517             CODECHAL_NUM_MEDIA_STATES,
1518             "_DEC"));
1519     )
1520 
1521     CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_UnlockBb(m_osInterface, &batchBuffer, true));
1522 
1523     m_bbInUse = (m_bbInUse + 1) % m_bbAllocated;
1524     m_bbInUsePerFrame++;
1525 
1526     if (!m_incompletePicture)
1527     {
1528         // Check if destination surface needs to be synchronized
1529         MOS_SYNC_PARAMS syncParams          = g_cInitSyncParams;
1530         syncParams.GpuContext               = m_videoContext;
1531         syncParams.presSyncResource         = &m_destSurface.OsResource;
1532         syncParams.bReadOnly                = false;
1533         syncParams.bDisableDecodeSyncLock   = m_disableDecodeSyncLock;
1534         syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1535 
1536         if (!CodecHal_PictureIsField(m_picParams->m_currPic) ||
1537             !m_picParams->m_secondField)
1538         {
1539             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(
1540                 m_osInterface,
1541                 &syncParams));
1542             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(
1543                 m_osInterface,
1544                 &syncParams));
1545 
1546             // Update the resource tag (s/w tag) for On-Demand Sync
1547             m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1548         }
1549 
1550         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1551         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1552 
1553         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1554             &cmdBuffer,
1555             &flushDwParams));
1556 
1557         // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
1558         if (m_osInterface->bTagResourceSync &&
1559             (!CodecHal_PictureIsField(m_picParams->m_currPic) || m_picParams->m_secondField))
1560         {
1561             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
1562                 &cmdBuffer,
1563                 &syncParams));
1564         }
1565 
1566         if (m_statusQueryReportingEnabled)
1567         {
1568             CodechalDecodeStatusReport decodeStatusReport;
1569 
1570             decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
1571             decodeStatusReport.m_currDecodedPic     = m_picParams->m_currPic;
1572             decodeStatusReport.m_currDeblockedPic   = m_picParams->m_currPic;
1573             decodeStatusReport.m_codecStatus        = CODECHAL_STATUS_UNAVAILABLE;
1574             decodeStatusReport.m_currDecodedPicRes =
1575                 m_mpeg2RefList[m_picParams->m_currPic.FrameIdx]->resRefPic;
1576 
1577             CODECHAL_DEBUG_TOOL(
1578                 decodeStatusReport.m_secondField = m_picParams->m_secondField ? true : false;
1579                 decodeStatusReport.m_frameType   = m_perfType;)
1580 
1581             CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(
1582                 decodeStatusReport,
1583                 &cmdBuffer));
1584         }
1585 
1586         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1587             &cmdBuffer,
1588             nullptr));
1589 
1590         m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1591 
1592         CODECHAL_DEBUG_TOOL(
1593         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1594             &cmdBuffer,
1595             CODECHAL_NUM_MEDIA_STATES,
1596             "_DEC"));
1597 
1598         //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
1599         //    m_debugInterface,
1600         //    &cmdBuffer));
1601         )
1602 
1603         //Sync up complete frame
1604         syncParams                      = g_cInitSyncParams;
1605         syncParams.GpuContext           = m_videoContextForWa;
1606         syncParams.presSyncResource     = &m_resSyncObjectWaContextInUse;
1607 
1608         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1609 
1610         syncParams                      = g_cInitSyncParams;
1611         syncParams.GpuContext           = m_videoContext;
1612         syncParams.presSyncResource     = &m_resSyncObjectWaContextInUse;
1613 
1614         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1615 
1616         HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
1617 
1618         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
1619             m_osInterface,
1620             &cmdBuffer,
1621             m_videoContextUsesNullHw));
1622 
1623         CODECHAL_DEBUG_TOOL(
1624             m_mmc->UpdateUserFeatureKey(&m_destSurface);)
1625 
1626         if (m_statusQueryReportingEnabled)
1627         {
1628             CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(
1629                 m_videoContextUsesNullHw));
1630         }
1631 
1632         // Needs to be re-set for Linux buffer re-use scenarios
1633         m_mpeg2RefList[m_picParams->m_currPic.FrameIdx]->resRefPic = m_destSurface.OsResource;
1634 
1635         // Send the signal to indicate decode completion, in case On-Demand Sync is not present
1636         if (!CodecHal_PictureIsField(m_picParams->m_currPic) || m_picParams->m_secondField)
1637         {
1638             syncParams                      = g_cInitSyncParams;
1639             syncParams.GpuContext           = m_videoContext;
1640             syncParams.presSyncResource     = &m_destSurface.OsResource;
1641 
1642             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
1643         }
1644     }
1645     else
1646     {
1647         m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1648     }
1649 
1650     return eStatus;
1651 }
1652 
InitMmcState()1653 MOS_STATUS CodechalDecodeMpeg2::InitMmcState()
1654 {
1655 #ifdef _MMC_SUPPORTED
1656     m_mmc = MOS_New(CodechalMmcDecodeMpeg2, m_hwInterface, this);
1657     CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
1658 #endif
1659     return MOS_STATUS_SUCCESS;
1660 }
1661 
AllocateStandard(CodechalSetting * settings)1662 MOS_STATUS CodechalDecodeMpeg2::AllocateStandard (
1663     CodechalSetting *settings)
1664 {
1665     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1666 
1667     CODECHAL_DECODE_FUNCTION_ENTER;
1668 
1669     CODECHAL_DECODE_CHK_NULL_RETURN(settings);
1670 
1671     CODECHAL_DECODE_CHK_STATUS_RETURN(InitMmcState());
1672 
1673     m_width                         = settings->width;
1674     m_height                        = settings->height;
1675     m_picWidthInMb                  = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_width);
1676     m_picHeightInMb                 = (uint16_t)CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_height);
1677     m_bbAllocated                   = CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP;
1678 
1679     // Picture Level Commands
1680     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetMfxStateCommandsDataSize(
1681         m_mode,
1682         &m_commandBufferSizeNeeded,
1683         &m_commandPatchListSizeNeeded,
1684         0));
1685 
1686     // Primitive Level Commands
1687     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetMfxPrimitiveCommandsDataSize(
1688         m_mode,
1689         &m_standardDecodeSizeNeeded,
1690         &m_standardDecodePatchListSizeNeeded,
1691         0));
1692 
1693     CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResources());
1694 
1695     return eStatus;
1696 }
1697 
CodechalDecodeMpeg2(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)1698 CodechalDecodeMpeg2::CodechalDecodeMpeg2 (
1699     CodechalHwInterface   *hwInterface,
1700     CodechalDebugInterface* debugInterface,
1701     PCODECHAL_STANDARD_INFO standardInfo) :
1702     CodechalDecode(hwInterface, debugInterface, standardInfo)
1703 {
1704     CODECHAL_DECODE_FUNCTION_ENTER;
1705 
1706     MOS_ZeroMemory(&m_destSurface, sizeof(m_destSurface));
1707     MOS_ZeroMemory(m_presReferences, sizeof(m_presReferences));
1708     MOS_ZeroMemory(&m_resDataBuffer, sizeof(m_resDataBuffer));
1709     MOS_ZeroMemory(&m_resMfdDeblockingFilterRowStoreScratchBuffer, sizeof(m_resMfdDeblockingFilterRowStoreScratchBuffer));
1710     MOS_ZeroMemory(&m_resBsdMpcRowStoreScratchBuffer, sizeof(m_resBsdMpcRowStoreScratchBuffer));
1711     MOS_ZeroMemory(m_mpeg2RefList, sizeof(m_mpeg2RefList));
1712     MOS_ZeroMemory(m_mediaObjectBatchBuffer, sizeof(m_mediaObjectBatchBuffer));
1713     MOS_ZeroMemory(&m_resMpeg2DummyBistream, sizeof(m_resMpeg2DummyBistream));
1714     MOS_ZeroMemory(m_resCopiedDataBuffer, sizeof(m_resCopiedDataBuffer));
1715     MOS_ZeroMemory(&m_resSyncObjectWaContextInUse, sizeof(m_resSyncObjectWaContextInUse));
1716     MOS_ZeroMemory(&m_resSyncObjectVideoContextInUse, sizeof(m_resSyncObjectVideoContextInUse));
1717     MOS_ZeroMemory(&m_savedMpeg2MbParam, sizeof(m_savedMpeg2MbParam));
1718 #if (_DEBUG || _RELEASE_INTERNAL)
1719     m_reportFrameCrc = true;
1720 #endif
1721 }
1722 
1723 #if USE_CODECHAL_DEBUG_TOOL
DumpPicParams(CodecDecodeMpeg2PicParams * picParams)1724 MOS_STATUS CodechalDecodeMpeg2::DumpPicParams(
1725     CodecDecodeMpeg2PicParams *picParams)
1726 {
1727     CODECHAL_DEBUG_FUNCTION_ENTER;
1728 
1729     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
1730     {
1731         return MOS_STATUS_SUCCESS;
1732     }
1733 
1734     CODECHAL_DEBUG_CHK_NULL(picParams);
1735 
1736     std::ostringstream oss;
1737     oss.setf(std::ios::showbase | std::ios::uppercase);
1738 
1739     oss << "m_currPic FrameIdx: " << +picParams->m_currPic.FrameIdx << std::endl;
1740     oss << "m_currPic PicFlags: " << +picParams->m_currPic.PicFlags << std::endl;
1741     oss << "m_forwardRefIdx: " << +picParams->m_forwardRefIdx << std::endl;
1742     oss << "m_backwardRefIdx: " << +picParams->m_backwardRefIdx << std::endl;
1743     oss << "m_topFieldFirst: " << +picParams->m_topFieldFirst << std::endl;
1744     oss << "m_secondField: " << +picParams->m_secondField << std::endl;
1745     oss << "m_statusReportFeedbackNumber: " << +picParams->m_statusReportFeedbackNumber << std::endl;
1746     //Dump union w0
1747     oss << "w0 m_value: " << +picParams->W0.m_value << std::endl;
1748     oss << "m_scanOrder: " << +picParams->W0.m_scanOrder << std::endl;
1749     oss << "m_intraVlcFormat: " << +picParams->W0.m_intraVlcFormat << std::endl;
1750     oss << "m_quantizerScaleType: " << +picParams->W0.m_quantizerScaleType << std::endl;
1751     oss << "m_concealmentMVFlag: " << +picParams->W0.m_concealmentMVFlag << std::endl;
1752     oss << "m_frameDctPrediction: " << +picParams->W0.m_frameDctPrediction << std::endl;
1753     oss << "m_topFieldFirst: " << +picParams->W0.m_topFieldFirst << std::endl;
1754     oss << "m_intraDCPrecision: " << +picParams->W0.m_intraDCPrecision << std::endl;
1755     //Dump union w1
1756     oss << "w1 m_value: " << +picParams->W1.m_value << std::endl;
1757     oss << "m_fcode11: " << +picParams->W1.m_fcode11 << std::endl;
1758     oss << "m_fcode10: " << +picParams->W1.m_fcode10 << std::endl;
1759     oss << "m_fcode01: " << +picParams->W1.m_fcode01 << std::endl;
1760     oss << "m_fcode00: " << +picParams->W1.m_fcode00 << std::endl;
1761     oss << "m_horizontalSize: " << +picParams->m_horizontalSize << std::endl;
1762     oss << "m_verticalSize: " << +picParams->m_verticalSize << std::endl;
1763     oss << "m_pictureCodingType: " << +picParams->m_pictureCodingType << std::endl;
1764 
1765     const char *fileName = m_debugInterface->CreateFileName(
1766         "_DEC",
1767         CodechalDbgBufferType::bufPicParams,
1768         CodechalDbgExtType::txt);
1769 
1770     std::ofstream ofs(fileName, std::ios::out);
1771     ofs << oss.str();
1772     ofs.close();
1773     return MOS_STATUS_SUCCESS;
1774 }
1775 
DumpSliceParams(CodecDecodeMpeg2SliceParams * sliceParams,uint32_t numSlices)1776 MOS_STATUS CodechalDecodeMpeg2::DumpSliceParams(
1777     CodecDecodeMpeg2SliceParams *sliceParams,
1778     uint32_t                     numSlices)
1779 {
1780     CODECHAL_DEBUG_FUNCTION_ENTER;
1781 
1782     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
1783     {
1784         return MOS_STATUS_SUCCESS;
1785     }
1786 
1787     CODECHAL_DEBUG_CHK_NULL(sliceParams);
1788 
1789     const char *fileName = m_debugInterface->CreateFileName(
1790         "_DEC",
1791         CodechalDbgBufferType::bufSlcParams,
1792         CodechalDbgExtType::txt);
1793 
1794     std::ostringstream oss;
1795     oss.setf(std::ios::showbase | std::ios::uppercase);
1796 
1797     CodecDecodeMpeg2SliceParams *sliceControl = nullptr;
1798 
1799     for (uint16_t i = 0; i < numSlices; i++)
1800     {
1801         sliceControl = &sliceParams[i];
1802 
1803         oss << "====================================================================================================" << std::endl;
1804         oss << "Data for Slice number = " << +i << std::endl;
1805         oss << "m_sliceDataSize: " << +sliceControl->m_sliceDataSize << std::endl;
1806         oss << "m_sliceDataOffset: " << +sliceControl->m_sliceDataOffset << std::endl;
1807         oss << "m_macroblockOffset: " << +sliceControl->m_macroblockOffset << std::endl;
1808         oss << "m_sliceHorizontalPosition: " << +sliceControl->m_sliceHorizontalPosition << std::endl;
1809         oss << "m_sliceVerticalPosition: " << +sliceControl->m_sliceVerticalPosition << std::endl;
1810         oss << "m_quantiserScaleCode: " << +sliceControl->m_quantiserScaleCode << std::endl;
1811         oss << "m_numMbsForSlice: " << +sliceControl->m_numMbsForSlice << std::endl;
1812         oss << "m_numMbsForSliceOverflow: " << +sliceControl->m_numMbsForSliceOverflow << std::endl;
1813         oss << "m_reservedBits: " << +sliceControl->m_reservedBits << std::endl;
1814         oss << "m_startCodeBitOffset: " << +sliceControl->m_startCodeBitOffset << std::endl;
1815 
1816         std::ofstream ofs;
1817         if (i == 0)
1818         {
1819             ofs.open(fileName, std::ios::out);
1820         }
1821         else
1822         {
1823             ofs.open(fileName, std::ios::app);
1824         }
1825         ofs << oss.str();
1826         ofs.close();
1827     }
1828 
1829     return MOS_STATUS_SUCCESS;
1830 }
1831 
DumpIQParams(CodecMpeg2IqMatrix * matrixData)1832 MOS_STATUS CodechalDecodeMpeg2::DumpIQParams(
1833     CodecMpeg2IqMatrix *matrixData)
1834 {
1835     CODECHAL_DEBUG_FUNCTION_ENTER;
1836 
1837     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams))
1838     {
1839         return MOS_STATUS_SUCCESS;
1840     }
1841 
1842     CODECHAL_DEBUG_CHK_NULL(matrixData);
1843 
1844     std::ostringstream oss;
1845     oss.setf(std::ios::showbase | std::ios::uppercase);
1846 
1847     if (matrixData->m_loadIntraQuantiserMatrix)
1848     {
1849         oss << "intra_QmatrixData:" << std::endl;
1850 
1851         for (uint8_t i = 0; i < 56; i += 8)
1852         {
1853             oss << "Qmatrix[" << +i / 8 << "]: ";
1854             for (uint8_t j = 0; j < 8; j++)
1855                 oss << +matrixData->m_intraQuantiserMatrix[i + j] << " ";
1856             oss << std::endl;
1857         }
1858     }
1859     if (matrixData->m_loadNonIntraQuantiserMatrix)
1860     {
1861         oss << "non_intra_QmatrixData:" << std::endl;
1862 
1863         for (uint8_t i = 0; i < 56; i += 8)
1864         {
1865             oss << "Qmatrix[" << +i / 8 << "]: ";
1866             for (uint8_t j = 0; j < 8; j++)
1867                 oss << +matrixData->m_nonIntraQuantiserMatrix[i + j] << " ";
1868             oss << std::endl;
1869         }
1870     }
1871     if (matrixData->m_loadChromaIntraQuantiserMatrix)
1872     {
1873         oss << "chroma_intra_QmatrixData:" << std::endl;
1874 
1875         for (uint8_t i = 0; i < 56; i += 8)
1876         {
1877             oss << "Qmatrix[" << +i / 8 << "]: ";
1878             for (uint8_t j = 0; j < 8; j++)
1879                 oss << +matrixData->m_chromaIntraQuantiserMatrix[i + j] << " ";
1880             oss << std::endl;
1881         }
1882     }
1883     if (matrixData->m_loadChromaNonIntraQuantiserMatrix)
1884     {
1885         oss << "chroma_non_intra_QmatrixData:" << std::endl;
1886 
1887         for (uint8_t i = 0; i < 56; i += 8)
1888         {
1889             oss << "Qmatrix[" << +i / 8 << "]: ";
1890             for (uint8_t j = 0; j < 8; j++)
1891                 oss << +matrixData->m_chromaNonIntraQuantiserMatrix[i + j] << " ";
1892             oss << std::endl;
1893         }
1894     }
1895 
1896     const char *fileName = m_debugInterface->CreateFileName(
1897         "_DEC",
1898         CodechalDbgBufferType::bufIqParams,
1899         CodechalDbgExtType::txt);
1900 
1901     std::ofstream ofs(fileName, std::ios::out);
1902     ofs << oss.str();
1903     ofs.close();
1904 
1905     return MOS_STATUS_SUCCESS;
1906 }
1907 
DumpMbParams(CodecDecodeMpeg2MbParmas * mbParams)1908 MOS_STATUS CodechalDecodeMpeg2::DumpMbParams(
1909     CodecDecodeMpeg2MbParmas *mbParams)
1910 {
1911     CODECHAL_DEBUG_FUNCTION_ENTER;
1912 
1913     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrMbParams))
1914     {
1915         return MOS_STATUS_SUCCESS;
1916     }
1917 
1918     CODECHAL_DEBUG_CHK_NULL(mbParams);
1919 
1920     std::ostringstream oss;
1921     oss.setf(std::ios::showbase | std::ios::uppercase);
1922 
1923     oss << "m_mbAddr: " << +mbParams->m_mbAddr << std::endl;
1924     //Dump union MBType
1925     oss << "MBType.m_intraMb: " << +mbParams->MBType.m_intraMb << std::endl;
1926     oss << "MBType.m_motionFwd: " << +mbParams->MBType.m_motionFwd << std::endl;
1927     oss << "MBType.m_motionBwd: " << +mbParams->MBType.m_motionBwd << std::endl;
1928     oss << "MBType.m_motion4mv: " << +mbParams->MBType.m_motion4mv << std::endl;
1929     oss << "MBType.m_h261Lpfilter: " << +mbParams->MBType.m_h261Lpfilter << std::endl;
1930     oss << "MBType.m_fieldResidual: " << +mbParams->MBType.m_fieldResidual << std::endl;
1931     oss << "MBType.m_mbScanMethod: " << +mbParams->MBType.m_mbScanMethod << std::endl;
1932     oss << "MBType.m_motionType: " << +mbParams->MBType.m_motionType << std::endl;
1933     oss << "MBType.m_hostResidualDiff: " << +mbParams->MBType.m_hostResidualDiff << std::endl;
1934     oss << "MBType.m_mvertFieldSel: " << +mbParams->MBType.m_mvertFieldSel << std::endl;
1935     oss << "m_mbSkipFollowing: " << +mbParams->m_mbSkipFollowing << std::endl;
1936     oss << "m_mbDataLoc: " << +mbParams->m_mbDataLoc << std::endl;
1937     oss << "m_codedBlockPattern: " << +mbParams->m_codedBlockPattern << std::endl;
1938 
1939     //Dump NumCoeff[CODEC_NUM_BLOCK_PER_MB]
1940     for (uint16_t i = 0; i < CODEC_NUM_BLOCK_PER_MB; ++i)
1941     {
1942         oss << "m_numCoeff[" << +i << "]: " << +mbParams->m_numCoeff[i] << std::endl;
1943     }
1944 
1945     //Dump motion_vectors[8],printing them in 4 value chunks per line
1946     for (uint8_t i = 0; i < 2; ++i)
1947     {
1948         oss << "m_motionVectors[" << +i * 4 << "-" << (+i * 4) + 3 << "]: ";
1949         for (uint8_t j = 0; j < 4; j++)
1950             oss << +mbParams->m_motionVectors[i * 4 + j] << " ";
1951         oss << std::endl;
1952     }
1953 
1954     const char *fileName = m_debugInterface->CreateFileName(
1955         "_DEC",
1956         CodechalDbgBufferType::bufMbParams,
1957         CodechalDbgExtType::txt);
1958 
1959     std::ofstream ofs(fileName, std::ios::out);
1960     ofs << oss.str();
1961     ofs.close();
1962     return MOS_STATUS_SUCCESS;
1963 }
1964 
1965 #endif
1966