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