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_vp8_g11.cpp
24 //! \brief Implements the decode interface extension for VP8.
25 //! \details Implements all functions and constants required by CodecHal for VP8 decoding.
26 //!
27
28 #include "codechal_decoder.h"
29 #include "codechal_decode_vp8_g11.h"
30 #include "mhw_vdbox_mfx_g11_X.h"
31 #include "hal_oca_interface.h"
32
~CodechalDecodeVp8G11()33 CodechalDecodeVp8G11::~CodechalDecodeVp8G11()
34 {
35 CODECHAL_DECODE_FUNCTION_ENTER;
36
37 if (m_veState != nullptr)
38 {
39 MOS_FreeMemAndSetNull(m_veState);
40 m_veState = nullptr;
41 }
42 }
43
SetGpuCtxCreatOption(CodechalSetting * codecHalSetting)44 MOS_STATUS CodechalDecodeVp8G11::SetGpuCtxCreatOption(
45 CodechalSetting * codecHalSetting)
46 {
47 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
48
49 CODECHAL_DECODE_FUNCTION_ENTER;
50
51 if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
52 {
53 CodechalDecode::SetGpuCtxCreatOption(codecHalSetting);
54 }
55 else
56 {
57 m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED);
58
59 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_ConstructParmsForGpuCtxCreation(
60 m_veState,
61 (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt,
62 false));
63 m_videoContext = MOS_GPU_CONTEXT_VIDEO; // Move functionality to CodecHalDecodeMapGpuNodeToGpuContex
64 }
65 return eStatus;
66 }
67
SetFrameStates()68 MOS_STATUS CodechalDecodeVp8G11::SetFrameStates()
69 {
70 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
71
72 CODECHAL_DECODE_FUNCTION_ENTER;
73
74 CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVp8::SetFrameStates());
75
76 if ( MOS_VE_SUPPORTED(m_osInterface))
77 {
78 if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
79 {
80 MOS_VIRTUALENGINE_SET_PARAMS vesetParams;
81
82 MOS_ZeroMemory(&vesetParams, sizeof(vesetParams));
83 vesetParams.bSFCInUse = false;
84 vesetParams.bNeedSyncWithPrevious = true;
85 vesetParams.bSameEngineAsLastSubmission = false;
86 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_SetHintParams(m_veState, &vesetParams));
87 }
88 }
89
90 return eStatus;
91 }
92
DecodeStateLevel()93 MOS_STATUS CodechalDecodeVp8G11::DecodeStateLevel()
94 {
95 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
96
97 CODECHAL_DECODE_FUNCTION_ENTER;
98
99 PCODEC_REF_LIST *vp8RefList = m_vp8RefList;
100
101 uint8_t lastRefPicIndex = m_vp8PicParams->ucLastRefPicIndex;
102 uint8_t goldenRefPicIndex = m_vp8PicParams->ucGoldenRefPicIndex;
103 uint8_t altRefPicIndex = m_vp8PicParams->ucAltRefPicIndex;
104
105 PMOS_SURFACE destSurface = &m_destSurface;
106 if (m_vp8PicParams->key_frame) // reference surface should be nullptr when key_frame == true
107 {
108 m_presLastRefSurface = nullptr;
109 m_presGoldenRefSurface = nullptr;
110 m_presAltRefSurface = nullptr;
111 }
112 else
113 {
114 if((Mos_ResourceIsNull(&vp8RefList[m_vp8PicParams->ucLastRefPicIndex]->resRefPic)) && (m_presLastRefSurface))
115 {
116 vp8RefList[m_vp8PicParams->ucLastRefPicIndex]->resRefPic = *m_presLastRefSurface;
117 }
118 else
119 {
120 m_presLastRefSurface = &(vp8RefList[lastRefPicIndex]->resRefPic);
121 }
122 if((Mos_ResourceIsNull(&vp8RefList[m_vp8PicParams->ucGoldenRefPicIndex]->resRefPic)) && (m_presGoldenRefSurface))
123 {
124 vp8RefList[m_vp8PicParams->ucGoldenRefPicIndex]->resRefPic = *m_presGoldenRefSurface;
125 }
126 else
127 {
128 m_presGoldenRefSurface = &(vp8RefList[goldenRefPicIndex]->resRefPic);
129 }
130 if((Mos_ResourceIsNull(&vp8RefList[m_vp8PicParams->ucAltRefPicIndex]->resRefPic)) && (m_presAltRefSurface))
131 {
132 vp8RefList[m_vp8PicParams->ucAltRefPicIndex]->resRefPic = *m_presAltRefSurface;
133 }
134 else
135 {
136 m_presAltRefSurface = &(vp8RefList[altRefPicIndex]->resRefPic);
137 }
138 }
139
140 MOS_COMMAND_BUFFER cmdBuffer;
141 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
142
143 auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
144 HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
145
146 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
147 pipeModeSelectParams.Mode = m_mode;
148 pipeModeSelectParams.bStreamOutEnabled = m_streamOutEnabled;
149 pipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled;
150 pipeModeSelectParams.bPreDeblockOutEnable = !m_deblockingEnabled;
151 pipeModeSelectParams.bShortFormatInUse = m_shortFormatInUse;
152
153 MHW_VDBOX_SURFACE_PARAMS surfaceParams;
154 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
155 surfaceParams.Mode = m_mode;
156 surfaceParams.psSurface = destSurface;
157
158 MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
159 pipeBufAddrParams.Mode = m_mode;
160 // MMC is only enabled for frame decoding and no interlaced support in VP8
161 // So no need to check frame/field type here.
162 if (m_deblockingEnabled)
163 {
164 pipeBufAddrParams.psPostDeblockSurface = destSurface;
165 }
166 else
167 {
168 pipeBufAddrParams.psPreDeblockSurface = destSurface;
169 }
170
171 #ifdef _MMC_SUPPORTED
172 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams));
173 #endif
174
175 // when there is no last, golden and alternate reference,
176 // the index is set to the destination frame index
177 pipeBufAddrParams.presReferences[CodechalDecodeLastRef] = m_presLastRefSurface;
178 pipeBufAddrParams.presReferences[CodechalDecodeGoldenRef] = m_presGoldenRefSurface;
179 pipeBufAddrParams.presReferences[CodechalDecodeAlternateRef] = m_presAltRefSurface;
180
181 pipeBufAddrParams.presMfdIntraRowStoreScratchBuffer = &m_resMfdIntraRowStoreScratchBuffer;
182 pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resMfdDeblockingFilterRowStoreScratchBuffer;
183 if (m_streamOutEnabled)
184 {
185 pipeBufAddrParams.presStreamOutBuffer =
186 &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
187 }
188
189 // set all ref pic addresses to valid addresses for error concealment purpose
190 for (uint32_t i = 0; i <= CodechalDecodeAlternateRef; i++)
191 {
192 if (pipeBufAddrParams.presReferences[i] == nullptr &&
193 MEDIA_IS_WA(m_waTable, WaDummyReference) &&
194 !Mos_ResourceIsNull(&m_dummyReference.OsResource))
195 {
196 pipeBufAddrParams.presReferences[i] = &m_dummyReference.OsResource;
197 }
198 }
199
200 #ifdef _MMC_SUPPORTED
201 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&pipeBufAddrParams));
202
203 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode));
204 #endif
205
206 MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
207 MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
208 indObjBaseAddrParams.Mode = m_mode;
209 indObjBaseAddrParams.dwDataSize = m_dataSize;
210 indObjBaseAddrParams.presDataBuffer = &m_resDataBuffer;
211
212 MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams;
213 MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
214 bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer;
215 bspBufBaseAddrParams.presMprRowStoreScratchBuffer = &m_resMprRowStoreScratchBuffer;
216
217 MHW_VDBOX_VP8_PIC_STATE vp8PicState;
218 vp8PicState.pVp8PicParams = m_vp8PicParams;
219 vp8PicState.pVp8IqMatrixParams = m_vp8IqMatrixParams;
220 vp8PicState.presSegmentationIdStreamBuffer = &m_resSegmentationIdStreamBuffer;
221 vp8PicState.dwCoefProbTableOffset = 0;
222 vp8PicState.presCoefProbBuffer = &m_resCoefProbBuffer;
223
224 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
225 &cmdBuffer, true));
226
227 if (m_statusQueryReportingEnabled)
228 {
229 CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer));
230 }
231
232 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
233
234 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
235
236 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams));
237
238 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
239
240 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams));
241
242 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVp8PicCmd(&cmdBuffer, &vp8PicState));
243
244 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
245
246 return eStatus;
247 }
248
DecodePrimitiveLevel()249 MOS_STATUS CodechalDecodeVp8G11::DecodePrimitiveLevel()
250 {
251 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
252
253 CODECHAL_DECODE_FUNCTION_ENTER;
254
255 CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
256
257 MOS_COMMAND_BUFFER cmdBuffer;
258 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
259
260 // Fill BSD Object Commands
261 MHW_VDBOX_VP8_BSD_PARAMS vp8BsdParams;
262 vp8BsdParams.pVp8PicParams = m_vp8PicParams;
263
264 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVp8BsdObjectCmd(&cmdBuffer, &vp8BsdParams));
265
266 // Check if destination surface needs to be synchronized
267 MOS_SYNC_PARAMS syncParams;
268 syncParams = g_cInitSyncParams;
269 syncParams.GpuContext = m_videoContext;
270 syncParams.presSyncResource = &m_destSurface.OsResource;
271 syncParams.bReadOnly = false;
272 syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
273 syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
274
275 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
276 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
277
278 // Update the resource tag (s/w tag) for On-Demand Sync
279 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
280
281 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
282 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
283
284 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
285
286 // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
287 if (m_osInterface->bTagResourceSync)
288 {
289 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
290 }
291
292 if (m_statusQueryReportingEnabled)
293 {
294 CodechalDecodeStatusReport decodeStatusReport;
295
296 decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
297 decodeStatusReport.m_currDecodedPic = m_vp8PicParams->CurrPic;
298 decodeStatusReport.m_currDeblockedPic = m_vp8PicParams->CurrPic;
299 decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
300 decodeStatusReport.m_currDecodedPicRes = m_vp8RefList[m_vp8PicParams->CurrPic.FrameIdx]->resRefPic;
301 CODECHAL_DEBUG_TOOL(
302 decodeStatusReport.m_secondField = CodecHal_PictureIsBottomField(m_vp8PicParams->CurrPic);
303 decodeStatusReport.m_frameType = m_perfType;)
304 CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
305 }
306
307 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
308
309 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
310
311 CODECHAL_DEBUG_TOOL(
312 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
313 &cmdBuffer,
314 CODECHAL_NUM_MEDIA_STATES,
315 "_DEC"));
316 )
317
318 if ( MOS_VE_SUPPORTED(m_osInterface))
319 {
320 CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, true);
321 }
322
323 if (m_huCCopyInUse)
324 {
325 syncParams = g_cInitSyncParams;
326 syncParams.GpuContext = m_videoContextForWa;
327 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
328
329 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
330
331 syncParams = g_cInitSyncParams;
332 syncParams.GpuContext = m_videoContext;
333 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
334
335 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
336
337 m_huCCopyInUse = false;
338 }
339
340 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
341
342 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
343
344 CODECHAL_DEBUG_TOOL(
345 m_mmc->UpdateUserFeatureKey(&m_destSurface);)
346
347 if (m_statusQueryReportingEnabled)
348 {
349 CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
350 }
351
352 // Needs to be re-set for Linux buffer re-use scenarios
353 m_vp8RefList[m_vp8PicParams->ucCurrPicIndex]->resRefPic =
354 m_destSurface.OsResource;
355
356 // Send the signal to indicate decode completion, in case On-Demand Sync is not present
357 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
358
359 return eStatus;
360 }
361
AllocateStandard(CodechalSetting * settings)362 MOS_STATUS CodechalDecodeVp8G11::AllocateStandard(
363 CodechalSetting * settings)
364 {
365 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
366
367 CODECHAL_DECODE_FUNCTION_ENTER;
368
369 CODECHAL_DECODE_CHK_NULL_RETURN(settings);
370
371 CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVp8::AllocateStandard(settings));
372
373 if ( MOS_VE_SUPPORTED(m_osInterface))
374 {
375 static_cast<MhwVdboxMfxInterfaceG11*>(m_mfxInterface)->DisableScalabilitySupport();
376
377 //single pipe VE initialize
378 m_veState = (PCODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE));
379 CODECHAL_DECODE_CHK_NULL_RETURN(m_veState);
380 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_InitInterface(m_osInterface, m_veState));
381 }
382
383 return eStatus;
384 }
385
CodechalDecodeVp8G11(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)386 CodechalDecodeVp8G11::CodechalDecodeVp8G11(
387 CodechalHwInterface *hwInterface,
388 CodechalDebugInterface* debugInterface,
389 PCODECHAL_STANDARD_INFO standardInfo) :
390 CodechalDecodeVp8(hwInterface, debugInterface, standardInfo)
391 {
392 CODECHAL_DECODE_FUNCTION_ENTER;
393
394 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
395
396 m_osInterface->pfnVirtualEngineSupported(m_osInterface, true, true);
397 }
398
399