1 /*
2 * Copyright (c) 2022-2023, 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 ddi_decode_functions.cpp
24 //! \brief ddi decode functions implementaion.
25 //!
26
27 #include <sys/ioctl.h>
28 #include <fcntl.h>
29 #include <linux/fb.h>
30
31 #include "ddi_decode_functions.h"
32 #include "media_libva_util_next.h"
33 #include "media_libva_common_next.h"
34 #include "ddi_register_components_specific.h"
35 #include "decode_status_report.h"
36 #include "vphal_render_vebox_memdecomp.h"
37 #include "media_libva_interface_next.h"
38 #include "ddi_decode_trace_specific.h"
39
40 #define DDI_DECODE_SFC_MAX_WIDTH 4096
41 #define DDI_DECODE_SFC_MAX_HEIGHT 4096
42 #define DDI_DECODE_SFC_MIN_WIDTH 128
43 #define DDI_DECODE_SFC_MIN_HEIGHT 128
44 #define DDI_DECODE_HCP_SFC_MAX_WIDTH (16*1024)
45 #define DDI_DECODE_HCP_SFC_MAX_HEIGHT (16*1024)
46
47 #ifndef VA_ENCRYPTION_TYPE_NONE
48 #define VA_ENCRYPTION_TYPE_NONE 0x00000000
49 #endif
50
51 using namespace decode;
52
CreateConfig(VADriverContextP ctx,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attribList,int32_t numAttribs,VAConfigID * configId)53 VAStatus DdiDecodeFunctions::CreateConfig (
54 VADriverContextP ctx,
55 VAProfile profile,
56 VAEntrypoint entrypoint,
57 VAConfigAttrib *attribList,
58 int32_t numAttribs,
59 VAConfigID *configId)
60 {
61 DDI_CODEC_FUNC_ENTER;
62
63 VAStatus status = VA_STATUS_SUCCESS;
64 DDI_CODEC_CHK_NULL(configId, "nullptr configId", VA_STATUS_ERROR_INVALID_PARAMETER);
65 if(numAttribs)
66 {
67 DDI_CODEC_CHK_NULL(attribList, "nullptr attribList", VA_STATUS_ERROR_INVALID_PARAMETER);
68 }
69
70 PDDI_MEDIA_CONTEXT mediaCtx = GetMediaContext(ctx);
71 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
72 DDI_CODEC_CHK_NULL(mediaCtx->m_capsNext, "nullptr m_caps", VA_STATUS_ERROR_INVALID_PARAMETER);
73 DDI_CODEC_CHK_NULL(mediaCtx->m_capsNext->m_capsTable, "nullptr m_capsTable", VA_STATUS_ERROR_INVALID_PARAMETER);
74
75 status = mediaCtx->m_capsNext->CreateConfig(profile, entrypoint, attribList, numAttribs, configId);
76 DDI_CODEC_CHK_RET(status, "Create common config failed");
77
78 VAConfigAttrib decAttributes[3];
79
80 decAttributes[0].type = VAConfigAttribDecSliceMode;
81 decAttributes[0].value = VA_DEC_SLICE_MODE_NORMAL;
82 decAttributes[1].type = VAConfigAttribEncryption;
83 decAttributes[1].value = VA_ENCRYPTION_TYPE_NONE;
84 decAttributes[2].type = VAConfigAttribDecProcessing;
85 decAttributes[2].value = VA_DEC_PROCESSING_NONE;
86
87 int32_t i = 0, j = 0;
88 for (j = 0; j < numAttribs; j++)
89 {
90 for (i = 0; i < 3; i++)
91 {
92 if (attribList[j].type == decAttributes[i].type)
93 {
94 decAttributes[i].value = attribList[j].value;
95 break;
96 }
97 }
98 }
99
100 auto configList = mediaCtx->m_capsNext->GetConfigList();
101 DDI_CODEC_CHK_NULL(configList, "Get configList failed", VA_STATUS_ERROR_INVALID_PARAMETER);
102
103 for (int i = 0; i < configList->size(); i++)
104 {
105 if ((configList->at(i).profile == profile) &&
106 (configList->at(i).entrypoint == entrypoint))
107 {
108 if (decAttributes[0].value == configList->at(i).componentData.data.sliceMode &&
109 decAttributes[1].value == configList->at(i).componentData.data.encryptType &&
110 decAttributes[2].value == configList->at(i).componentData.data.processType)
111 {
112 uint32_t curConfigID = ADD_CONFIG_ID_DEC_OFFSET(i);
113 if (!mediaCtx->m_capsNext->m_capsTable->IsDecConfigId(curConfigID))
114 {
115 DDI_CODEC_ASSERTMESSAGE("DDI: Invalid configID.");
116 return VA_STATUS_ERROR_INVALID_CONFIG;
117 }
118 *configId = curConfigID;
119 return VA_STATUS_SUCCESS;
120 }
121 }
122 }
123
124 *configId = 0xFFFFFFFF;
125 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
126 }
127
CreateContext(VADriverContextP ctx,VAConfigID configId,int32_t pictureWidth,int32_t pictureHeight,int32_t flag,VASurfaceID * renderTargets,int32_t renderTargetsNum,VAContextID * context)128 VAStatus DdiDecodeFunctions::CreateContext(
129 VADriverContextP ctx,
130 VAConfigID configId,
131 int32_t pictureWidth,
132 int32_t pictureHeight,
133 int32_t flag,
134 VASurfaceID *renderTargets,
135 int32_t renderTargetsNum,
136 VAContextID *context)
137 {
138 DDI_CODEC_FUNC_ENTER;
139
140 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
141 {
142 DECODE_EVENTDATA_VA_CREATECONTEXT_START eventData;
143 eventData.configId = configId;
144 MOS_TraceEvent(EVENT_DECODE_DDI_CREATECONTEXTVA, EVENT_TYPE_START, &eventData, sizeof(eventData), NULL, 0);
145 }
146 #endif
147
148 PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_DDI);
149
150 DDI_CODEC_CHK_NULL(ctx, "nullptr ctx in Decode CreateContext", VA_STATUS_ERROR_INVALID_CONTEXT);
151
152 if (renderTargetsNum > DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT)
153 {
154 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
155 }
156
157 PDDI_MEDIA_CONTEXT mediaCtx = GetMediaContext(ctx);
158 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
159 DDI_CODEC_CHK_NULL(mediaCtx->m_capsNext, "nullptr m_capsNext", VA_STATUS_ERROR_INVALID_CONTEXT);
160 DDI_CODEC_CHK_NULL(mediaCtx->m_capsNext->m_capsTable, "nullptr m_capsTable", VA_STATUS_ERROR_INVALID_CONTEXT);
161
162 DDI_UNUSED(flag);
163
164 ConfigLinux *configItem = nullptr;
165 configItem = mediaCtx->m_capsNext->m_capsTable->QueryConfigItemFromIndex(configId + DDI_CODEC_GEN_CONFIG_ATTRIBUTES_DEC_BASE);
166 DDI_CODEC_CHK_NULL(configItem, "Invalid config id!", VA_STATUS_ERROR_INVALID_PARAMETER);
167
168 PDDI_DECODE_CONTEXT decCtx = nullptr;
169 VAStatus va = VA_STATUS_SUCCESS;
170
171 DdiDecodeBase *ddiDecode = DdiDecodeFactory::Create(ComponentInfo{configItem->profile, configItem->entrypoint});
172 DDI_CODEC_CHK_NULL(ddiDecode, "DDI: failed to Create Decode Context in CreateContext", VA_STATUS_ERROR_ALLOCATION_FAILED);
173
174 va = ddiDecode->CheckDecodeResolution(configItem, pictureWidth, pictureHeight);
175 if (va != VA_STATUS_SUCCESS)
176 {
177 return va;
178 }
179
180 if (ddiDecode->BasicInit(configItem) != VA_STATUS_SUCCESS)
181 {
182 MOS_Delete(ddiDecode);
183 return VA_STATUS_ERROR_ALLOCATION_FAILED;
184 }
185
186 /* one instance of DdiDecodeBase is created for the codec */
187 decCtx = ddiDecode->m_decodeCtx;
188 if (nullptr == decCtx)
189 {
190 if (ddiDecode)
191 {
192 MOS_Delete(ddiDecode);
193 }
194 return VA_STATUS_ERROR_ALLOCATION_FAILED;
195 }
196
197 decCtx->pMediaCtx = mediaCtx;
198 decCtx->m_ddiDecodeNext = ddiDecode;
199
200 MOS_CONTEXT mosCtx = {};
201 mosCtx.bufmgr = mediaCtx->pDrmBufMgr;
202 mosCtx.fd = mediaCtx->fd;
203 mosCtx.iDeviceId = mediaCtx->iDeviceId;
204 mosCtx.m_skuTable = mediaCtx->SkuTable;
205 mosCtx.m_waTable = mediaCtx->WaTable;
206 mosCtx.m_gtSystemInfo = *mediaCtx->pGtSystemInfo;
207 mosCtx.m_platform = mediaCtx->platform;
208 mosCtx.ppMediaMemDecompState = &mediaCtx->pMediaMemDecompState;
209 mosCtx.pfnMemoryDecompress = mediaCtx->pfnMemoryDecompress;
210 mosCtx.pfnMediaMemoryCopy = mediaCtx->pfnMediaMemoryCopy;
211 mosCtx.pfnMediaMemoryCopy2D = mediaCtx->pfnMediaMemoryCopy2D;
212 mosCtx.ppMediaCopyState = &mediaCtx->pMediaCopyState;
213 mosCtx.m_auxTableMgr = mediaCtx->m_auxTableMgr;
214 mosCtx.pGmmClientContext = mediaCtx->pGmmClientContext;
215 mosCtx.m_osDeviceContext = mediaCtx->m_osDeviceContext;
216 mosCtx.m_apoMosEnabled = true;
217 mosCtx.m_userSettingPtr = mediaCtx->m_userSettingPtr;
218 mosCtx.pPerfData = (PERF_DATA *)MOS_AllocAndZeroMemory(sizeof(PERF_DATA));
219
220 if (nullptr == mosCtx.pPerfData)
221 {
222 va = VA_STATUS_ERROR_ALLOCATION_FAILED;
223 CleanUp(ctx, decCtx);
224 return va;
225 }
226
227 ddiDecode->ContextInit(pictureWidth, pictureHeight);
228
229 // Initialize DDI level CP interface
230 decCtx->pCpDdiInterfaceNext = CreateDdiCpNext(&mosCtx);
231 if (nullptr == decCtx->pCpDdiInterfaceNext)
232 {
233 va = VA_STATUS_ERROR_ALLOCATION_FAILED;
234 CleanUp(ctx, decCtx);
235 return va;
236 }
237
238 va = ddiDecode->CodecHalInit(mediaCtx, &mosCtx);
239 if (va != VA_STATUS_SUCCESS)
240 {
241 CleanUp(ctx, decCtx);
242 return va;
243 }
244
245 GetDisplayInfo(ctx);
246
247 // register render targets
248 for (int32_t i = 0; i < renderTargetsNum; i++)
249 {
250 DDI_MEDIA_SURFACE *surface;
251 surface = MediaLibvaCommonNext::GetSurfaceFromVASurfaceID(mediaCtx, renderTargets[i]);
252 if (nullptr == surface)
253 {
254 DDI_CODEC_ASSERTMESSAGE("DDI: invalid render target %d in vpgCreateContext.",i);
255 va = VA_STATUS_ERROR_INVALID_SURFACE;
256 CleanUp(ctx, decCtx);
257 return va;
258 }
259
260 if (VA_STATUS_SUCCESS != ddiDecode->RegisterRTSurfaces(&decCtx->RTtbl, surface))
261 {
262 va = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
263 CleanUp(ctx, decCtx);
264 return va;
265 }
266 }
267
268 MosUtilities::MosLockMutex(&mediaCtx->DecoderMutex);
269 PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaContextHeapElmt = MediaLibvaUtilNext::DdiAllocPVAContextFromHeap(mediaCtx->pDecoderCtxHeap);
270 if (nullptr == vaContextHeapElmt)
271 {
272 MosUtilities::MosUnlockMutex(&mediaCtx->DecoderMutex);
273 va = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
274 CleanUp(ctx, decCtx);
275 return va;
276 }
277
278 vaContextHeapElmt->pVaContext = (void*)decCtx;
279 mediaCtx->uiNumDecoders++;
280 *context = (VAContextID)(vaContextHeapElmt->uiVaContextID + DDI_MEDIA_SOFTLET_VACONTEXTID_DECODER_OFFSET);
281 MosUtilities::MosUnlockMutex(&mediaCtx->DecoderMutex);
282
283 // init the RecListSUrfaceID for checking DPB.
284 for(int32_t i = 0; i < CODEC_AVC_NUM_UNCOMPRESSED_SURFACE; i++)
285 {
286 decCtx->RecListSurfaceID[i] = VA_INVALID_ID;
287 }
288
289 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
290 {
291 DECODE_EVENTDATA_VA_CREATECONTEXT eventData;
292 eventData.configId = configId;
293 eventData.hRes = va;
294 MOS_TraceEvent(EVENT_DECODE_DDI_CREATECONTEXTVA, EVENT_TYPE_END, &eventData, sizeof(eventData), NULL, 0);
295 }
296 #endif
297
298 return va;
299 }
300
FreeBufferHeapElements(VADriverContextP ctx,PDDI_DECODE_CONTEXT decCtx)301 void DdiDecodeFunctions::FreeBufferHeapElements(VADriverContextP ctx, PDDI_DECODE_CONTEXT decCtx)
302 {
303 DDI_CODEC_FUNC_ENTER;
304
305 DDI_CODEC_CHK_NULL(ctx, "nullptr ctx in Decode DestroyContext", );
306 PDDI_MEDIA_CONTEXT mediaCtx = GetMediaContext(ctx);
307 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx", );
308
309 PDDI_MEDIA_HEAP bufferHeap = mediaCtx->pBufferHeap;
310 if (nullptr == bufferHeap)
311 {
312 return;
313 }
314
315 PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapBase = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pHeapBase;
316 if (nullptr == mediaBufferHeapBase)
317 {
318 return;
319 }
320
321 int32_t bufNums = mediaCtx->uiNumBufs;
322
323 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
324 {
325 DECODE_EVENTDATA_VA_FREEBUFFERHEAPELEMENTS eventData;
326 eventData.bufNums = bufNums;
327 MOS_TraceEvent(EVENT_DECODE_DDI_FREEBUFFERHEAPELEMENTSVA, EVENT_TYPE_START, &eventData, sizeof(eventData), NULL, 0);
328 }
329 #endif
330
331 for (int32_t elementId = 0; bufNums > 0; ++elementId)
332 {
333 PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapElmt = &mediaBufferHeapBase[elementId];
334 if (nullptr == mediaBufferHeapElmt->pBuffer)
335 continue;
336
337 void *pDecContext = nullptr;
338 uint32_t i = (uint32_t)mediaBufferHeapElmt->uiVaBufferID;
339 DDI_CODEC_CHK_LESS(i, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "invalid buffer id", );
340 MosUtilities::MosLockMutex(&mediaCtx->BufferMutex);
341 PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufHeapElement = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)mediaCtx->pBufferHeap->pHeapBase;
342 bufHeapElement += i;
343 pDecContext = bufHeapElement->pCtx;
344 MosUtilities::MosUnlockMutex(&mediaCtx->BufferMutex);
345
346 if (pDecContext == decCtx)
347 {
348 DDI_MEDIA_BUFFER *buf = MediaLibvaCommonNext::GetBufferFromVABufferID(mediaCtx, mediaBufferHeapElmt->uiVaBufferID);
349
350 if (nullptr == buf)
351 {
352 return;
353 }
354
355 if (buf->uiType == VASliceDataBufferType ||
356 buf->uiType == VAProtectedSliceDataBufferType ||
357 buf->uiType == VASliceParameterBufferType)
358 {
359 MediaLibvaInterfaceNext::DestroyBuffer(ctx, mediaBufferHeapElmt->uiVaBufferID);
360 }
361 }
362 // Ensure the non-empty buffer to be destroyed.
363 --bufNums;
364 }
365
366 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
367 {
368 DECODE_EVENTDATA_VA_FREEBUFFERHEAPELEMENTS eventData;
369 eventData.bufNums = bufNums;
370 MOS_TraceEvent(EVENT_DECODE_DDI_FREEBUFFERHEAPELEMENTSVA, EVENT_TYPE_END, &eventData, sizeof(eventData), NULL, 0);
371 }
372 #endif
373
374 return;
375 }
376
DestroyContext(VADriverContextP ctx,VAContextID context)377 VAStatus DdiDecodeFunctions::DestroyContext(
378 VADriverContextP ctx,
379 VAContextID context)
380 {
381 DDI_CODEC_FUNC_ENTER;
382
383 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
384 {
385 DECODE_EVENTDATA_VA_DESTROYCONTEXT_START eventData;
386 eventData.context = context;
387 MOS_TraceEvent(EVENT_DECODE_DDI_DESTROYCONTEXTVA, EVENT_TYPE_START, &eventData, sizeof(eventData), NULL, 0);
388 }
389 #endif
390
391 DDI_CODEC_CHK_NULL(ctx, "nullptr ctx in Decode DestroyContext", VA_STATUS_ERROR_INVALID_CONTEXT);
392 PDDI_MEDIA_CONTEXT mediaCtx = GetMediaContext(ctx);
393 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
394 uint32_t ctxType;
395 PDDI_DECODE_CONTEXT decCtx = (decltype(decCtx))MediaLibvaCommonNext::GetContextFromContextID(ctx, context, &ctxType);
396 DDI_CODEC_CHK_NULL(decCtx, "nullptr decCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
397 DDI_CODEC_CHK_NULL(decCtx->pCodecHal, "nullptr decCtx->pCodecHal", VA_STATUS_ERROR_INVALID_CONTEXT);
398
399 /* Free the context id from the context_heap earlier */
400 uint32_t decIndex = (uint32_t)context & DDI_MEDIA_MASK_VACONTEXTID;
401 MosUtilities::MosLockMutex(&mediaCtx->DecoderMutex);
402 MediaLibvaUtilNext::DdiReleasePVAContextFromHeap(mediaCtx->pDecoderCtxHeap, decIndex);
403 mediaCtx->uiNumDecoders--;
404 MosUtilities::MosUnlockMutex(&mediaCtx->DecoderMutex);
405
406 FreeBufferHeapElements(ctx, decCtx);
407
408 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
409 {
410 DECODE_EVENTDATA_VA_DESTROYCONTEXT eventData;
411 eventData.context = context;
412 MOS_TraceEvent(EVENT_DECODE_DDI_DESTROYCONTEXTVA, EVENT_TYPE_END, &eventData, sizeof(eventData), NULL, 0);
413 }
414 #endif
415
416 if (decCtx->m_ddiDecodeNext)
417 {
418 CleanUp(ctx, decCtx);
419 return VA_STATUS_SUCCESS;
420 }
421
422 return VA_STATUS_SUCCESS;
423 }
424
CreateBuffer(VADriverContextP ctx,VAContextID context,VABufferType type,uint32_t size,uint32_t elementsNum,void * data,VABufferID * bufId)425 VAStatus DdiDecodeFunctions::CreateBuffer(
426 VADriverContextP ctx,
427 VAContextID context,
428 VABufferType type,
429 uint32_t size,
430 uint32_t elementsNum,
431 void *data,
432 VABufferID *bufId)
433 {
434 DDI_CODEC_FUNC_ENTER;
435
436 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
437 {
438 MOS_TraceEvent(EVENT_DECODE_DDI_CREATEBUFFERVA, EVENT_TYPE_START, NULL, 0, NULL, 0);
439 }
440 #endif
441
442 DDI_CODEC_CHK_NULL(ctx, "nullptr ctx in Decode CreateBuffer", VA_STATUS_ERROR_INVALID_CONTEXT);
443 uint32_t ctxType;
444 PDDI_DECODE_CONTEXT decCtx = (decltype(decCtx))MediaLibvaCommonNext::GetContextFromContextID(ctx, context, &ctxType);
445 DDI_CODEC_CHK_NULL(decCtx, "nullptr decCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
446
447 *bufId = VA_INVALID_ID;
448 if (decCtx->m_ddiDecodeNext)
449 {
450 DDI_CHK_RET(decCtx->m_ddiDecodeNext->CreateBuffer(type, size, elementsNum, data, bufId), "Decode CreateBuffer failed!");
451 }
452
453 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
454 {
455 DECODE_EVENTDATA_VA_CREATEBUFFER eventData;
456 eventData.type = type;
457 eventData.size = size;
458 eventData.numElements = elementsNum;
459 eventData.bufId = bufId;
460 MOS_TraceEvent(EVENT_DECODE_DDI_CREATEBUFFERVA, EVENT_TYPE_END, &eventData, sizeof(eventData), NULL, 0);
461 }
462 #endif
463
464 return VA_STATUS_SUCCESS;
465 }
466
BeginPicture(VADriverContextP ctx,VAContextID context,VASurfaceID renderTarget)467 VAStatus DdiDecodeFunctions::BeginPicture(
468 VADriverContextP ctx,
469 VAContextID context,
470 VASurfaceID renderTarget)
471 {
472 DDI_CODEC_FUNC_ENTER;
473
474 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
475 {
476 DECODE_EVENTDATA_VA_BEGINPICTURE_START eventData;
477 eventData.FrameIndex = DecodeFrameIndex;
478 MOS_TraceEvent(EVENT_DECODE_DDI_BEGINPICTUREVA, EVENT_TYPE_START, &eventData, sizeof(eventData), NULL, 0);
479 }
480 #endif
481
482 PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_DDI);
483
484 DDI_CODEC_CHK_NULL(ctx, "nullptr context in Decode BeginPicture!", VA_STATUS_ERROR_INVALID_CONTEXT);
485
486 uint32_t ctxType = 0;
487 PDDI_DECODE_CONTEXT decCtx = (decltype(decCtx))MediaLibvaCommonNext::GetContextFromContextID(ctx, context, &ctxType);
488 DDI_CODEC_CHK_NULL(decCtx, "Null decCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
489
490 if (decCtx->pCpDdiInterfaceNext)
491 {
492 VAStatus ret = decCtx->pCpDdiInterfaceNext->IsAttachedSessionAlive();
493 DDI_CODEC_CHK_CONDITION(VA_STATUS_SUCCESS != ret, "Session not alive!", ret);
494 }
495
496 if (decCtx->m_ddiDecodeNext)
497 {
498 VAStatus va = decCtx->m_ddiDecodeNext->BeginPicture(ctx, context, renderTarget);
499
500 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
501 {
502 DECODE_EVENTDATA_VA_BEGINPICTURE eventData;
503 eventData.FrameIndex = DecodeFrameIndex;
504 eventData.hRes = va;
505 MOS_TraceEvent(EVENT_DECODE_DDI_BEGINPICTUREVA, EVENT_TYPE_END, &eventData, sizeof(eventData), NULL, 0);
506 }
507 #endif
508
509 return va;
510 }
511
512 return VA_STATUS_SUCCESS;
513 }
514
RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t buffersNum)515 VAStatus DdiDecodeFunctions::RenderPicture(
516 VADriverContextP ctx,
517 VAContextID context,
518 VABufferID *buffers,
519 int32_t buffersNum)
520 {
521 DDI_CODEC_FUNC_ENTER;
522
523 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
524 {
525 DECODE_EVENTDATA_VA_RENDERPICTURE_START eventData;
526 eventData.buffers = buffers;
527 MOS_TraceEvent(EVENT_DECODE_DDI_RENDERPICTUREVA, EVENT_TYPE_START, &eventData, sizeof(eventData), NULL, 0);
528 }
529 #endif
530
531 PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_DDI);
532
533 DDI_CODEC_CHK_NULL(ctx, "nullptr ctx in decode RenderPicture", VA_STATUS_ERROR_INVALID_CONTEXT);
534 // assume the VAContextID is decoder ID
535 uint32_t ctxType = 0;
536 PDDI_DECODE_CONTEXT decCtx = (decltype(decCtx))MediaLibvaCommonNext::GetContextFromContextID(ctx, context, &ctxType);
537 DDI_CODEC_CHK_NULL(decCtx, "Null decCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
538
539 if (decCtx->pCpDdiInterfaceNext)
540 {
541 DDI_CHK_RET(decCtx->pCpDdiInterfaceNext->IsAttachedSessionAlive(), "Session not alive!");
542 }
543
544 VAStatus va = VA_STATUS_SUCCESS;
545 int32_t priorityIndexInBuffers = -1;
546 int32_t numOfBuffers = buffersNum;
547 int32_t priority = 0;
548 bool updatePriority = false;
549
550 priorityIndexInBuffers = MediaLibvaCommonNext::GetGpuPriority(ctx, buffers, numOfBuffers, &updatePriority, &priority);
551 if (priorityIndexInBuffers != -1)
552 {
553 if (updatePriority)
554 {
555 va = SetGpuPriority(ctx, decCtx, priority);
556 if (va != VA_STATUS_SUCCESS)
557 {
558 return va;
559 }
560 }
561 MediaLibvaCommonNext::MovePriorityBufferIdToEnd(buffers, priorityIndexInBuffers, numOfBuffers);
562 numOfBuffers--;
563 }
564
565 if (numOfBuffers == 0)
566 {
567 return va;
568 }
569
570 if (decCtx->m_ddiDecodeNext)
571 {
572 va = decCtx->m_ddiDecodeNext->RenderPicture(ctx, context, buffers, numOfBuffers);
573
574 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
575 {
576 DECODE_EVENTDATA_VA_RENDERPICTURE eventData;
577 eventData.buffers = buffers;
578 eventData.hRes = va;
579 eventData.numBuffers = buffersNum;
580 MOS_TraceEvent(EVENT_DECODE_DDI_RENDERPICTUREVA, EVENT_TYPE_END, &eventData, sizeof(eventData), NULL, 0);
581 }
582 #endif
583
584 return va;
585 }
586
587 return VA_STATUS_SUCCESS;
588 }
589
EndPicture(VADriverContextP ctx,VAContextID context)590 VAStatus DdiDecodeFunctions::EndPicture(
591 VADriverContextP ctx,
592 VAContextID context)
593 {
594 DDI_CODEC_FUNC_ENTER;
595
596 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
597 {
598 DECODE_EVENTDATA_VA_ENDPICTURE_START eventData;
599 eventData.FrameIndex = DecodeFrameIndex;
600 MOS_TraceEvent(EVENT_DECODE_DDI_ENDPICTUREVA, EVENT_TYPE_START, &eventData, sizeof(eventData), NULL, 0);
601 }
602 #endif
603
604 PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_DDI);
605
606 DDI_CODEC_CHK_NULL(ctx, "nullptr ctx in Decode EndPicture", VA_STATUS_ERROR_INVALID_CONTEXT);
607
608 uint32_t ctxType = 0;
609 PDDI_DECODE_CONTEXT decCtx = (decltype(decCtx))MediaLibvaCommonNext::GetContextFromContextID(ctx, context, &ctxType);
610 DDI_CODEC_CHK_NULL(decCtx, "Null decCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
611
612 if (decCtx->pCpDdiInterfaceNext)
613 {
614 DDI_CHK_RET(decCtx->pCpDdiInterfaceNext->IsAttachedSessionAlive(), "Session not alive!");
615
616 if (decCtx->pCpDdiInterfaceNext->IsCencProcessing())
617 {
618 VAStatus va = decCtx->pCpDdiInterfaceNext->EndPicture(ctx, context);
619
620 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
621 {
622 DECODE_EVENTDATA_VA_ENDPICTURE eventData;
623 eventData.FrameIndex = DecodeFrameIndex;
624 eventData.hRes = va;
625 MOS_TraceEvent(EVENT_DECODE_DDI_ENDPICTUREVA, EVENT_TYPE_END, &eventData, sizeof(eventData), NULL, 0);
626 DecodeFrameIndex++;
627 }
628 #endif
629
630 return va;
631 }
632 }
633
634 if (decCtx->m_ddiDecodeNext)
635 {
636 VAStatus va = decCtx->m_ddiDecodeNext->EndPicture(ctx, context);
637
638 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
639 {
640 DECODE_EVENTDATA_VA_ENDPICTURE eventData;
641 eventData.FrameIndex = DecodeFrameIndex;
642 eventData.hRes = va;
643 MOS_TraceEvent(EVENT_DECODE_DDI_ENDPICTUREVA, EVENT_TYPE_END, &eventData, sizeof(eventData), NULL, 0);
644 DecodeFrameIndex++;
645 }
646 #endif
647
648 return va;
649 }
650
651 return VA_STATUS_SUCCESS;
652 }
653
QueryVideoProcPipelineCaps(VADriverContextP ctx,VAContextID context,VABufferID * filters,uint32_t filtersNum,VAProcPipelineCaps * pipelineCaps)654 VAStatus DdiDecodeFunctions::QueryVideoProcPipelineCaps(
655 VADriverContextP ctx,
656 VAContextID context,
657 VABufferID *filters,
658 uint32_t filtersNum,
659 VAProcPipelineCaps *pipelineCaps)
660 {
661 DDI_CODEC_FUNC_ENTER;
662
663 PDDI_MEDIA_CONTEXT mediaCtx = nullptr;
664
665 DDI_CODEC_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
666 DDI_CODEC_CHK_NULL(pipelineCaps, "nullptr pipelineCaps", VA_STATUS_ERROR_INVALID_PARAMETER);
667 if (filtersNum > 0)
668 {
669 DDI_CODEC_CHK_NULL(filters, "nullptr filters", VA_STATUS_ERROR_INVALID_PARAMETER);
670 }
671
672 mediaCtx = GetMediaContext(ctx);
673 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
674
675 pipelineCaps->pipeline_flags = VA_PROC_PIPELINE_FAST;
676 pipelineCaps->filter_flags = 0;
677 pipelineCaps->rotation_flags = (1 << VA_ROTATION_NONE) | (1 << VA_ROTATION_90) | (1 << VA_ROTATION_180) | (1 << VA_ROTATION_270);
678 pipelineCaps->mirror_flags = VA_MIRROR_HORIZONTAL | VA_MIRROR_VERTICAL;
679 pipelineCaps->blend_flags = VA_BLEND_GLOBAL_ALPHA | VA_BLEND_PREMULTIPLIED_ALPHA | VA_BLEND_LUMA_KEY;
680 pipelineCaps->num_forward_references = DDI_CODEC_NUM_FWD_REF;
681 pipelineCaps->num_backward_references = DDI_CODEC_NUM_BK_REF;
682 pipelineCaps->input_color_standards = const_cast<VAProcColorStandardType*>(m_vpInputColorStd);
683 pipelineCaps->num_input_color_standards = DDI_VP_NUM_INPUT_COLOR_STD;
684 pipelineCaps->output_color_standards = const_cast<VAProcColorStandardType*>(m_vpOutputColorStd);
685 pipelineCaps->num_output_color_standards = DDI_VP_NUM_OUT_COLOR_STD;
686
687 pipelineCaps->num_input_pixel_formats = 1;
688 pipelineCaps->input_pixel_format[0] = VA_FOURCC_NV12;
689 pipelineCaps->num_output_pixel_formats = 1;
690 pipelineCaps->output_pixel_format[0] = VA_FOURCC_NV12;
691
692 if ((MEDIA_IS_SKU(&(mediaCtx->SkuTable), FtrHCP2SFCPipe)))
693 {
694 pipelineCaps->max_input_width = DDI_DECODE_HCP_SFC_MAX_WIDTH;
695 pipelineCaps->max_input_height = DDI_DECODE_HCP_SFC_MAX_HEIGHT;
696 }
697 else
698 {
699 pipelineCaps->max_input_width = DDI_DECODE_SFC_MAX_WIDTH;
700 pipelineCaps->max_input_height = DDI_DECODE_SFC_MAX_HEIGHT;
701 }
702 pipelineCaps->min_input_width = DDI_DECODE_SFC_MIN_WIDTH;
703 pipelineCaps->min_input_height = DDI_DECODE_SFC_MIN_HEIGHT;
704 pipelineCaps->max_output_width = DDI_DECODE_SFC_MAX_WIDTH;
705 pipelineCaps->max_output_height = DDI_DECODE_SFC_MAX_HEIGHT;
706 pipelineCaps->min_output_width = DDI_DECODE_SFC_MIN_WIDTH;
707 pipelineCaps->min_output_height = DDI_DECODE_SFC_MIN_HEIGHT;
708
709 return VA_STATUS_SUCCESS;
710 }
711
MapBufferInternal(DDI_MEDIA_CONTEXT * mediaCtx,VABufferID buf_id,void ** pbuf,uint32_t flag)712 VAStatus DdiDecodeFunctions::MapBufferInternal(
713 DDI_MEDIA_CONTEXT *mediaCtx,
714 VABufferID buf_id,
715 void **pbuf,
716 uint32_t flag)
717 {
718 DDI_CODEC_FUNC_ENTER;
719
720 MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_START, &buf_id, sizeof(buf_id), &flag, sizeof(flag));
721
722 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx in Decode MapBufferInternal", VA_STATUS_ERROR_INVALID_CONTEXT);
723 DDI_CODEC_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
724 DDI_CODEC_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid bufferId", VA_STATUS_ERROR_INVALID_PARAMETER);
725 DDI_MEDIA_BUFFER *buf = MediaLibvaCommonNext::GetBufferFromVABufferID(mediaCtx, buf_id);
726 DDI_CODEC_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_BUFFER);
727
728 // The context is nullptr when the buffer is created from DeriveImage
729 // So doesn't need to check the context for all cases
730 // Only check the context in dec/enc mode
731 VAStatus vaStatus = VA_STATUS_SUCCESS;
732 uint32_t ctxType = MediaLibvaCommonNext::GetCtxTypeFromVABufferID(mediaCtx, buf_id);
733 void *ctxPtr = MediaLibvaCommonNext::GetCtxFromVABufferID(mediaCtx, buf_id);
734 DDI_CODEC_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
735 DDI_CODEC_COM_BUFFER_MGR *bufMgr = nullptr;
736 PDDI_DECODE_CONTEXT decCtx = nullptr;
737
738 switch (ctxType)
739 {
740 case DDI_MEDIA_CONTEXT_TYPE_DECODER:
741 decCtx = (decltype(decCtx)) GetDecContextFromPVOID(ctxPtr);
742 bufMgr = &(decCtx->BufMgr);
743 break;
744 case DDI_MEDIA_CONTEXT_TYPE_MEDIA:
745 break;
746 default:
747 return VA_STATUS_ERROR_INVALID_BUFFER;
748 }
749
750 MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_INFO, &ctxType, sizeof(ctxType), &buf->uiType, sizeof(uint32_t));
751 switch ((int32_t)buf->uiType)
752 {
753 case VASliceDataBufferType:
754 case VAProtectedSliceDataBufferType:
755 case VABitPlaneBufferType:
756 *pbuf = (void *)(buf->pData + buf->uiOffset);
757 break;
758
759 case VASliceParameterBufferType:
760 if(decCtx != nullptr)
761 {
762 switch (decCtx->wMode)
763 {
764 case CODECHAL_DECODE_MODE_AVCVLD:
765 if (decCtx->bShortFormatInUse)
766 *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base) + buf->uiOffset);
767 else
768 *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264) + buf->uiOffset);
769 break;
770 case CODECHAL_DECODE_MODE_MPEG2VLD:
771 *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_MPEG2.pVASliceParaBufMPEG2) + buf->uiOffset);
772 break;
773 case CODECHAL_DECODE_MODE_VC1VLD:
774 *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1) + buf->uiOffset);
775 break;
776 case CODECHAL_DECODE_MODE_JPEG:
777 *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG) + buf->uiOffset);
778 break;
779 case CODECHAL_DECODE_MODE_VP8VLD:
780 *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_VP8.pVASliceParaBufVP8) + buf->uiOffset);
781 break;
782 case CODECHAL_DECODE_MODE_HEVCVLD:
783 if (decCtx->bShortFormatInUse)
784 *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC) + buf->uiOffset);
785 else
786 {
787 if (!decCtx->m_ddiDecodeNext->IsRextProfile())
788 *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC) + buf->uiOffset);
789 else
790 *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext) + buf->uiOffset);
791 }
792 break;
793 case CODECHAL_DECODE_MODE_VP9VLD:
794 *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9) + buf->uiOffset);
795 break;
796 case CODECHAL_DECODE_MODE_AV1VLD:
797 case CODECHAL_DECODE_MODE_VVCVLD:
798 *pbuf = (void *)((uint8_t*)(bufMgr->pCodecSlcParamReserved) + buf->uiOffset);
799 break;
800 default:
801 break;
802 }
803 }
804 break;
805
806 case VADecodeStreamoutBufferType:
807 if (buf->bo)
808 {
809 uint32_t timeout_NS = 100000000;
810 while (0 != mos_bo_wait(buf->bo, timeout_NS))
811 {
812 // Just loop while gem_bo_wait times-out.
813 }
814 *pbuf = MediaLibvaUtilNext::LockBuffer(buf, flag);
815 }
816 break;
817
818 case VAStatsStatisticsParameterBufferType:
819 *pbuf = (void *)(buf->pData + buf->uiOffset);
820 break;
821
822 case VAProbabilityBufferType:
823 *pbuf = (void *)(buf->pData + buf->uiOffset);
824 break;
825
826 case VAImageBufferType:
827 default:
828 if ((buf->format != Media_Format_CPU) && (MediaLibvaInterfaceNext::MediaFormatToOsFormat(buf->format) != VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT))
829 {
830 MosUtilities::MosLockMutex(&mediaCtx->BufferMutex);
831 // A critical section starts.
832 // Make sure not to bailout with a return until the section ends.
833 if (nullptr != buf->pSurface && Media_Format_CPU != buf->format)
834 {
835 vaStatus = MediaLibvaInterfaceNext::MediaMemoryDecompress(mediaCtx, buf->pSurface);
836 }
837
838 if (VA_STATUS_SUCCESS == vaStatus)
839 {
840 *pbuf = MediaLibvaUtilNext::LockBuffer(buf, flag);
841 if (nullptr == *pbuf)
842 {
843 vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
844 }
845 }
846
847 // The critical section ends.
848 MosUtilities::MosUnlockMutex(&mediaCtx->BufferMutex);
849 }
850 else
851 {
852 *pbuf = (void *)(buf->pData + buf->uiOffset);
853 }
854 break;
855 }
856
857 MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
858 return vaStatus;
859 }
860
UnmapBuffer(DDI_MEDIA_CONTEXT * mediaCtx,VABufferID buf_id)861 VAStatus DdiDecodeFunctions::UnmapBuffer(
862 DDI_MEDIA_CONTEXT *mediaCtx,
863 VABufferID buf_id)
864 {
865 DDI_CODEC_FUNC_ENTER;
866
867 MOS_TraceEventExt(EVENT_VA_UNMAP, EVENT_TYPE_START, &buf_id, sizeof(buf_id), nullptr, 0);
868
869 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx in Decode UnmapBuffer", VA_STATUS_ERROR_INVALID_CONTEXT);
870 DDI_CODEC_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
871 DDI_CODEC_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid bufferId", VA_STATUS_ERROR_INVALID_PARAMETER);
872 DDI_MEDIA_BUFFER *buf = MediaLibvaCommonNext::GetBufferFromVABufferID(mediaCtx, buf_id);
873 DDI_CODEC_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_BUFFER);
874
875 // The context is nullptr when the buffer is created from DeriveImage
876 // So doesn't need to check the context for all cases
877 // Only check the context in dec/enc mode
878 void *ctxPtr = MediaLibvaCommonNext::GetCtxFromVABufferID(mediaCtx, buf_id);;
879 DDI_CODEC_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
880 uint32_t ctxType = MediaLibvaCommonNext::GetCtxTypeFromVABufferID(mediaCtx, buf_id);
881 DDI_CODEC_COM_BUFFER_MGR *bufMgr = nullptr;
882 PDDI_DECODE_CONTEXT decCtx = nullptr;
883
884 switch (ctxType)
885 {
886 case DDI_MEDIA_CONTEXT_TYPE_DECODER:
887 decCtx = (decltype(decCtx)) GetDecContextFromPVOID(ctxPtr);
888 bufMgr = &(decCtx->BufMgr);
889 break;
890 case DDI_MEDIA_CONTEXT_TYPE_MEDIA:
891 break;
892 default:
893 return VA_STATUS_ERROR_INVALID_BUFFER;
894 }
895
896 switch ((int32_t)buf->uiType)
897 {
898 case VASliceDataBufferType:
899 case VAProtectedSliceDataBufferType:
900 case VABitPlaneBufferType:
901 break;
902 case VADecodeStreamoutBufferType:
903 if (buf->bo)
904 {
905 MediaLibvaUtilNext::UnlockBuffer(buf);
906 }
907 break;
908 case VAImageBufferType:
909 default:
910 if ((buf->format != Media_Format_CPU) && (MediaLibvaInterfaceNext::MediaFormatToOsFormat(buf->format) != VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT))
911 {
912 MosUtilities::MosLockMutex(&mediaCtx->BufferMutex);
913 MediaLibvaUtilNext::UnlockBuffer(buf);
914 MosUtilities::MosUnlockMutex(&mediaCtx->BufferMutex);
915 }
916 break;
917 }
918
919 MOS_TraceEventExt(EVENT_VA_UNMAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
920 return VA_STATUS_SUCCESS;
921 }
922
DestroyBuffer(DDI_MEDIA_CONTEXT * mediaCtx,VABufferID buffer_id)923 VAStatus DdiDecodeFunctions::DestroyBuffer(
924 DDI_MEDIA_CONTEXT *mediaCtx,
925 VABufferID buffer_id)
926 {
927 DDI_CODEC_FUNC_ENTER;
928
929 MOS_TraceEventExt(EVENT_VA_FREE_BUFFER, EVENT_TYPE_START, &buffer_id, sizeof(buffer_id), nullptr, 0);
930
931 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx in Decode DestroyBuffer", VA_STATUS_ERROR_INVALID_CONTEXT);
932 DDI_CODEC_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
933 DDI_CODEC_CHK_LESS((uint32_t)buffer_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid bufferId", VA_STATUS_ERROR_INVALID_PARAMETER);
934 DDI_MEDIA_BUFFER *buf = MediaLibvaCommonNext::GetBufferFromVABufferID(mediaCtx, buffer_id);
935 DDI_CODEC_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_BUFFER);
936
937 void *ctxPtr = MediaLibvaCommonNext::GetCtxFromVABufferID(mediaCtx, buffer_id);
938 uint32_t ctxType = MediaLibvaCommonNext::GetCtxTypeFromVABufferID(mediaCtx, buffer_id);
939 DDI_CODEC_COM_BUFFER_MGR *bufMgr = nullptr;
940 PDDI_DECODE_CONTEXT decCtx = nullptr;
941
942 switch (ctxType)
943 {
944 case DDI_MEDIA_CONTEXT_TYPE_DECODER:
945 decCtx = (decltype(decCtx)) GetDecContextFromPVOID(ctxPtr);
946 bufMgr = &(decCtx->BufMgr);
947 break;
948 case DDI_MEDIA_CONTEXT_TYPE_MEDIA:
949 break;
950 default:
951 return VA_STATUS_ERROR_INVALID_BUFFER;
952 }
953
954 switch ((int32_t)buf->uiType)
955 {
956 case VASliceDataBufferType:
957 case VAProtectedSliceDataBufferType:
958 ReleaseBsBuffer(bufMgr, buf);
959 break;
960 case VABitPlaneBufferType:
961 ReleaseBpBuffer(bufMgr, buf);
962 break;
963 case VAProbabilityBufferType:
964 ReleaseBpBuffer(bufMgr, buf);
965 break;
966 case VASliceParameterBufferType:
967 ReleaseSliceControlBuffer(ctxType, ctxPtr, buf);
968 break;
969 case VAPictureParameterBufferType:
970 break;
971 case VADecodeStreamoutBufferType:
972 MediaLibvaUtilNext::FreeBuffer(buf);
973 break;
974 case VAImageBufferType:
975 if (buf->format == Media_Format_CPU)
976 {
977 MOS_FreeMemory(buf->pData);
978 }
979 else
980 {
981 MediaLibvaUtilNext::UnRefBufObjInMediaBuffer(buf);
982 if (buf->uiExportcount)
983 {
984 buf->bPostponedBufFree = true;
985 MOS_TraceEventExt(EVENT_VA_FREE_BUFFER, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
986 return VA_STATUS_SUCCESS;
987 }
988 }
989 break;
990 case VAProcPipelineParameterBufferType:
991 case VAProcFilterParameterBufferType:
992 MOS_FreeMemory(buf->pData);
993 break;
994 case VASubsetsParameterBufferType:
995 case VAIQMatrixBufferType:
996 case VAHuffmanTableBufferType:
997 MOS_FreeMemory(buf->pData);
998 break;
999 default:
1000 MOS_FreeMemory(buf->pData);
1001 break;
1002 }
1003 MOS_FreeMemory(buf);
1004
1005 MediaLibvaInterfaceNext::DestroyBufFromVABufferID(mediaCtx, buffer_id);
1006 MOS_TraceEventExt(EVENT_VA_FREE_BUFFER, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
1007 return VA_STATUS_SUCCESS;
1008 }
1009
StatusCheck(PDDI_MEDIA_CONTEXT mediaCtx,DDI_MEDIA_SURFACE * surface,VASurfaceID surfaceId)1010 VAStatus DdiDecodeFunctions::StatusCheck(
1011 PDDI_MEDIA_CONTEXT mediaCtx,
1012 DDI_MEDIA_SURFACE *surface,
1013 VASurfaceID surfaceId)
1014 {
1015 DDI_CODEC_FUNC_ENTER;
1016
1017 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx in Decode StatusCheck", VA_STATUS_ERROR_INVALID_CONTEXT);
1018 DDI_CODEC_CHK_NULL(surface, "nullptr surface in Decode StatusCheck", VA_STATUS_ERROR_INVALID_CONTEXT);
1019
1020 uint32_t i = 0;
1021 PDDI_DECODE_CONTEXT decCtx = (decltype(decCtx))surface->pDecCtx;
1022 MediaLibvaUtilNext_LockGuard guard(&mediaCtx->SurfaceMutex);
1023
1024 Codechal *codecHal = decCtx->pCodecHal;
1025 // return success just avoid vaDestroyContext is ahead of vaSyncSurface
1026 DDI_CODEC_CHK_NULL(codecHal, "nullptr decCtx->pCodecHal", VA_STATUS_SUCCESS);
1027
1028 // return success just avoid vaDestroyContext is ahead of vaSyncSurface
1029 DecodePipelineAdapter *decoder = dynamic_cast<DecodePipelineAdapter *>(codecHal);
1030 DDI_CODEC_CHK_NULL(decoder, "nullptr (DecodePipelineAdapter *decoder)", VA_STATUS_SUCCESS);
1031 return StatusReport(mediaCtx, decoder, surface);
1032 }
1033
StatusReport(PDDI_MEDIA_CONTEXT mediaCtx,DecodePipelineAdapter * decoder,DDI_MEDIA_SURFACE * surface)1034 VAStatus DdiDecodeFunctions::StatusReport(
1035 PDDI_MEDIA_CONTEXT mediaCtx,
1036 DecodePipelineAdapter *decoder,
1037 DDI_MEDIA_SURFACE *surface)
1038 {
1039 DDI_CODEC_FUNC_ENTER;
1040
1041 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
1042 {
1043 MOS_TraceEvent(EVENT_DECODE_DDI_STATUSREPORTVA, EVENT_TYPE_START, NULL, 0, NULL, 0);
1044 }
1045 #endif
1046
1047 if (surface->curStatusReportQueryState == DDI_MEDIA_STATUS_REPORT_QUERY_STATE_PENDING) // TODO: Use soltlet class
1048 {
1049 uint32_t uNumCompletedReport = decoder->GetCompletedReport();
1050 if (uNumCompletedReport != 0)
1051 {
1052 DDI_CODEC_CHK_CONDITION((uNumCompletedReport == 0), "No report available at all", VA_STATUS_ERROR_OPERATION_FAILED);
1053
1054 for (uint32_t i = 0; i < uNumCompletedReport; i++)
1055 {
1056 DecodeStatusReportData tempNewReport;
1057 MOS_ZeroMemory(&tempNewReport, sizeof(CodechalDecodeStatusReport));
1058 MOS_STATUS eStatus = decoder->GetStatusReport(&tempNewReport, 1);
1059 DDI_CODEC_CHK_CONDITION(MOS_STATUS_SUCCESS != eStatus, "Get status report fail", VA_STATUS_ERROR_OPERATION_FAILED);
1060
1061 MOS_LINUX_BO *bo = tempNewReport.currDecodedPicRes.bo;
1062
1063 if ((tempNewReport.codecStatus == CODECHAL_STATUS_SUCCESSFUL) ||
1064 (tempNewReport.codecStatus == CODECHAL_STATUS_ERROR) ||
1065 (tempNewReport.codecStatus == CODECHAL_STATUS_RESET) ||
1066 (tempNewReport.codecStatus == CODECHAL_STATUS_INCOMPLETE))
1067 {
1068 PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapElmt = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)mediaCtx->pSurfaceHeap->pHeapBase;
1069
1070 uint32_t j = 0;
1071 for (j = 0; j < mediaCtx->pSurfaceHeap->uiAllocatedHeapElements && mediaSurfaceHeapElmt != nullptr; j++, mediaSurfaceHeapElmt++)
1072 {
1073 if (mediaSurfaceHeapElmt->pSurface != nullptr && bo == mediaSurfaceHeapElmt->pSurface->bo)
1074 {
1075 mediaSurfaceHeapElmt->pSurface->curStatusReport.decode.status = (uint32_t)tempNewReport.codecStatus;
1076 mediaSurfaceHeapElmt->pSurface->curStatusReport.decode.errMbNum = (uint32_t)tempNewReport.numMbsAffected;
1077 mediaSurfaceHeapElmt->pSurface->curStatusReport.decode.crcValue = (uint32_t)tempNewReport.frameCrc;
1078 mediaSurfaceHeapElmt->pSurface->curStatusReportQueryState = DDI_MEDIA_STATUS_REPORT_QUERY_STATE_COMPLETED;
1079 break;
1080 }
1081 }
1082
1083 if (j == mediaCtx->pSurfaceHeap->uiAllocatedHeapElements)
1084 {
1085 return VA_STATUS_ERROR_OPERATION_FAILED;
1086 }
1087 }
1088 else
1089 {
1090 // return failed if queried INCOMPLETE or UNAVAILABLE report.
1091 return VA_STATUS_ERROR_OPERATION_FAILED;
1092 }
1093 }
1094 }
1095 // The surface is not busy in HW, but uNumCompletedReport is 0, treat as engine reset
1096 else
1097 {
1098 surface->curStatusReport.decode.status = CODECHAL_STATUS_INCOMPLETE;
1099 surface->curStatusReportQueryState = DDI_MEDIA_STATUS_REPORT_QUERY_STATE_COMPLETED;
1100 DDI_ASSERTMESSAGE("No report available at all! Engine reset may have occured.");
1101 }
1102 }
1103
1104 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
1105 {
1106 MOS_TraceEvent(EVENT_DECODE_DDI_STATUSREPORTVA, EVENT_TYPE_END, NULL, 0, NULL, 0);
1107 }
1108 #endif
1109
1110 // check the report ptr of current surface.
1111 if (surface->curStatusReportQueryState == DDI_MEDIA_STATUS_REPORT_QUERY_STATE_COMPLETED)
1112 {
1113 if (surface->curStatusReport.decode.status == CODECHAL_STATUS_SUCCESSFUL)
1114 {
1115 return VA_STATUS_SUCCESS;
1116 }
1117 else if (surface->curStatusReport.decode.status == CODECHAL_STATUS_ERROR)
1118 {
1119 return VA_STATUS_ERROR_DECODING_ERROR;
1120 }
1121 else if (surface->curStatusReport.decode.status == CODECHAL_STATUS_INCOMPLETE ||
1122 surface->curStatusReport.decode.status == CODECHAL_STATUS_RESET ||
1123 surface->curStatusReport.decode.status == CODECHAL_STATUS_UNAVAILABLE)
1124 {
1125 return mediaCtx->bMediaResetEnable ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_HW_BUSY;
1126 }
1127 }
1128 else
1129 {
1130 return VA_STATUS_ERROR_OPERATION_FAILED;
1131 }
1132 return VA_STATUS_SUCCESS;
1133 }
1134
QuerySurfaceError(VADriverContextP ctx,VASurfaceID renderTarget,VAStatus errorStatus,void ** errorInfo)1135 VAStatus DdiDecodeFunctions::QuerySurfaceError(
1136 VADriverContextP ctx,
1137 VASurfaceID renderTarget,
1138 VAStatus errorStatus,
1139 void **errorInfo)
1140 {
1141 DDI_CODEC_FUNC_ENTER;
1142
1143 DDI_UNUSED(errorStatus);
1144
1145 DDI_CODEC_CHK_NULL(ctx, "nullptr ctx in Decode QuerySurfaceError", VA_STATUS_ERROR_INVALID_CONTEXT);
1146
1147 PDDI_MEDIA_CONTEXT mediaCtx = GetMediaContext(ctx);
1148 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
1149
1150 DDI_MEDIA_SURFACE *surface = MediaLibvaCommonNext::GetSurfaceFromVASurfaceID(mediaCtx, renderTarget);
1151 DDI_CODEC_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
1152
1153
1154 PDDI_DECODE_CONTEXT decCtx = (decltype(decCtx))surface->pDecCtx;
1155 DDI_CODEC_CHK_NULL(decCtx, "nullptr surface->pDecCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
1156
1157 VASurfaceDecodeMBErrors *surfaceErrors = decCtx->vaSurfDecErrOutput;
1158 DDI_CODEC_CHK_NULL(surfaceErrors , "nullptr surfaceErrors", VA_STATUS_ERROR_INVALID_CONTEXT);
1159
1160 VAStatus vaStatus = VA_STATUS_SUCCESS;
1161
1162 MosUtilities::MosLockMutex(&mediaCtx->SurfaceMutex);
1163 if (surface->curStatusReportQueryState == DDI_MEDIA_STATUS_REPORT_QUERY_STATE_COMPLETED)
1164 {
1165 if (errorStatus != -1 && surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_DECODER)
1166 {
1167 if(surface->curStatusReport.decode.status == CODECHAL_STATUS_ERROR ||
1168 surface->curStatusReport.decode.status == CODECHAL_STATUS_RESET)
1169 {
1170 surfaceErrors[1].status = -1;
1171 surfaceErrors[0].status = 1;
1172 surfaceErrors[0].start_mb = 0;
1173 surfaceErrors[0].end_mb = 0;
1174 surfaceErrors[0].num_mb = surface->curStatusReport.decode.errMbNum;
1175 #if VA_CHECK_VERSION(1, 20, 0)
1176 surfaceErrors[0].decode_error_type = (surface->curStatusReport.decode.status == CODECHAL_STATUS_RESET) ? VADecodeReset : VADecodeMBError;
1177 #else
1178 surfaceErrors[0].decode_error_type = VADecodeMBError;
1179 #endif
1180 *errorInfo = surfaceErrors;
1181 MosUtilities::MosUnlockMutex(&mediaCtx->SurfaceMutex);
1182 return VA_STATUS_SUCCESS;
1183 }
1184 #if VA_CHECK_VERSION(1, 20, 0)
1185 else if (surface->curStatusReport.decode.status == CODECHAL_STATUS_INCOMPLETE ||
1186 surface->curStatusReport.decode.status == CODECHAL_STATUS_UNAVAILABLE)
1187 {
1188 MOS_ZeroMemory(&surfaceErrors[0], sizeof(VASurfaceDecodeMBErrors));
1189 surfaceErrors[1].status = -1;
1190 surfaceErrors[0].status = 1;
1191 surfaceErrors[0].decode_error_type = VADecodeReset;
1192 *errorInfo = surfaceErrors;
1193 MosUtilities::MosUnlockMutex(&mediaCtx->SurfaceMutex);
1194 return VA_STATUS_SUCCESS;
1195 }
1196 #endif
1197 }
1198
1199 if (errorStatus == -1 && surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_DECODER)
1200 //&& surface->curStatusReport.decode.status == CODECHAL_STATUS_SUCCESSFUL) // get the crc value whatever the status is
1201 {
1202 if (nullptr == decCtx->m_ddiDecodeNext)
1203 {
1204 DDI_CODEC_ASSERTMESSAGE("nullptr decCtx->m_ddiDecodeNext");
1205 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
1206 }
1207 else
1208 {
1209 if (decCtx->m_ddiDecodeNext->GetStandard() != CODECHAL_AVC)
1210 {
1211 vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
1212 }
1213 else
1214 {
1215 *errorInfo = (void *)&surface->curStatusReport.decode.crcValue;
1216 }
1217 }
1218
1219 MosUtilities::MosUnlockMutex(&mediaCtx->SurfaceMutex);
1220 return vaStatus;
1221 }
1222
1223 if (surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_VP &&
1224 surface->curStatusReport.vpp.status == CODECHAL_STATUS_ERROR)
1225 {
1226 MosUtilities::MosUnlockMutex(&mediaCtx->SurfaceMutex);
1227 return VA_STATUS_SUCCESS;
1228 }
1229 }
1230
1231 surfaceErrors[0].status = -1;
1232 MosUtilities::MosUnlockMutex(&mediaCtx->SurfaceMutex);
1233 return VA_STATUS_SUCCESS;
1234 }
1235
GetDisplayInfo(VADriverContextP ctx)1236 int32_t DdiDecodeFunctions::GetDisplayInfo(VADriverContextP ctx)
1237 {
1238 DDI_CODEC_FUNC_ENTER;
1239
1240 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
1241 {
1242 MOS_TraceEvent(EVENT_DECODE_DDI_DISPLAYINFOVA, EVENT_TYPE_START, NULL, 0, NULL, 0);
1243 }
1244 #endif
1245
1246 PDDI_MEDIA_CONTEXT mediaDrvCtx = GetMediaContext(ctx);
1247 int32_t fd = -1;
1248 struct fb_var_screeninfo vsinfo;
1249 vsinfo.xres = 0;
1250 vsinfo.yres = 0;
1251
1252 fd = open("/dev/graphics/fb0",O_RDONLY);
1253 if (fd >= 0)
1254 {
1255 if (ioctl(fd, FBIOGET_VSCREENINFO, &vsinfo) < 0)
1256 {
1257 DDI_CODEC_NORMALMESSAGE("ioctl: fail to get display information!\n");
1258 }
1259 close(fd);
1260 }
1261 else
1262 {
1263 DDI_CODEC_NORMALMESSAGE("GetDisplayInfo: cannot open device!\n");
1264 }
1265
1266 if (vsinfo.xres <= 0 || vsinfo.yres <= 0)
1267 {
1268 vsinfo.xres = 1280;
1269 vsinfo.yres = 720;
1270 }
1271 mediaDrvCtx->uiDisplayWidth = vsinfo.xres;
1272 mediaDrvCtx->uiDisplayHeight = vsinfo.yres;
1273
1274 DDI_CODEC_NORMALMESSAGE("DDI:mediaDrvCtx->uiDisplayWidth =%d", mediaDrvCtx->uiDisplayWidth);
1275 DDI_CODEC_NORMALMESSAGE("DDI:mediaDrvCtx->uiDisplayHeight =%d",mediaDrvCtx->uiDisplayHeight);
1276
1277 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
1278 {
1279 DECODE_EVENTDATA_VA_DISPLAYINFO eventData;
1280 eventData.uiDisplayWidth = mediaDrvCtx->uiDisplayWidth;
1281 eventData.uiDisplayHeight = mediaDrvCtx->uiDisplayHeight;
1282 MOS_TraceEvent(EVENT_DECODE_DDI_DISPLAYINFOVA, EVENT_TYPE_END, &eventData, sizeof(eventData), NULL, 0);
1283 }
1284 #endif
1285
1286 return 0;
1287 }
1288
CleanUp(VADriverContextP ctx,PDDI_DECODE_CONTEXT decCtx)1289 void DdiDecodeFunctions::CleanUp(
1290 VADriverContextP ctx,
1291 PDDI_DECODE_CONTEXT decCtx)
1292 {
1293 DDI_CODEC_FUNC_ENTER;
1294
1295 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
1296 {
1297 MOS_TraceEvent(EVENT_DECODE_DDI_CLEARUPVA, EVENT_TYPE_START, NULL, 0, NULL, 0);
1298 }
1299 #endif
1300
1301 if (decCtx)
1302 {
1303 if (decCtx->m_ddiDecodeNext)
1304 {
1305 decCtx->m_ddiDecodeNext->DestroyContext(ctx);
1306 MOS_Delete(decCtx->m_ddiDecodeNext);
1307 MOS_FreeMemory(decCtx);
1308 decCtx = nullptr;
1309 }
1310 }
1311
1312 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
1313 {
1314 MOS_TraceEvent(EVENT_DECODE_DDI_CLEARUPVA, EVENT_TYPE_END, NULL, 0, NULL, 0);
1315 }
1316 #endif
1317
1318 return;
1319 }
1320
SetGpuPriority(VADriverContextP ctx,PDDI_DECODE_CONTEXT decCtx,int32_t priority)1321 VAStatus DdiDecodeFunctions::SetGpuPriority(
1322 VADriverContextP ctx,
1323 PDDI_DECODE_CONTEXT decCtx,
1324 int32_t priority)
1325 {
1326 DDI_CODEC_FUNC_ENTER;
1327
1328 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
1329 {
1330 MOS_TraceEvent(EVENT_DECODE_DDI_SETGPUPRIORITYVA, EVENT_TYPE_START, NULL, 0, NULL, 0);
1331 }
1332 #endif
1333
1334 DDI_CODEC_CHK_NULL(ctx, "nullptr ctx in Decode SetGpuPriority", VA_STATUS_ERROR_INVALID_CONTEXT);
1335 DDI_CODEC_CHK_NULL(decCtx, "nullptr decCtx in Decode SetGpuPriority", VA_STATUS_ERROR_INVALID_CONTEXT);
1336
1337 PDDI_MEDIA_CONTEXT mediaCtx = GetMediaContext(ctx);
1338 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
1339
1340 // Set the priority for Gpu
1341 if (decCtx->pCodecHal != nullptr)
1342 {
1343 PMOS_INTERFACE osInterface = decCtx->pCodecHal->GetOsInterface();
1344 DDI_CODEC_CHK_NULL(osInterface, "nullptr osInterface.", VA_STATUS_ERROR_ALLOCATION_FAILED);
1345 osInterface->pfnSetGpuPriority(osInterface, priority);
1346 }
1347
1348 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
1349 {
1350 MOS_TraceEvent(EVENT_DECODE_DDI_SETGPUPRIORITYVA, EVENT_TYPE_END, NULL, 0, NULL, 0);
1351 }
1352 #endif
1353
1354 return VA_STATUS_SUCCESS;
1355 }
1356
ReleaseBsBuffer(DDI_CODEC_COM_BUFFER_MGR * bufMgr,DDI_MEDIA_BUFFER * buf)1357 bool DdiDecodeFunctions::ReleaseBsBuffer(DDI_CODEC_COM_BUFFER_MGR *bufMgr, DDI_MEDIA_BUFFER *buf)
1358 {
1359 DDI_CODEC_FUNC_ENTER;
1360
1361 if ((nullptr == bufMgr) || (nullptr == buf))
1362 {
1363 return true;
1364 }
1365
1366 if (Media_Format_CPU == buf->format)
1367 {
1368 for (uint32_t i = 0; i < bufMgr->dwNumSliceData; i++)
1369 {
1370 if (bufMgr->pSliceData[i].pBaseAddress == buf->pData)
1371 {
1372 MediaLibvaUtilNext::FreeBuffer(buf);
1373 bufMgr->pSliceData[i].pBaseAddress = nullptr;
1374 if (nullptr != bufMgr->pSliceData[i].pMappedGPUBuffer)
1375 {
1376 MediaLibvaUtilNext::UnlockBuffer(bufMgr->pSliceData[i].pMappedGPUBuffer);
1377 if (false == bufMgr->pSliceData[i].pMappedGPUBuffer->bMapped)
1378 {
1379 MediaLibvaUtilNext::FreeBuffer(bufMgr->pSliceData[i].pMappedGPUBuffer);
1380 MOS_FreeMemory(bufMgr->pSliceData[i].pMappedGPUBuffer);
1381 }
1382 }
1383 MOS_ZeroMemory((void*)(&(bufMgr->pSliceData[i])), sizeof(bufMgr->pSliceData[0]));
1384 bufMgr->dwNumSliceData --;
1385 return true;
1386 }
1387 }
1388 return false;
1389 }
1390 else
1391 {
1392 if (bufMgr->dwNumSliceData)
1393 bufMgr->dwNumSliceData--;
1394 }
1395 return true;
1396 }
1397
ReleaseBpBuffer(DDI_CODEC_COM_BUFFER_MGR * bufMgr,DDI_MEDIA_BUFFER * buf)1398 bool DdiDecodeFunctions::ReleaseBpBuffer(
1399 DDI_CODEC_COM_BUFFER_MGR *bufMgr,
1400 DDI_MEDIA_BUFFER *buf)
1401 {
1402 DDI_CODEC_FUNC_ENTER;
1403
1404 DDI_UNUSED(bufMgr);
1405 DDI_UNUSED(buf);
1406 return true;
1407 }
1408
ReleaseSliceControlBuffer(uint32_t ctxType,void * ctx,DDI_MEDIA_BUFFER * buf)1409 bool DdiDecodeFunctions::ReleaseSliceControlBuffer(uint32_t ctxType, void *ctx, DDI_MEDIA_BUFFER *buf)
1410 {
1411 DDI_CODEC_FUNC_ENTER;
1412
1413 PDDI_DECODE_CONTEXT decCtx = (decltype(decCtx)) GetDecContextFromPVOID(ctx);
1414 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(decCtx->BufMgr);
1415 switch (decCtx->wMode)
1416 {
1417 case CODECHAL_DECODE_MODE_AVCVLD:
1418 if (decCtx->bShortFormatInUse)
1419 {
1420 if (nullptr == bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base)
1421 {
1422 return false;
1423 }
1424 }
1425 else
1426 {
1427 if (nullptr == bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264)
1428 {
1429 return false;
1430 }
1431 }
1432 break;
1433 case CODECHAL_DECODE_MODE_MPEG2VLD:
1434 if (nullptr == bufMgr->Codec_Param.Codec_Param_MPEG2.pVASliceParaBufMPEG2)
1435 {
1436 return false;
1437 }
1438 break;
1439 case CODECHAL_DECODE_MODE_VC1VLD:
1440 if (nullptr == bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1)
1441 {
1442 return false;
1443 }
1444 break;
1445 case CODECHAL_DECODE_MODE_JPEG:
1446 if (nullptr == bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG)
1447 {
1448 return false;
1449 }
1450 break;
1451 case CODECHAL_DECODE_MODE_VP8VLD:
1452 if (nullptr == bufMgr->Codec_Param.Codec_Param_VP8.pVASliceParaBufVP8)
1453 {
1454 return false;
1455 }
1456 break;
1457 case CODECHAL_DECODE_MODE_HEVCVLD:
1458 if (decCtx->bShortFormatInUse)
1459 {
1460 if (nullptr == bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC)
1461 {
1462 return false;
1463 }
1464 }
1465 else
1466 {
1467 if (nullptr == bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC &&
1468 nullptr == bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext)
1469 {
1470 return false;
1471 }
1472 }
1473 break;
1474 case CODECHAL_DECODE_MODE_VP9VLD:
1475 if (nullptr == bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9)
1476 {
1477 return false;
1478 }
1479 break;
1480 default:
1481 return false;
1482 }
1483 return true;
1484 }
1485