1 /*
2 * Copyright (c) 2015-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 //!
24 //! \file     codechal_decode_vc1_g11.cpp
25 //! \brief    Implements the decode interface extension for Gen11 VC1.
26 //! \details  Implements all functions required by CodecHal for Gen11 VC1 decoding.
27 //!
28 
29 #include "codeckrnheader.h"
30 #ifndef _FULL_OPEN_SOURCE
31 #include "igcodeckrn_g11.h"
32 #endif
33 #include "igcodeckrn_g11_icllp.h"
34 #include "codechal_decode_vc1_g11.h"
35 #include "codechal_secure_decode_interface.h"
36 #include "mhw_vdbox_mfx_g11_X.h"
37 #include "hal_oca_interface.h"
38 
AllocateStandard(CodechalSetting * settings)39 MOS_STATUS CodechalDecodeVc1G11::AllocateStandard(
40     CodechalSetting *          settings)
41 {
42     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
43 
44     CODECHAL_DECODE_FUNCTION_ENTER;
45 
46     CODECHAL_DECODE_CHK_NULL_RETURN(settings);
47 
48     CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVc1::AllocateStandard(settings));
49 
50     if ( MOS_VE_SUPPORTED(m_osInterface))
51     {
52         static_cast<MhwVdboxMfxInterfaceG11*>(m_mfxInterface)->DisableScalabilitySupport();
53 
54         //single pipe VE initialize
55         m_veState = (PCODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE));
56         CODECHAL_DECODE_CHK_NULL_RETURN(m_veState);
57         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_InitInterface(m_osInterface, m_veState));
58     }
59 
60     return eStatus;
61 }
62 
SetGpuCtxCreatOption(CodechalSetting * codecHalSetting)63 MOS_STATUS CodechalDecodeVc1G11::SetGpuCtxCreatOption(
64     CodechalSetting *          codecHalSetting)
65 {
66     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
67 
68     CODECHAL_DECODE_FUNCTION_ENTER;
69 
70     if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
71     {
72         CodechalDecode::SetGpuCtxCreatOption(codecHalSetting);
73     }
74     else
75     {
76         m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED);
77 
78         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_ConstructParmsForGpuCtxCreation(
79             m_veState,
80             (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt,
81             false));
82         m_videoContext = MOS_GPU_CONTEXT_VIDEO; // Move functionality to CodecHalDecodeMapGpuNodeToGpuContex
83     }
84     return eStatus;
85 }
86 
SetFrameStates()87 MOS_STATUS CodechalDecodeVc1G11::SetFrameStates()
88 {
89     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
90 
91     CODECHAL_DECODE_FUNCTION_ENTER;
92 
93     CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVc1::SetFrameStates());
94 
95     if ( MOS_VE_SUPPORTED(m_osInterface))
96     {
97         if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
98         {
99             MOS_VIRTUALENGINE_SET_PARAMS  vesetParams;
100 
101             MOS_ZeroMemory(&vesetParams, sizeof(vesetParams));
102             vesetParams.bSFCInUse = false;
103             vesetParams.bNeedSyncWithPrevious = true;
104             vesetParams.bSameEngineAsLastSubmission = false;
105             CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_SetHintParams(m_veState, &vesetParams));
106         }
107     }
108 
109     return eStatus;
110 }
111 
DecodeStateLevel()112 MOS_STATUS CodechalDecodeVc1G11::DecodeStateLevel()
113 {
114     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
115 
116     CODECHAL_DECODE_FUNCTION_ENTER;
117 
118     PCODEC_REF_LIST     *vc1RefList;
119     vc1RefList = &(m_vc1RefList[0]);
120 
121     uint8_t destIdx   = m_vc1PicParams->CurrPic.FrameIdx;
122     uint8_t fwdRefIdx = (uint8_t)m_vc1PicParams->ForwardRefIdx;
123     uint8_t bwdRefIdx = (uint8_t)m_vc1PicParams->BackwardRefIdx;
124 
125     bool isIPicture = m_mfxInterface->IsVc1IPicture(
126                           m_vc1PicParams->CurrPic,
127                           m_vc1PicParams->picture_fields.is_first_field,
128                           m_vc1PicParams->picture_fields.picture_type)
129                           ? true
130                           : false;
131     bool isPPicture = m_mfxInterface->IsVc1PPicture(
132                           m_vc1PicParams->CurrPic,
133                           m_vc1PicParams->picture_fields.is_first_field,
134                           m_vc1PicParams->picture_fields.picture_type)
135                           ? true
136                           : false;
137     bool isBPicture = m_mfxInterface->IsVc1BPicture(
138                           m_vc1PicParams->CurrPic,
139                           m_vc1PicParams->picture_fields.is_first_field,
140                           m_vc1PicParams->picture_fields.picture_type)
141                           ? true
142                           : false;
143 
144     PMOS_SURFACE    destSurface;
145     PMOS_RESOURCE   fwdRefSurface, bwdRefSurface;
146     if (m_unequalFieldWaInUse && CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
147     {
148         destSurface =
149             &(m_unequalFieldSurface[vc1RefList[destIdx]->dwUnequalFieldSurfaceIdx]);
150         fwdRefSurface =
151             &(m_unequalFieldSurface[vc1RefList[fwdRefIdx]->dwUnequalFieldSurfaceIdx].OsResource);
152         bwdRefSurface =
153             &(m_unequalFieldSurface[vc1RefList[bwdRefIdx]->dwUnequalFieldSurfaceIdx].OsResource);
154 
155         // Overwrite the actual surface height with the coded height and width of the frame
156         // for VC1 since it's possible for a VC1 frame to change size during playback
157         destSurface->dwWidth = m_width;
158         destSurface->dwHeight = m_height;
159     }
160     else
161     {
162         destSurface   = &m_destSurface;
163         fwdRefSurface = &(vc1RefList[fwdRefIdx]->resRefPic);
164         bwdRefSurface = &(vc1RefList[bwdRefIdx]->resRefPic);
165     }
166 
167     // WA for SP/MP short format
168     if (m_shortFormatInUse &&
169         !m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
170     {
171         CODECHAL_DECODE_CHK_STATUS_RETURN(ConstructBistreamBuffer());
172     }
173 
174     MOS_COMMAND_BUFFER  cmdBuffer;
175     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
176 
177     auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
178     HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
179 
180     if (m_olpNeeded)
181     {
182         CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, false));
183     }
184     else
185     {
186         CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, true));
187     }
188 
189     MHW_VDBOX_PIPE_MODE_SELECT_PARAMS   pipeModeSelectParams;
190     pipeModeSelectParams.Mode = m_mode;
191     pipeModeSelectParams.bStreamOutEnabled = m_streamOutEnabled;
192     pipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled;
193     pipeModeSelectParams.bPreDeblockOutEnable  = !m_deblockingEnabled;
194     pipeModeSelectParams.bShortFormatInUse     = m_shortFormatInUse;
195     pipeModeSelectParams.bVC1OddFrameHeight    = m_vc1OddFrameHeight;
196 
197     MHW_VDBOX_SURFACE_PARAMS    surfaceParams;
198     MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
199     surfaceParams.Mode = m_mode;
200     surfaceParams.psSurface = destSurface;
201 
202     MHW_VDBOX_PIPE_BUF_ADDR_PARAMS  pipeBufAddrParams;
203     pipeBufAddrParams.Mode = m_mode;
204     if (m_deblockingEnabled)
205     {
206         pipeBufAddrParams.psPostDeblockSurface = destSurface;
207     }
208     else
209     {
210         pipeBufAddrParams.psPreDeblockSurface = destSurface;
211     }
212 
213     // when there is not a forward or backward reference,
214     // the index is set to the destination frame index
215     m_presReferences[CodechalDecodeFwdRefTop] =
216         m_presReferences[CodechalDecodeFwdRefBottom] =
217             fwdRefSurface;
218     m_presReferences[CodechalDecodeBwdRefTop] =
219         m_presReferences[CodechalDecodeBwdRefBottom] =
220             bwdRefSurface;
221     // special case for second fields
222     if (!m_vc1PicParams->picture_fields.is_first_field &&
223         !m_mfxInterface->IsVc1IPicture(
224             m_vc1PicParams->CurrPic,
225             m_vc1PicParams->picture_fields.is_first_field,
226             m_vc1PicParams->picture_fields.picture_type))
227     {
228         if (m_vc1PicParams->picture_fields.top_field_first)
229         {
230             m_presReferences[CodechalDecodeFwdRefTop] =
231                 &destSurface->OsResource;
232         }
233         else
234         {
235             m_presReferences[CodechalDecodeFwdRefBottom] =
236                 &destSurface->OsResource;
237         }
238     }
239 
240     // set all ref pic addresses to valid addresses for error concealment purpose
241     for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
242     {
243         if (m_presReferences[i] == nullptr &&
244             MEDIA_IS_WA(m_waTable, WaDummyReference) &&
245             !Mos_ResourceIsNull(&m_dummyReference.OsResource))
246         {
247             m_presReferences[i] = &m_dummyReference.OsResource;
248         }
249     }
250 
251     CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(pipeBufAddrParams.presReferences, sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC, m_presReferences, sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC));
252 
253     pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
254         &m_resMfdDeblockingFilterRowStoreScratchBuffer;
255 
256     if (m_streamOutEnabled)
257     {
258         pipeBufAddrParams.presStreamOutBuffer =
259             &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
260     }
261 
262     pipeBufAddrParams.pDecodedReconParam = &surfaceParams;
263     pipeBufAddrParams.pRawSurfParam = nullptr;
264 
265 #ifdef _MMC_SUPPORTED
266     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams, &cmdBuffer));
267 #endif
268 
269     pipeBufAddrParams.pDecodedReconParam = nullptr;
270 
271 #ifdef _MMC_SUPPORTED
272     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&pipeBufAddrParams));
273 
274     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode));
275 #endif
276 
277     CODECHAL_DEBUG_TOOL(
278         for (int i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
279         {
280             if (pipeBufAddrParams.presReferences[i])
281             {
282                 MOS_SURFACE dstSurface;
283 
284                 MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
285                 dstSurface.Format = Format_NV12;
286                 dstSurface.OsResource = *(pipeBufAddrParams.presReferences[i]);
287                 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
288                     m_osInterface,
289                     &dstSurface));
290 
291                 m_debugInterface->m_refIndex = (uint16_t)i;
292                 std::string refSurfName      = "RefSurf" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex));
293                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
294                     &dstSurface,
295                     CodechalDbgAttr::attrReferenceSurfaces,
296                     refSurfName.data()));
297             }
298         }
299     )
300 
301     MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS      indObjBaseAddrParams;
302     MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
303     indObjBaseAddrParams.Mode = m_mode;
304     if (m_shortFormatInUse &&
305         !m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
306     {
307         indObjBaseAddrParams.dwDataSize     = m_dataSize + CODECHAL_DECODE_VC1_STUFFING_BYTES;
308         indObjBaseAddrParams.presDataBuffer = &m_resPrivateBistreamBuffer;
309     }
310     else
311     {
312         indObjBaseAddrParams.dwDataSize     = m_dataSize;
313         indObjBaseAddrParams.presDataBuffer = &m_resDataBuffer;
314     }
315 
316     MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS  bspBufBaseAddrParams;
317     MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
318     bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer;
319 
320     if (m_vc1PicParams->raw_coding.bitplane_present || m_shortFormatInUse)
321     {
322         bspBufBaseAddrParams.presBitplaneBuffer = &m_resBitplaneBuffer;
323     }
324 
325     MHW_VDBOX_VC1_PRED_PIPE_PARAMS  vc1PredPipeParams;
326     vc1PredPipeParams.pVc1PicParams = m_vc1PicParams;
327     vc1PredPipeParams.ppVc1RefList = vc1RefList;
328 
329     MHW_VDBOX_VC1_PIC_STATE vc1PicState;
330     vc1PicState.pVc1PicParams             = m_vc1PicParams;
331     vc1PicState.Mode = m_mode;
332     vc1PicState.ppVc1RefList = vc1RefList;
333     vc1PicState.wPrevAnchorPictureTFF     = m_prevAnchorPictureTff;
334     vc1PicState.bPrevEvenAnchorPictureIsP = m_prevEvenAnchorPictureIsP;
335     vc1PicState.bPrevOddAnchorPictureIsP  = m_prevOddAnchorPictureIsP;
336 
337     if (m_shortFormatInUse)
338     {
339         // WA for WMP. WMP does not provide REFDIST for I/P pictures correctly
340         if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag &&
341             CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
342             (isIPicture || isPPicture) &&
343             m_vc1PicParams->reference_fields.reference_distance_flag)
344         {
345             if (m_vc1PicParams->picture_fields.is_first_field)
346             {
347                 CODECHAL_DECODE_CHK_STATUS_RETURN(ParsePictureHeader());
348                 m_referenceDistance = m_vc1PicParams->reference_fields.reference_distance;
349             }
350             else
351             {
352                 m_vc1PicParams->reference_fields.reference_distance = m_referenceDistance;
353             }
354         }
355 
356         // WA for WMP. WMP does not provide BFRACTION correctly. So parse picture header to get BFRACTION
357         if (isBPicture)
358         {
359             if (m_vc1PicParams->picture_fields.is_first_field)
360             {
361                 CODECHAL_DECODE_CHK_STATUS_RETURN(ParsePictureHeader());
362             }
363         }
364     }
365 
366     MHW_VDBOX_VC1_DIRECTMODE_PARAMS vc1DirectmodeParams;
367     if (m_mode == CODECHAL_DECODE_MODE_VC1VLD)
368     {
369         uint8_t dmvBufferIdx                   = (m_vc1PicParams->CurrPic.PicFlags == PICTURE_BOTTOM_FIELD) ? CODECHAL_DECODE_VC1_DMV_ODD : CODECHAL_DECODE_VC1_DMV_EVEN;
370         vc1DirectmodeParams.presDmvReadBuffer  = &m_resVc1BsdMvData[dmvBufferIdx];
371         vc1DirectmodeParams.presDmvWriteBuffer = &m_resVc1BsdMvData[dmvBufferIdx];
372     }
373 
374     if (m_statusQueryReportingEnabled)
375     {
376         CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer));
377     }
378 
379     if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
380         m_vc1PicParams->picture_fields.picture_type == vc1SkippedFrame)
381     {
382         // no further picture level commands needed for skipped frames
383         m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
384 
385         return eStatus;
386     }
387 
388     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
389 
390     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
391 
392     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams));
393 
394     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
395 
396     if (m_mode == CODECHAL_DECODE_MODE_VC1VLD)
397     {
398         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams));
399     }
400 
401     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1PredPipeCmd(&cmdBuffer, &vc1PredPipeParams));
402 
403     if (m_intelEntrypointInUse || m_mode == CODECHAL_DECODE_MODE_VC1IT)
404     {
405         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1LongPicCmd(&cmdBuffer, &vc1PicState));
406     }
407     else if (m_shortFormatInUse)
408     {
409         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ShortPicCmd(&cmdBuffer, &vc1PicState));
410     }
411     else
412     {
413         CODECHAL_DECODE_ASSERTMESSAGE("Unsupported decode mode.");
414         eStatus = MOS_STATUS_UNKNOWN;
415         return eStatus;
416     }
417 
418     if (m_mode == CODECHAL_DECODE_MODE_VC1VLD)
419     {
420         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1DirectmodeCmd(&cmdBuffer, &vc1DirectmodeParams));
421     }
422 
423     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
424 
425     return eStatus;
426 }
427 
DecodePrimitiveLevelVLD()428 MOS_STATUS CodechalDecodeVc1G11::DecodePrimitiveLevelVLD()
429 {
430     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
431 
432     CODECHAL_DECODE_FUNCTION_ENTER;
433 
434     MOS_SYNC_PARAMS syncParams;
435 
436     // static VC1 slice parameters
437     MHW_VDBOX_VC1_SLICE_STATE vc1SliceState;
438     vc1SliceState.presDataBuffer = &m_resDataBuffer;
439 
440     uint16_t frameFieldHeightInMb;
441     CodecHal_GetFrameFieldHeightInMb(
442         m_vc1PicParams->CurrPic,
443         m_picHeightInMb,
444         frameFieldHeightInMb);
445 
446     CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
447 
448     MOS_COMMAND_BUFFER cmdBuffer;
449     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
450 
451     if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
452         m_vc1PicParams->picture_fields.picture_type == vc1SkippedFrame)
453     {
454         CODECHAL_DECODE_CHK_STATUS_RETURN(HandleSkipFrame());
455         goto submit;
456     }
457     else
458     {
459         PCODEC_VC1_SLICE_PARAMS slc             = m_vc1SliceParams;
460         bool firstValidSlice = true;
461         int prevValidSlc = 0;
462         for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++)
463         {
464             m_vldSliceRecord[slcCount].dwSliceYOffset     = slc->slice_vertical_position;
465             m_vldSliceRecord[slcCount].dwNextSliceYOffset = frameFieldHeightInMb;  // init to last slice
466 
467             int32_t lLength = slc->slice_data_size >> 3;
468             int32_t lOffset = slc->macroblock_offset >> 3;
469 
470             CodechalResLock ResourceLock(m_osInterface, &m_resDataBuffer);
471             auto buf = (uint8_t*)ResourceLock.Lock(CodechalResLock::readOnly);
472             if (lOffset > 3 && buf != nullptr &&
473                 m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
474             {
475                 int i = 0;
476                 int j = 0;
477 
478                 buf += slc->slice_data_offset;
479 
480                 for (i = 0, j = 0; i < lOffset - 1; i++, j++)
481                 {
482                     if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3 && buf[j + 3] < 4)
483                     {
484                         i++, j += 2;
485                     }
486                 }
487                 if (i == lOffset - 1)
488                 {
489                     if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3 && buf[j + 3] < 4)
490                     {
491                         buf[j + 2] = 0;
492                         j++;
493                     }
494                     j++;
495                 }
496                 lOffset = (8 * j + slc->macroblock_offset % 8)>>3;
497             }
498 
499             // Check that the slice data does not overrun the bitstream buffer size
500             if (((uintptr_t)(slc->slice_data_offset) + lLength) > m_dataSize)
501             {
502                 lLength = m_dataSize - (uintptr_t)(slc->slice_data_offset);
503 
504                 if (lLength < 0)
505                 {
506                     lLength = 0;
507                 }
508             }
509 
510             // Error handling for garbage data
511             if (((uintptr_t)(slc->slice_data_offset)) > m_dataSize)
512             {
513                 slc++;
514                 m_vldSliceRecord[slcCount].dwSkip = true;
515                 continue;
516             }
517 
518             // Check offset not larger than slice length, can have slice length of 0
519             if (lOffset > lLength)
520             {
521                 slc++;
522                 m_vldSliceRecord[slcCount].dwSkip = true;
523                 continue;
524             }
525 
526             // Check that the slices do not overlap, else do not send the lower slice
527             if (!firstValidSlice &&
528                 (m_vldSliceRecord[slcCount].dwSliceYOffset <= m_vldSliceRecord[prevValidSlc].dwSliceYOffset))
529             {
530                 slc++;
531                 m_vldSliceRecord[slcCount].dwSkip = true;
532                 continue;
533             }
534 
535             if (firstValidSlice)
536             {
537                 // Ensure that the first slice starts from 0
538                 m_vldSliceRecord[slcCount].dwSliceYOffset = 0;
539                 slc->slice_vertical_position = 0;
540             }
541             else
542             {
543                 // Set next slice start Y offset of previous slice
544                 m_vldSliceRecord[prevValidSlc].dwNextSliceYOffset =
545                     m_vldSliceRecord[slcCount].dwSliceYOffset;
546             }
547 
548             if (m_shortFormatInUse)
549             {
550                 if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
551                 {
552                     if ((slc->macroblock_offset >> 3) < CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH)
553                     {
554                         slc++;
555                         m_vldSliceRecord[slcCount].dwSkip = true;
556                         continue;
557                     }
558 
559                     // set macroblock_offset of the first slice to 0 to avoid crash
560                     if (slcCount == 0)
561                     {
562                         slc->macroblock_offset = CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH << 3;
563                     }
564 
565                     lOffset = CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH;
566                 }
567                 else // Simple Profile or Main Profile
568                 {
569                     {
570                         lOffset = CODECHAL_DECODE_VC1_STUFFING_BYTES - 1;
571                         lLength += CODECHAL_DECODE_VC1_STUFFING_BYTES;
572                         slc->macroblock_offset += CODECHAL_DECODE_VC1_STUFFING_BYTES << 3;
573                         slc->macroblock_offset &= (~0x7); // Clear bit offset of first MB for short format
574                     }
575                 }
576             }
577 
578             m_vldSliceRecord[slcCount].dwOffset = lOffset;
579             m_vldSliceRecord[slcCount].dwLength = lLength - lOffset;
580             firstValidSlice = false;
581             prevValidSlc = slcCount;
582             slc++;
583         }
584 
585         if (m_shortFormatInUse &&
586             m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
587         {
588             CODECHAL_DECODE_CHK_STATUS_RETURN(GetSliceMbDataOffset());
589         }
590 
591         // Reset slc pointer
592         slc -= m_numSlices;
593 
594         //------------------------------------
595         // Fill BSD Object Commands
596         //------------------------------------
597         for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++)
598         {
599             if (m_vldSliceRecord[slcCount].dwSkip)
600             {
601                 slc++;
602                 continue;
603             }
604 
605             vc1SliceState.pSlc = slc;
606             vc1SliceState.dwOffset               = m_vldSliceRecord[slcCount].dwOffset;
607             vc1SliceState.dwLength               = m_vldSliceRecord[slcCount].dwLength;
608             vc1SliceState.dwNextVerticalPosition = m_vldSliceRecord[slcCount].dwNextSliceYOffset;
609 
610             CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1BsdObjectCmd(&cmdBuffer, &vc1SliceState));
611 
612             slc++;
613         }
614 
615         // Free VLD slice record
616         MOS_ZeroMemory(m_vldSliceRecord, (m_numSlices * sizeof(CODECHAL_VC1_VLD_SLICE_RECORD)));
617     }
618 
619     // Check if destination surface needs to be synchronized
620     if (m_unequalFieldWaInUse &&
621         CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
622         !m_vc1PicParams->picture_fields.is_first_field)
623     {
624         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
625         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
626 
627         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
628     }
629     else
630     {
631         // Check if destination surface needs to be synchronized
632         syncParams = g_cInitSyncParams;
633         syncParams.GpuContext = m_videoContext;
634         syncParams.presSyncResource         = &m_destSurface.OsResource;
635         syncParams.bReadOnly = false;
636         syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
637         syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
638 
639         if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) ||
640             m_vc1PicParams->picture_fields.is_first_field)
641         {
642             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
643             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
644 
645             // Update the resource tag (s/w tag) for On-Demand Sync
646             m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
647         }
648 
649         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
650         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
651 
652         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
653 
654         // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
655         if (m_osInterface->bTagResourceSync &&
656             !(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && m_vc1PicParams->picture_fields.is_first_field))
657         {
658             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
659         }
660     }
661 
662 submit:
663     if (m_statusQueryReportingEnabled)
664     {
665         CodechalDecodeStatusReport decodeStatusReport;
666 
667         decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
668         decodeStatusReport.m_currDecodedPic     = m_vc1PicParams->CurrPic;
669         if (m_olpNeeded)
670         {
671             CODECHAL_DEBUG_TOOL(
672                 decodeStatusReport.m_currDeblockedPic.FrameIdx = (uint8_t)m_vc1PicParams->DeblockedPicIdx;
673                 decodeStatusReport.m_currDeblockedPic.PicFlags = PICTURE_FRAME;)
674             decodeStatusReport.m_deblockedPicResOlp = m_deblockSurface.OsResource;
675         }
676         else
677         {
678             decodeStatusReport.m_currDeblockedPic = m_vc1PicParams->CurrPic;
679         }
680         decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
681         decodeStatusReport.m_currDecodedPicRes = m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic;
682 
683         CODECHAL_DEBUG_TOOL(
684             decodeStatusReport.m_secondField = (m_vc1PicParams->picture_fields.is_first_field == 1);
685             decodeStatusReport.m_olpNeeded   = m_olpNeeded;
686             decodeStatusReport.m_frameType   = m_perfType;)
687 
688         CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
689     }
690 
691     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
692 
693     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
694 
695     CODECHAL_DEBUG_TOOL(
696         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
697             &cmdBuffer,
698             CODECHAL_NUM_MEDIA_STATES,
699             "_DEC"));
700 
701     //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
702     //    m_debugInterface,
703     //    &cmdBuffer));
704     )
705 
706     if ( MOS_VE_SUPPORTED(m_osInterface))
707     {
708         CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, true);
709     }
710 
711     if (m_huCCopyInUse)
712     {
713         syncParams = g_cInitSyncParams;
714         syncParams.GpuContext = m_videoContextForWa;
715         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
716 
717         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
718 
719         syncParams = g_cInitSyncParams;
720         syncParams.GpuContext = m_videoContext;
721         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
722 
723         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
724 
725         m_huCCopyInUse = false;
726     }
727 
728     HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
729 
730     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
731 
732     CODECHAL_DEBUG_TOOL(
733         m_mmc->UpdateUserFeatureKey(&m_destSurface);)
734 
735     if (m_unequalFieldWaInUse &&
736         CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
737         !m_vc1PicParams->picture_fields.is_first_field)
738     {
739         CODECHAL_DECODE_CHK_NULL_RETURN(m_vc1RefList);
740 
741         uint32_t destFrameIdx = m_vc1PicParams->CurrPic.FrameIdx;
742 
743         CODECHAL_DECODE_CHK_STATUS_RETURN(FormatUnequalFieldPicture(
744             m_unequalFieldSurface[m_vc1RefList[destFrameIdx]->dwUnequalFieldSurfaceIdx],
745             m_destSurface,
746             true,
747             m_videoContextUsesNullHw ? true : false));
748         }
749 
750         if (m_olpNeeded)
751         {
752             CODECHAL_DECODE_CHK_STATUS_RETURN(PerformVc1Olp());
753     }
754     else
755     {
756         if (m_statusQueryReportingEnabled)
757         {
758             CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
759         }
760     }
761 
762     // Needs to be re-set for Linux buffer re-use scenarios
763     m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic = m_destSurface.OsResource;
764 
765     // Send the signal to indicate decode completion, in case On-Demand Sync is not present
766     if (!(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
767             m_vc1PicParams->picture_fields.is_first_field))
768     {
769         MOS_SYNC_PARAMS syncParams;
770         syncParams = g_cInitSyncParams;
771         syncParams.GpuContext = m_videoContext;
772         syncParams.presSyncResource = &m_destSurface.OsResource;
773 
774         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
775 
776         if (m_olpNeeded)
777         {
778             syncParams = g_cInitSyncParams;
779             syncParams.GpuContext = m_renderContext;
780             syncParams.presSyncResource = &m_deblockSurface.OsResource;
781 
782             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
783         }
784     }
785 
786     m_olpNeeded = false;
787 
788     return eStatus;
789 }
790 
DecodePrimitiveLevelIT()791 MOS_STATUS CodechalDecodeVc1G11::DecodePrimitiveLevelIT()
792 {
793     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
794 
795     CODECHAL_DECODE_FUNCTION_ENTER;
796 
797     MOS_SYNC_PARAMS syncParams;
798 
799     PCODEC_VC1_MB_PARAMS mb = m_vc1MbParams;
800 
801     MHW_VDBOX_VC1_MB_STATE vc1MbState;
802     MOS_ZeroMemory(&vc1MbState, sizeof(vc1MbState));
803 
804     // static VC1 MB parameters
805     vc1MbState.presDataBuffer     = &m_resDataBuffer;
806     vc1MbState.pVc1PicParams      = m_vc1PicParams;
807     vc1MbState.pWaTable = m_waTable;
808     vc1MbState.pDeblockDataBuffer = m_deblockDataBuffer;
809     vc1MbState.dwDataSize         = m_dataSize;
810     vc1MbState.wPicWidthInMb      = m_picWidthInMb;
811     vc1MbState.wPicHeightInMb     = m_picHeightInMb;
812     vc1MbState.PicFlags           = m_vc1PicParams->CurrPic.PicFlags;
813     vc1MbState.bFieldPolarity     = m_fieldPolarity;
814 
815     uint16_t frameFieldHeightInMb;
816     CodecHal_GetFrameFieldHeightInMb(
817         m_vc1PicParams->CurrPic,
818         m_picHeightInMb,
819         frameFieldHeightInMb);
820 
821     CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
822 
823     MOS_COMMAND_BUFFER cmdBuffer;
824     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
825 
826     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(&cmdBuffer, &m_itObjectBatchBuffer));
827 
828     CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_LockBb(m_osInterface, &m_itObjectBatchBuffer));
829 
830     PMHW_BATCH_BUFFER batchBuffer = &m_itObjectBatchBuffer;
831 
832     uint32_t mbAddress = 0;
833     uint32_t mbCount;
834     for (mbCount = 0; mbCount < m_numMacroblocks; mbCount++)
835     {
836         vc1MbState.pMb = mb + mbCount;
837 
838         // Skipped MBs before current MB
839         uint16_t skippedMBs = (mbCount) ?
840             (mb[mbCount].mb_address - mb[mbCount - 1].mb_address - 1) :
841             (mb[mbCount].mb_address);
842 
843         while (skippedMBs--)
844         {
845             vc1MbState.bMbHorizOrigin = (uint8_t)(mbAddress % m_picWidthInMb);
846             vc1MbState.bMbVertOrigin  = (uint8_t)(mbAddress / m_picWidthInMb);
847             vc1MbState.bSkipped = true;
848 
849             CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState));
850 
851             mbAddress++;
852         }
853 
854         // Current MB
855         if (mbCount + 1 == m_numMacroblocks)
856         {
857             vc1MbState.dwLength = m_dataSize - mb[mbCount].data_offset;
858         }
859         else
860         {
861             vc1MbState.dwLength = mb[mbCount + 1].data_offset - mb[mbCount].data_offset;
862         }
863 
864         vc1MbState.bMbHorizOrigin = mb[mbCount].mb_address % m_picWidthInMb;
865         vc1MbState.bMbVertOrigin  = mb[mbCount].mb_address / m_picWidthInMb;
866         vc1MbState.dwOffset = (vc1MbState.dwLength) ? mb[mbCount].data_offset : 0;
867         vc1MbState.bSkipped = false;
868 
869         if (m_vc1PicParams->entrypoint_fields.loopfilter)
870         {
871             eStatus = MOS_SecureMemcpy(vc1MbState.DeblockData,
872                 CODEC_NUM_BLOCK_PER_MB,
873                 m_deblockDataBuffer + CODEC_NUM_BLOCK_PER_MB * mb[mbCount].mb_address,
874                 CODEC_NUM_BLOCK_PER_MB);
875             if (eStatus != MOS_STATUS_SUCCESS)
876             {
877                 CODECHAL_DECODE_ASSERTMESSAGE("Failed to copy memory.");
878                 m_olpNeeded = false;
879                 return eStatus;
880             }
881         }
882 
883         if (!mb[mbCount].mb_type.intra_mb)
884         {
885             if (mb[mbCount].mb_type.motion_forward || mb[mbCount].mb_type.motion_backward)
886             {
887                 PackMotionVectors(
888                     &vc1MbState,
889                     (short *)mb[mbCount].motion_vector,
890                     (short *)vc1MbState.PackedLumaMvs,
891                     (short *)&vc1MbState.PackedChromaMv);
892             }
893             else
894             {
895                 mb[mbCount].mb_type.motion_forward = 1;
896                 MOS_ZeroMemory(vc1MbState.PackedLumaMvs, sizeof(vc1MbState.PackedLumaMvs)); // MV's of zero
897                 vc1MbState.bMotionSwitch = 0;
898             }
899         }
900 
901         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState));
902 
903         mbAddress = mb[mbCount].mb_address;
904     }
905 
906     m_fieldPolarity = vc1MbState.bFieldPolarity;
907 
908     // skipped MBs at the end
909     uint16_t skippedMBs = m_picWidthInMb * frameFieldHeightInMb - mb[mbCount - 1].mb_address - 1;
910 
911     while (skippedMBs--)
912     {
913         vc1MbState.bSkipped = true;
914         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState));
915     }
916 
917     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(nullptr, &m_itObjectBatchBuffer));
918 
919     CODECHAL_DEBUG_TOOL(
920         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
921             batchBuffer,
922             CODECHAL_NUM_MEDIA_STATES,
923             "_DEC"));
924     )
925 
926     CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_UnlockBb(m_osInterface, &m_itObjectBatchBuffer, true));
927 
928     // Check if destination surface needs to be synchronized
929     if (m_unequalFieldWaInUse &&
930         CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
931     {
932         if (!m_vc1PicParams->picture_fields.is_first_field)
933         {
934             MHW_MI_FLUSH_DW_PARAMS flushDwParams;
935             MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
936 
937             CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
938         }
939     }
940     else
941     {
942         syncParams = g_cInitSyncParams;
943         syncParams.GpuContext = m_videoContext;
944         syncParams.presSyncResource         = &m_destSurface.OsResource;
945         syncParams.bReadOnly = false;
946         syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
947         syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
948 
949         if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) ||
950             m_vc1PicParams->picture_fields.is_first_field)
951         {
952             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
953             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
954 
955             // Update the resource tag (s/w tag) for On-Demand Sync
956             m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
957         }
958 
959         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
960         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
961 
962         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
963 
964         // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
965         if (m_osInterface->bTagResourceSync &&
966             !(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && m_vc1PicParams->picture_fields.is_first_field))
967         {
968             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
969         }
970     }
971 
972     if (m_statusQueryReportingEnabled)
973     {
974         CodechalDecodeStatusReport decodeStatusReport;
975 
976         decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
977         decodeStatusReport.m_currDecodedPic     = m_vc1PicParams->CurrPic;
978         if (m_olpNeeded)
979         {
980             CODECHAL_DEBUG_TOOL(
981                 decodeStatusReport.m_currDeblockedPic.FrameIdx = (uint8_t)m_vc1PicParams->DeblockedPicIdx;
982                 decodeStatusReport.m_currDeblockedPic.PicFlags = PICTURE_FRAME;)
983             decodeStatusReport.m_deblockedPicResOlp = m_deblockSurface.OsResource;
984         }
985         else
986         {
987             decodeStatusReport.m_currDeblockedPic = m_vc1PicParams->CurrPic;
988         }
989         decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
990         decodeStatusReport.m_currDecodedPicRes = m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic;
991 
992         CODECHAL_DEBUG_TOOL(
993             decodeStatusReport.m_secondField = (m_vc1PicParams->picture_fields.is_first_field == 1);
994             decodeStatusReport.m_olpNeeded   = m_olpNeeded;
995             decodeStatusReport.m_frameType   = m_perfType;)
996 
997         CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
998     }
999 
1000     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
1001 
1002     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1003 
1004     CODECHAL_DEBUG_TOOL(
1005         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1006             &cmdBuffer,
1007             CODECHAL_NUM_MEDIA_STATES,
1008             "_DEC"));
1009 
1010     //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
1011     //    m_debugInterface,
1012     //    &cmdBuffer));
1013     )
1014 
1015     if ( MOS_VE_SUPPORTED(m_osInterface))
1016     {
1017         CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, true);
1018     }
1019 
1020     if (m_huCCopyInUse)
1021     {
1022         syncParams = g_cInitSyncParams;
1023         syncParams.GpuContext = m_videoContextForWa;
1024         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
1025 
1026         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1027 
1028         syncParams = g_cInitSyncParams;
1029         syncParams.GpuContext = m_videoContext;
1030         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
1031 
1032         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1033 
1034         m_huCCopyInUse = false;
1035     }
1036 
1037     HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
1038 
1039     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
1040 
1041     CODECHAL_DEBUG_TOOL(
1042         m_mmc->UpdateUserFeatureKey(&m_destSurface);)
1043 
1044     if (m_unequalFieldWaInUse &&
1045         CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
1046         !m_vc1PicParams->picture_fields.is_first_field)
1047     {
1048         CODECHAL_DECODE_CHK_NULL_RETURN(m_vc1RefList);
1049 
1050         uint32_t destFrameIdx = m_vc1PicParams->CurrPic.FrameIdx;
1051 
1052         CODECHAL_DECODE_CHK_STATUS_RETURN(FormatUnequalFieldPicture(
1053             m_unequalFieldSurface[m_vc1RefList[destFrameIdx]->dwUnequalFieldSurfaceIdx],
1054             m_destSurface,
1055             true,
1056             m_videoContextUsesNullHw ? true : false));
1057         }
1058 
1059         if (m_olpNeeded)
1060         {
1061             CODECHAL_DECODE_CHK_STATUS_RETURN(PerformVc1Olp());
1062     }
1063     else
1064     {
1065         if (m_statusQueryReportingEnabled)
1066         {
1067             CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
1068         }
1069     }
1070 
1071     // Needs to be re-set for Linux buffer re-use scenarios
1072     m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic = m_destSurface.OsResource;
1073 
1074     // Send the signal to indicate decode completion, in case On-Demand Sync is not present
1075     if (!(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
1076             m_vc1PicParams->picture_fields.is_first_field))
1077     {
1078         MOS_SYNC_PARAMS syncParams;
1079         syncParams = g_cInitSyncParams;
1080         syncParams.GpuContext = m_videoContext;
1081         syncParams.presSyncResource = &m_destSurface.OsResource;
1082 
1083         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
1084 
1085         if (m_olpNeeded)
1086         {
1087             syncParams = g_cInitSyncParams;
1088             syncParams.GpuContext = m_renderContext;
1089             syncParams.presSyncResource = &m_deblockSurface.OsResource;
1090 
1091             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
1092         }
1093     }
1094 
1095     m_olpNeeded = false;
1096 
1097     return eStatus;
1098 }
1099 
HandleSkipFrame()1100 MOS_STATUS CodechalDecodeVc1G11::HandleSkipFrame()
1101 {
1102     MOS_COMMAND_BUFFER                  cmdBuffer;
1103     MHW_MI_FLUSH_DW_PARAMS              flushDwParams;
1104     MHW_GENERIC_PROLOG_PARAMS           genericPrologParams;
1105     MOS_SURFACE                         srcSurface;
1106     uint8_t                             fwdRefIdx;
1107     uint32_t                            surfaceSize;
1108     MOS_SYNC_PARAMS                     syncParams;
1109     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
1110 
1111     CODECHAL_DECODE_FUNCTION_ENTER;
1112 
1113     fwdRefIdx = (uint8_t)m_vc1PicParams->ForwardRefIdx;
1114 
1115     MOS_ZeroMemory(&srcSurface, sizeof(MOS_SURFACE));
1116     srcSurface.Format = Format_NV12;
1117     srcSurface.OsResource = m_vc1RefList[fwdRefIdx]->resRefPic;
1118     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &srcSurface));
1119 
1120 #ifdef _MMC_SUPPORTED
1121     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceMmcMode(&m_destSurface, &srcSurface));
1122 #endif
1123 
1124         surfaceSize = ((srcSurface.OsResource.pGmmResInfo->GetArraySize()) > 1) ?
1125             ((uint32_t)(srcSurface.OsResource.pGmmResInfo->GetQPitchPlanar(GMM_PLANE_Y) *
1126                         srcSurface.OsResource.pGmmResInfo->GetRenderPitch())) :
1127             (uint32_t)(srcSurface.OsResource.pGmmResInfo->GetSizeMainSurface());
1128 
1129     if (m_hwInterface->m_noHuC)
1130     {
1131         CodechalDataCopyParams dataCopyParams;
1132         MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
1133         dataCopyParams.srcResource = &srcSurface.OsResource;
1134         dataCopyParams.srcSize     = surfaceSize;
1135         dataCopyParams.srcOffset = srcSurface.dwOffset;
1136         dataCopyParams.dstResource = &m_destSurface.OsResource;
1137         dataCopyParams.dstSize     = surfaceSize;
1138         dataCopyParams.dstOffset   = m_destSurface.dwOffset;
1139 
1140         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams));
1141     }
1142     else
1143     {
1144         m_huCCopyInUse = true;
1145 
1146         syncParams = g_cInitSyncParams;
1147         syncParams.GpuContext = m_videoContext;
1148         syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
1149 
1150         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1151 
1152         syncParams = g_cInitSyncParams;
1153         syncParams.GpuContext = m_videoContextForWa;
1154         syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
1155 
1156         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1157 
1158         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContextForWa));
1159         m_osInterface->pfnResetOsStates(m_osInterface);
1160 
1161         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1162 
1163         // Send command buffer header at the beginning (OS dependent)
1164         CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, false));
1165 
1166         CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
1167             &cmdBuffer,                             // pCmdBuffer
1168             &srcSurface.OsResource,                 // presSrc
1169             &m_destSurface.OsResource,              // presDst
1170             surfaceSize,                            // u32CopyLength
1171             srcSurface.dwOffset,                    // u32CopyInputOffset
1172             m_destSurface.dwOffset));               // u32CopyOutputOffset
1173 
1174         syncParams = g_cInitSyncParams;
1175         syncParams.GpuContext = m_videoContextForWa;
1176         syncParams.presSyncResource         = &m_destSurface.OsResource;
1177         syncParams.bReadOnly = false;
1178         syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
1179         syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1180 
1181         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
1182         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1183 
1184         // Update the resource tag (s/w tag) for On-Demand Sync
1185         m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1186 
1187         // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
1188         if (m_osInterface->bTagResourceSync)
1189         {
1190             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
1191                 &cmdBuffer,
1192                 &syncParams));
1193         }
1194 
1195         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1196         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1197             &cmdBuffer,
1198             &flushDwParams));
1199 
1200         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1201             &cmdBuffer,
1202             nullptr));
1203 
1204         m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1205 
1206         if ( MOS_VE_SUPPORTED(m_osInterface))
1207         {
1208             CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false);
1209         }
1210 
1211         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
1212 
1213         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext));
1214     }
1215 
1216     return (MOS_STATUS)eStatus;
1217 }
1218 
PerformVc1Olp()1219 MOS_STATUS CodechalDecodeVc1G11::PerformVc1Olp()
1220 {
1221     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1222 
1223     CODECHAL_DECODE_FUNCTION_ENTER;
1224 
1225     MhwRenderInterface *renderEngineInterface = m_hwInterface->GetRenderInterface();
1226     PMHW_KERNEL_STATE         kernelState           = &m_olpKernelState;
1227     PMHW_STATE_HEAP_INTERFACE stateHeapInterface = renderEngineInterface->m_stateHeapInterface;
1228 
1229     CODECHAL_DECODE_CHK_NULL_RETURN(stateHeapInterface);
1230 
1231     MOS_SYNC_PARAMS syncParams;
1232     syncParams = g_cInitSyncParams;
1233     syncParams.GpuContext = m_videoContext;
1234     syncParams.presSyncResource = &m_resSyncObject;
1235 
1236     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1237 
1238     syncParams = g_cInitSyncParams;
1239     syncParams.GpuContext = m_renderContext;
1240     syncParams.presSyncResource = &m_resSyncObject;
1241 
1242     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1243 
1244     // Initialize DSH kernel region
1245     m_osInterface->pfnSetGpuContext(m_osInterface, m_renderContext);
1246     m_osInterface->pfnResetOsStates(m_osInterface);
1247 
1248     m_osInterface->pfnSetPerfTag(
1249         m_osInterface,
1250         (uint16_t)(((m_mode << 4) & 0xF0) | OLP_TYPE));
1251     m_osInterface->pfnResetPerfBufferID(m_osInterface);
1252 
1253     CodecHalGetResourceInfo(m_osInterface, &m_deblockSurface);  // DstSurface
1254 
1255 #ifdef _MMC_SUPPORTED
1256     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->DisableSurfaceMmcState(&m_deblockSurface));
1257 #endif
1258 
1259     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
1260         stateHeapInterface,
1261         kernelState->KernelParams.iBTCount));
1262 
1263     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
1264         stateHeapInterface,
1265         kernelState,
1266         false,
1267         m_olpDshSize,
1268         false,
1269         m_decodeStatusBuf.m_swStoreData));
1270 
1271     MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
1272     MOS_ZeroMemory(&idParams, sizeof(idParams));
1273     idParams.pKernelState = kernelState;
1274     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetInterfaceDescriptor(
1275         stateHeapInterface,
1276         1,
1277         &idParams));
1278     CODECHAL_DECODE_CHK_STATUS_RETURN(SetCurbeOlp());
1279 
1280     // Send HW commands (including SSH)
1281     MOS_COMMAND_BUFFER cmdBuffer;
1282     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1283 
1284     MHW_PIPE_CONTROL_PARAMS pipeControlParams;
1285     MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams));
1286 
1287     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetDefaultSSEuSetting(CODECHAL_MEDIA_STATE_OLP, false, false, false));
1288 
1289     // Send command buffer header at the beginning (OS dependent)
1290     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
1291         &cmdBuffer, true));
1292 
1293     if (renderEngineInterface->GetL3CacheConfig()->bL3CachingEnabled)
1294     {
1295         CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->SetL3Cache(&cmdBuffer));
1296     }
1297 
1298     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->EnablePreemption(&cmdBuffer));
1299 
1300     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddPipelineSelectCmd(&cmdBuffer, false));
1301 
1302     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetBindingTable(
1303         stateHeapInterface,
1304         kernelState));
1305 
1306     // common function for codec needed when we make change for AVC
1307     MHW_RCS_SURFACE_PARAMS surfaceParamsSrc;
1308     MOS_ZeroMemory(&surfaceParamsSrc, sizeof(surfaceParamsSrc));
1309     surfaceParamsSrc.dwNumPlanes = 2;    // Y, UV
1310     surfaceParamsSrc.psSurface          = &m_destSurface;
1311     surfaceParamsSrc.psSurface->dwDepth = 1;    // depth needs to be 0 for codec 2D surface
1312                                                 // Y Plane
1313     surfaceParamsSrc.dwBindingTableOffset[MHW_Y_PLANE] = CODECHAL_DECODE_VC1_OLP_SRC_Y;
1314     surfaceParamsSrc.ForceSurfaceFormat[MHW_Y_PLANE] = MHW_GFX3DSTATE_SURFACEFORMAT_R8_UNORM;
1315     // UV Plane
1316     surfaceParamsSrc.dwBindingTableOffset[MHW_U_PLANE] = CODECHAL_DECODE_VC1_OLP_SRC_UV;
1317     surfaceParamsSrc.ForceSurfaceFormat[MHW_U_PLANE] = MHW_GFX3DSTATE_SURFACEFORMAT_R16_UINT;
1318     surfaceParamsSrc.dwBaseAddrOffset[MHW_U_PLANE] =
1319         m_destSurface.dwPitch *
1320         MOS_ALIGN_FLOOR(m_destSurface.UPlaneOffset.iYOffset, MOS_YTILE_H_ALIGNMENT);
1321     surfaceParamsSrc.dwHeightToUse[MHW_U_PLANE] = surfaceParamsSrc.psSurface->dwHeight / 2;
1322     surfaceParamsSrc.dwYOffset[MHW_U_PLANE] =
1323         (m_destSurface.UPlaneOffset.iYOffset % MOS_YTILE_H_ALIGNMENT);
1324 
1325 #ifdef _MMC_SUPPORTED
1326     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->GetSurfaceMmcState(surfaceParamsSrc.psSurface));
1327 #endif
1328 
1329     MHW_RCS_SURFACE_PARAMS surfaceParamsDst;
1330     MOS_ZeroMemory(&surfaceParamsDst, sizeof(surfaceParamsDst));
1331     surfaceParamsDst = surfaceParamsSrc;
1332     surfaceParamsDst.bIsWritable = true;
1333     surfaceParamsDst.psSurface                         = &m_deblockSurface;
1334     surfaceParamsDst.psSurface->dwDepth = 1;    // depth needs to be 0 for codec 2D surface
1335     surfaceParamsDst.dwBindingTableOffset[MHW_Y_PLANE] = CODECHAL_DECODE_VC1_OLP_DST_Y;
1336     surfaceParamsDst.dwBindingTableOffset[MHW_U_PLANE] = CODECHAL_DECODE_VC1_OLP_DST_UV;
1337 
1338     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetSurfaceState(
1339         stateHeapInterface,
1340         kernelState,
1341         &cmdBuffer,
1342         1,
1343         &surfaceParamsSrc));
1344     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetSurfaceState(
1345         stateHeapInterface,
1346         kernelState,
1347         &cmdBuffer,
1348         1,
1349         &surfaceParamsDst));
1350 
1351     MHW_STATE_BASE_ADDR_PARAMS stateBaseAddrParams;
1352     MOS_ZeroMemory(&stateBaseAddrParams, sizeof(stateBaseAddrParams));
1353     MOS_RESOURCE *dsh = nullptr, *ish = nullptr;
1354     CODECHAL_DECODE_CHK_NULL_RETURN(dsh = kernelState->m_dshRegion.GetResource());
1355     CODECHAL_DECODE_CHK_NULL_RETURN(ish = kernelState->m_ishRegion.GetResource());
1356     stateBaseAddrParams.presDynamicState = dsh;
1357     stateBaseAddrParams.dwDynamicStateSize = kernelState->m_dshRegion.GetHeapSize();
1358     stateBaseAddrParams.presInstructionBuffer = ish;
1359     stateBaseAddrParams.dwInstructionBufferSize = kernelState->m_ishRegion.GetHeapSize();
1360     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddStateBaseAddrCmd(&cmdBuffer, &stateBaseAddrParams));
1361 
1362     MHW_VFE_PARAMS vfeParams = {};
1363     vfeParams.pKernelState = kernelState;
1364     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaVfeCmd(&cmdBuffer, &vfeParams));
1365 
1366     MHW_CURBE_LOAD_PARAMS curbeLoadParams;
1367     MOS_ZeroMemory(&curbeLoadParams, sizeof(curbeLoadParams));
1368     curbeLoadParams.pKernelState = kernelState;
1369     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaCurbeLoadCmd(&cmdBuffer, &curbeLoadParams));
1370 
1371     MHW_ID_LOAD_PARAMS idLoadParams;
1372     MOS_ZeroMemory(&idLoadParams, sizeof(idLoadParams));
1373     idLoadParams.pKernelState = kernelState;
1374     idLoadParams.dwNumKernelsLoaded = 1;
1375     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaIDLoadCmd(&cmdBuffer, &idLoadParams));
1376 
1377     CODECHAL_DEBUG_TOOL(
1378         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1379             CODECHAL_MEDIA_STATE_OLP,
1380             MHW_DSH_TYPE,
1381             kernelState));
1382 
1383     CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1384         CODECHAL_MEDIA_STATE_OLP,
1385         MHW_SSH_TYPE,
1386         kernelState));
1387     )
1388 
1389     CODECHAL_DECODE_VC1_OLP_PARAMS vc1OlpParams;
1390     vc1OlpParams.pCmdBuffer = &cmdBuffer;
1391     vc1OlpParams.pPipeControlParams = &pipeControlParams;
1392     vc1OlpParams.pStateBaseAddrParams = &stateBaseAddrParams;
1393     vc1OlpParams.pVfeParams = &vfeParams;
1394     vc1OlpParams.pCurbeLoadParams = &curbeLoadParams;
1395     vc1OlpParams.pIdLoadParams = &idLoadParams;
1396     CODECHAL_DECODE_CHK_STATUS_RETURN(AddVc1OlpCmd(&vc1OlpParams));
1397 
1398     // Check if destination surface needs to be synchronized, before command buffer submission
1399     syncParams = g_cInitSyncParams;
1400     syncParams.GpuContext = m_renderContext;
1401     syncParams.presSyncResource         = &m_deblockSurface.OsResource;
1402     syncParams.bReadOnly = false;
1403     syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
1404     syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1405 
1406     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
1407     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1408 
1409     // Update the resource tag (s/w tag) for On-Demand Sync
1410     m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1411 
1412     // Update GPU Sync tag for on demand synchronization
1413     if (m_osInterface->bTagResourceSync)
1414     {
1415 
1416         pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
1417         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(&cmdBuffer, nullptr, &pipeControlParams));
1418         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
1419     }
1420     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSubmitBlocks(
1421         stateHeapInterface,
1422         kernelState));
1423     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnUpdateGlobalCmdBufId(
1424         stateHeapInterface));
1425 
1426     // Add PipeControl to invalidate ISP and MediaState to avoid PageFault issue
1427     // This code is temporal and it will be moved to batch buffer end in short
1428     if (GFX_IS_GEN_9_OR_LATER(m_hwInterface->GetPlatform()))
1429     {
1430         MHW_PIPE_CONTROL_PARAMS pipeControlParams;
1431 
1432         MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams));
1433         pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
1434         pipeControlParams.bGenericMediaStateClear = true;
1435         pipeControlParams.bIndirectStatePointersDisable = true;
1436         pipeControlParams.bDisableCSStall = false;
1437         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(&cmdBuffer, nullptr, &pipeControlParams));
1438 
1439     }
1440 
1441     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
1442 
1443     // To clear the SSEU values in the hw interface struct, so next kernel can be programmed correctly
1444     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, false, true));
1445 
1446     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1447 
1448     CODECHAL_DEBUG_TOOL(
1449         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1450             &cmdBuffer,
1451             CODECHAL_MEDIA_STATE_OLP,
1452             "_DEC"));
1453     )
1454 
1455     if ( MOS_VE_SUPPORTED(m_osInterface))
1456     {
1457         CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false);
1458     }
1459 
1460     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw));
1461 
1462     if (m_statusQueryReportingEnabled)
1463     {
1464         CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_renderContextUsesNullHw));
1465     }
1466 
1467     m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext);
1468 
1469     return eStatus;
1470 }
1471 
CodechalDecodeVc1G11(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)1472 CodechalDecodeVc1G11::CodechalDecodeVc1G11(
1473     CodechalHwInterface   *hwInterface,
1474     CodechalDebugInterface* debugInterface,
1475     PCODECHAL_STANDARD_INFO standardInfo) :
1476     CodechalDecodeVc1(hwInterface, debugInterface, standardInfo)
1477 {
1478     CODECHAL_DECODE_FUNCTION_ENTER;
1479 
1480     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface);
1481     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
1482 
1483     Mos_CheckVirtualEngineSupported(m_osInterface, true, true);
1484 
1485     m_olpCurbeStaticDataLength = CODECHAL_DECODE_VC1_CURBE_SIZE_OLP;
1486 
1487     uint8_t *kernelBase = nullptr;
1488     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1489 #ifndef _FULL_OPEN_SOURCE
1490     if (GFX_IS_PRODUCT(hwInterface->GetPlatform(), IGFX_ICELAKE))
1491     {
1492         kernelBase = (uint8_t *)IGCODECKRN_G11;
1493     }
1494     else if (GFX_IS_PRODUCT(hwInterface->GetPlatform(), IGFX_ICELAKE_LP))
1495     {
1496         kernelBase = (uint8_t *)IGCODECKRN_G11_ICLLP;
1497     }
1498     else
1499     {
1500         kernelBase = (uint8_t *)IGCODECKRN_G11_ICLLP;
1501     }
1502 #endif
1503     eStatus = CodecHalGetKernelBinaryAndSize(
1504         kernelBase,
1505         IDR_CODEC_AllVC1_NV12,
1506         &m_olpKernelBase,
1507         &m_olpKernelSize);
1508     CODECHAL_DECODE_ASSERT(eStatus == MOS_STATUS_SUCCESS);
1509 
1510     hwInterface->GetStateHeapSettings()->dwNumSyncTags = CODECHAL_DECODE_VC1_NUM_SYNC_TAGS;
1511     hwInterface->GetStateHeapSettings()->dwIshSize =
1512         MOS_ALIGN_CEIL(m_olpKernelSize, (1 << MHW_KERNEL_OFFSET_SHIFT));
1513     hwInterface->GetStateHeapSettings()->dwDshSize = CODECHAL_DECODE_VC1_INITIAL_DSH_SIZE;
1514 }
1515 
~CodechalDecodeVc1G11()1516 CodechalDecodeVc1G11::~CodechalDecodeVc1G11()
1517 {
1518     CODECHAL_DECODE_FUNCTION_ENTER;
1519 
1520     if (m_veState != nullptr)
1521     {
1522         MOS_FreeMemAndSetNull(m_veState);
1523         m_veState = nullptr;
1524     }
1525 }
1526