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_avc_g11.cpp
24 //! \brief This modules implements Render interface layer for AVC decoding to be used on all operating systems/DDIs, across CODECHAL components.
25 //!
26
27 #include "codechal_decoder.h"
28 #include "codechal_decode_avc_g11.h"
29 #include "codechal_secure_decode_interface.h"
30 #include "mhw_vdbox_mfx_g11_X.h"
31 #include "hal_oca_interface.h"
32
AllocateStandard(CodechalSetting * settings)33 MOS_STATUS CodechalDecodeAvcG11::AllocateStandard(
34 CodechalSetting * settings)
35 {
36 CODECHAL_DECODE_FUNCTION_ENTER;
37
38 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
39
40 CODECHAL_DECODE_CHK_NULL_RETURN(settings);
41
42 CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeAvc::AllocateStandard(settings));
43
44 if ( MOS_VE_SUPPORTED(m_osInterface))
45 {
46 static_cast<MhwVdboxMfxInterfaceG11*>(m_mfxInterface)->DisableScalabilitySupport();
47
48 //single pipe VE initialize
49 m_veState = (PCODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE));
50 CODECHAL_DECODE_CHK_NULL_RETURN(m_veState);
51 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_InitInterface(m_osInterface, m_veState));
52 }
53
54 return eStatus;
55 }
56
~CodechalDecodeAvcG11()57 CodechalDecodeAvcG11::~CodechalDecodeAvcG11()
58 {
59 CODECHAL_DECODE_FUNCTION_ENTER;
60
61 if (m_veState)
62 {
63 MOS_FreeMemAndSetNull(m_veState);
64 m_veState = nullptr;
65 }
66
67 return;
68 }
69
SetGpuCtxCreatOption(CodechalSetting * codecHalSetting)70 MOS_STATUS CodechalDecodeAvcG11::SetGpuCtxCreatOption(
71 CodechalSetting * codecHalSetting)
72 {
73 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
74
75 CODECHAL_DECODE_FUNCTION_ENTER;
76
77 if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
78 {
79 CodechalDecode::SetGpuCtxCreatOption(codecHalSetting);
80 }
81 else
82 {
83 m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED);
84
85 bool sfcInUse = IsSfcInUse(codecHalSetting);
86
87 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_ConstructParmsForGpuCtxCreation(
88 m_veState,
89 (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt,
90 sfcInUse));
91
92 if (sfcInUse)
93 {
94 m_videoContext = MOS_GPU_CONTEXT_VIDEO4;
95
96 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
97 m_osInterface,
98 m_videoContext,
99 MOS_GPU_NODE_VIDEO,
100 m_gpuCtxCreatOpt));
101
102 MOS_GPUCTX_CREATOPTIONS createOption;
103 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
104 m_osInterface,
105 MOS_GPU_CONTEXT_VIDEO,
106 MOS_GPU_NODE_VIDEO,
107 &createOption));
108 }
109 else
110 {
111 m_videoContext = MOS_GPU_CONTEXT_VIDEO;
112 }
113 }
114
115 return eStatus;
116 }
117
SetFrameStates()118 MOS_STATUS CodechalDecodeAvcG11::SetFrameStates()
119 {
120 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
121
122 CODECHAL_DECODE_FUNCTION_ENTER;
123
124 CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeAvc::SetFrameStates());
125
126 if ( MOS_VE_SUPPORTED(m_osInterface))
127 {
128 if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
129 {
130 MOS_VIRTUALENGINE_SET_PARAMS vesetParams;
131
132 MOS_ZeroMemory(&vesetParams, sizeof(vesetParams));
133 #ifdef _DECODE_PROCESSING_SUPPORTED
134 vesetParams.bSFCInUse = m_sfcState->m_sfcPipeOut;
135 #else
136 vesetParams.bSFCInUse = false;
137 #endif
138 vesetParams.bNeedSyncWithPrevious = true;
139 vesetParams.bSameEngineAsLastSubmission = false;
140 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_SetHintParams(m_veState, &vesetParams));
141 }
142 }
143
144 return eStatus;
145 }
146
DecodeStateLevel()147 MOS_STATUS CodechalDecodeAvcG11::DecodeStateLevel()
148 {
149 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
150
151 CODECHAL_DECODE_FUNCTION_ENTER;
152
153 if (m_secureDecoder)
154 {
155 CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->Execute(this));
156 }
157
158 MOS_COMMAND_BUFFER cmdBuffer;
159 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
160
161 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
162 &cmdBuffer, true));
163
164 PIC_MHW_PARAMS picMhwParams;
165 CODECHAL_DECODE_CHK_STATUS_RETURN(InitPicMhwParams(&picMhwParams));
166
167 auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
168 HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
169
170 if (m_cencBuf && m_cencBuf->checkStatusRequired)
171 {
172 CODECHAL_DECODE_COND_ASSERTMESSAGE((m_vdboxIndex > m_hwInterface->GetMfxInterface()->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum");
173
174 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetCpInterface()->CheckStatusReportNum(
175 mmioRegisters,
176 m_cencBuf->bufIdx,
177 m_cencBuf->resStatus,
178 &cmdBuffer));
179 }
180
181 if (m_statusQueryReportingEnabled)
182 {
183 CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer));
184 }
185
186 CODECHAL_DECODE_CHK_STATUS_RETURN(AddPictureCmds(&cmdBuffer, &picMhwParams));
187
188 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
189
190 return eStatus;
191 }
192
DecodePrimitiveLevel()193 MOS_STATUS CodechalDecodeAvcG11::DecodePrimitiveLevel()
194 {
195 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
196
197 CODECHAL_DECODE_FUNCTION_ENTER;
198
199 CODECHAL_DECODE_CHK_NULL_RETURN(m_avcPicParams);
200
201 MOS_COMMAND_BUFFER cmdBuffer;
202 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
203
204 if (m_cencBuf)
205 {
206 CODECHAL_DECODE_CHK_STATUS_RETURN(SetCencBatchBuffer(&cmdBuffer));
207 }
208 else
209 {
210 CODECHAL_DECODE_CHK_STATUS_RETURN(ParseSlice(&cmdBuffer));
211 }
212
213 // Check if destination surface needs to be synchronized
214 MOS_SYNC_PARAMS syncParams;
215 syncParams = g_cInitSyncParams;
216 syncParams.GpuContext = m_videoContext;
217 syncParams.presSyncResource = &m_destSurface.OsResource;
218 syncParams.bReadOnly = false;
219 syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
220 syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
221
222 if (!CodecHal_PictureIsField(m_avcPicParams->CurrPic) ||
223 !m_isSecondField)
224 {
225 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
226 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
227
228 // Update the resource tag (s/w tag) for On-Demand Sync
229 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
230 }
231
232 #ifdef _DECODE_PROCESSING_SUPPORTED
233 DecodeProcessingParams *decProcessingParams = (DecodeProcessingParams *)m_decodeParams.m_procParams;
234 if (decProcessingParams != nullptr && decProcessingParams->m_isReferenceOnlyPattern)
235 {
236 CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(&cmdBuffer,
237 &m_destSurface.OsResource,
238 &decProcessingParams->m_outputSurface->OsResource,
239 decProcessingParams->m_outputSurface->dwSize,
240 m_destSurface.dwOffset,
241 decProcessingParams->m_outputSurface->dwOffset
242 ));
243 }
244 #endif
245
246 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
247 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
248
249 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
250 &cmdBuffer,
251 &flushDwParams));
252
253 // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
254 if (m_osInterface->bTagResourceSync &&
255 (!CodecHal_PictureIsField(m_avcPicParams->CurrPic) || m_isSecondField))
256 {
257 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
258 }
259
260 if (m_statusQueryReportingEnabled)
261 {
262 CodechalDecodeStatusReport decodeStatusReport;
263
264 decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
265 decodeStatusReport.m_currDecodedPic = m_avcPicParams->CurrPic;
266 decodeStatusReport.m_currDeblockedPic = m_avcPicParams->CurrPic;
267 decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
268 decodeStatusReport.m_currDecodedPicRes = m_avcRefList[m_avcPicParams->CurrPic.FrameIdx]->resRefPic;
269
270 CODECHAL_DEBUG_TOOL(
271 if (m_streamOutEnabled) {
272 // add current streamout buffer to the report and move onto the next one
273 decodeStatusReport.m_streamOutBuf = &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
274 decodeStatusReport.m_streamoutIdx = m_streamOutCurrBufIdx;
275 if (++m_streamOutCurrBufIdx >= CODECHAL_DECODE_NUM_STREAM_OUT_BUFFERS)
276 {
277 m_streamOutCurrBufIdx = 0;
278 }
279 // check next buffer in the list is free.
280 if (m_streamOutCurrStatusIdx[m_streamOutCurrBufIdx] != CODECHAL_DECODE_STATUS_NUM)
281 {
282 // We've run out of buffers. Temporarily lock the next one down to force a wait. Then mark it as free.
283 CodechalResLock ResourceLock(m_osInterface, &(m_streamOutBuffer[m_streamOutCurrBufIdx]));
284 ResourceLock.Lock(CodechalResLock::readOnly);
285
286 m_streamOutCurrStatusIdx[m_streamOutCurrBufIdx] = CODECHAL_DECODE_STATUS_NUM;
287 }
288 }
289
290 decodeStatusReport.m_secondField = CodecHal_PictureIsBottomField(m_avcPicParams->CurrPic);
291 decodeStatusReport.m_frameType = m_perfType;)
292
293 CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
294 }
295
296 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
297
298 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
299
300 bool syncCompleteFrame = (m_avcPicParams->seq_fields.chroma_format_idc == avcChromaFormatMono && !m_hwInterface->m_noHuC);
301 if (syncCompleteFrame)
302 {
303 syncParams = g_cInitSyncParams;
304 syncParams.GpuContext = m_videoContextForWa;
305 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
306
307 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
308
309 syncParams = g_cInitSyncParams;
310 syncParams.GpuContext = m_videoContext;
311 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
312
313 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
314 }
315
316 CODECHAL_DEBUG_TOOL(
317 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
318 &cmdBuffer,
319 CODECHAL_NUM_MEDIA_STATES,
320 "_DEC"));
321
322 //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
323 // m_debugInterface,
324 // &cmdBuffer));
325 )
326
327 if ( MOS_VE_SUPPORTED(m_osInterface))
328 {
329 CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, true);
330 }
331
332 HalOcaInterface::DumpCodechalParam(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, m_pCodechalOcaDumper, CODECHAL_AVC);
333 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
334
335 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
336
337 CODECHAL_DEBUG_TOOL(
338 m_mmc->UpdateUserFeatureKey(&m_destSurface);)
339 #ifdef _DECODE_PROCESSING_SUPPORTED
340 decProcessingParams = (DecodeProcessingParams *)m_decodeParams.m_procParams;
341 if (decProcessingParams != nullptr && !m_sfcState->m_sfcPipeOut && (m_isSecondField || m_avcPicParams->seq_fields.mb_adaptive_frame_field_flag))
342 {
343 CODECHAL_DECODE_CHK_STATUS_RETURN(m_fieldScalingInterface->DoFieldScaling(
344 decProcessingParams,
345 m_renderContext,
346 m_disableDecodeSyncLock,
347 m_disableLockForTranscode));
348 }
349 else
350 #endif
351 {
352 if (m_statusQueryReportingEnabled)
353 {
354 CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
355 }
356 }
357
358 // Needs to be re-set for Linux buffer re-use scenarios
359 m_avcRefList[m_avcPicParams->CurrPic.FrameIdx]->resRefPic =
360 m_destSurface.OsResource;
361
362 // Send the signal to indicate decode completion, in case On-Demand Sync is not present
363 if (!CodecHal_PictureIsField(m_avcPicParams->CurrPic) || m_isSecondField)
364 {
365 syncParams = g_cInitSyncParams;
366 syncParams.GpuContext = m_videoContext;
367 syncParams.presSyncResource = &m_destSurface.OsResource;
368
369 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
370 #ifdef _DECODE_PROCESSING_SUPPORTED
371 if (decProcessingParams && !m_sfcState->m_sfcPipeOut)
372 {
373 syncParams = g_cInitSyncParams;
374 syncParams.GpuContext = m_renderContext;
375 syncParams.presSyncResource = &decProcessingParams->m_outputSurface->OsResource;
376
377 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
378 }
379 #endif
380 }
381
382 #ifdef _DECODE_PROCESSING_SUPPORTED
383 CODECHAL_DEBUG_TOOL(
384 // Dump out downsampling result
385 if (decProcessingParams && decProcessingParams->m_outputSurface)
386 {
387 MOS_SURFACE dstSurface;
388 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
389 dstSurface.Format = Format_NV12;
390 dstSurface.OsResource = decProcessingParams->m_outputSurface->OsResource;
391
392 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
393 m_osInterface,
394 &dstSurface));
395
396 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
397 &dstSurface,
398 CodechalDbgAttr::attrSfcOutputSurface,
399 "SfcDstSurf"));
400 }
401 )
402 #endif
403 return eStatus;
404 }
405
CodechalDecodeAvcG11(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)406 CodechalDecodeAvcG11::CodechalDecodeAvcG11(
407 CodechalHwInterface * hwInterface,
408 CodechalDebugInterface *debugInterface,
409 PCODECHAL_STANDARD_INFO standardInfo) : CodechalDecodeAvc(hwInterface, debugInterface, standardInfo),
410 m_veState(nullptr)
411 {
412 CODECHAL_DECODE_FUNCTION_ENTER;
413
414 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
415
416 m_osInterface->pfnVirtualEngineSupported(m_osInterface, true, true);
417 };
418
419