xref: /aosp_15_r20/external/intel-media-driver/media_driver/linux/common/ddi/media_libva.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2009-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     media_libva.cpp
24 //! \brief    libva(and its extension) interface implementaion.
25 //!
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <fcntl.h>
31 #include <sys/mman.h>
32 #include <sys/ioctl.h>
33 #include <unistd.h>
34 
35 #if !defined(ANDROID) && defined(X11_FOUND)
36 #include <X11/Xutil.h>
37 #endif
38 
39 #include <linux/fb.h>
40 
41 #include "media_libva.h"
42 
43 #include "media_libva_util.h"
44 #include "media_libva_decoder.h"
45 #include "media_libva_encoder.h"
46 #if !defined(ANDROID) && defined(X11_FOUND)
47 #include "media_libva_putsurface_linux.h"
48 #endif
49 #include "media_libva_vp.h"
50 #include "media_ddi_prot.h"
51 
52 #include "mos_os.h"
53 #include "mos_context.h"
54 #include "mos_cmdbufmgr.h"
55 #include "mos_gpucontextmgr.h"
56 
57 #include "hwinfo_linux.h"
58 #include "mediamemdecomp.h"
59 #include "mos_solo_generic.h"
60 #include "media_libva_caps.h"
61 #include "media_interfaces_mmd.h"
62 #include "media_interfaces_mcpy.h"
63 #include "media_user_settings_mgr.h"
64 #include "media_factory.h"
65 #include "mos_interface.h"
66 #include "drm_fourcc.h"
67 #include "media_libva_apo_decision.h"
68 #include "mos_oca_interface_specific.h"
69 
70 #ifdef _MANUAL_SOFTLET_
71 #include "media_libva_interface.h"
72 #include "media_libva_interface_next.h"
73 #include "media_interfaces_hwinfo_device.h"
74 #include "media_libva_caps_next.h"
75 #endif
76 
77 #define BO_BUSY_TIMEOUT_LIMIT 100
78 
79 #ifdef __cplusplus
80 extern "C" {
81 #endif
82 extern VAStatus DdiDestroyContextCM (VADriverContextP   vaDrvCtx, VAContextID         vaCtxID);
83 #ifdef __cplusplus
84 }
85 #endif
86 
87 extern template class MediaFactory<uint32_t, MhwInterfaces>;
88 
89 VAProcFilterType vp_supported_filters[DDI_VP_MAX_NUM_FILTERS] = {
90     VAProcFilterNoiseReduction,
91     VAProcFilterDeinterlacing,
92     VAProcFilterSharpening,
93     VAProcFilterColorBalance,
94     VAProcFilterSkinToneEnhancement,
95     VAProcFilterTotalColorCorrection,
96     VAProcFilterHVSNoiseReduction,
97     VAProcFilterHighDynamicRangeToneMapping
98 #if VA_CHECK_VERSION(1, 12, 0)
99     , VAProcFilter3DLUT
100 #endif
101 };
102 
103 VAProcColorStandardType vp_input_color_std[DDI_VP_NUM_INPUT_COLOR_STD] = {
104     VAProcColorStandardBT601,
105     VAProcColorStandardBT709,
106     VAProcColorStandardSRGB,
107     VAProcColorStandardSTRGB,
108     VAProcColorStandardBT2020,
109     VAProcColorStandardExplicit
110 };
111 
112 VAProcColorStandardType vp_output_color_std[DDI_VP_NUM_OUT_COLOR_STD] = {
113     VAProcColorStandardBT601,
114     VAProcColorStandardBT709,
115     VAProcColorStandardSRGB,
116     VAProcColorStandardSTRGB,
117     VAProcColorStandardBT2020,
118     VAProcColorStandardExplicit
119 };
120 
121 // Making this API public since media_libva_vp.c calls this
122 VAStatus DdiMedia_MapBuffer (
123     VADriverContextP    ctx,
124     VABufferID          buf_id,    /* in */
125     void                **pbuf     /* out */
126 );
127 
128 VAStatus DdiMedia_UnmapBuffer (
129     VADriverContextP    ctx,
130     VABufferID          buf_id    /* in */
131 );
132 
133 VAStatus DdiMedia_DestroyImage (
134     VADriverContextP ctx,
135     VAImageID        image
136 );
137 
DdiMedia_CreateMediaDriverContext()138 static PDDI_MEDIA_CONTEXT DdiMedia_CreateMediaDriverContext()
139 {
140     PDDI_MEDIA_CONTEXT   mediaCtx;
141 
142     mediaCtx = MOS_New(DDI_MEDIA_CONTEXT);
143 
144     return mediaCtx;
145 }
146 
147 // refine this for decoder later
DdiMedia_ReleaseSliceControlBuffer(uint32_t ctxType,void * ctx,DDI_MEDIA_BUFFER * buf)148 static bool DdiMedia_ReleaseSliceControlBuffer(
149     uint32_t          ctxType,
150     void             *ctx,
151     DDI_MEDIA_BUFFER *buf)
152 {
153     DDI_UNUSED(buf);
154 
155     switch (ctxType)
156     {
157         case DDI_MEDIA_CONTEXT_TYPE_DECODER:
158         {
159             PDDI_DECODE_CONTEXT  decCtx;
160 
161             decCtx = DdiDecode_GetDecContextFromPVOID(ctx);
162             DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(decCtx->BufMgr);
163 
164             switch (decCtx->wMode)
165             {
166                 case CODECHAL_DECODE_MODE_AVCVLD:
167                     if(decCtx->bShortFormatInUse)
168                     {
169                         if(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base == nullptr)
170                         {
171                             return false;
172                         }
173                     }
174                     else
175                     {
176                         if(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264 == nullptr)
177                         {
178                             return false;
179                         }
180                     }
181                     break;
182                 case CODECHAL_DECODE_MODE_MPEG2VLD:
183                     if(bufMgr->Codec_Param.Codec_Param_MPEG2.pVASliceParaBufMPEG2 == nullptr)
184                     {
185                         return false;
186                     }
187                     break;
188                 case CODECHAL_DECODE_MODE_VC1VLD:
189                     if(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 == nullptr)
190                     {
191                         return false;
192                     }
193                     break;
194                 case CODECHAL_DECODE_MODE_JPEG:
195                     if(bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG == nullptr)
196                     {
197                         return false;
198                     }
199                     break;
200                 case CODECHAL_DECODE_MODE_VP8VLD:
201                     if(bufMgr->Codec_Param.Codec_Param_VP8.pVASliceParaBufVP8 == nullptr)
202                     {
203                         return false;
204                     }
205                     break;
206                 case CODECHAL_DECODE_MODE_HEVCVLD:
207                     if(decCtx->bShortFormatInUse)
208                     {
209                         if(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC == nullptr)
210                         {
211                             return false;
212                         }
213                     }
214                     else
215                     {
216                         if(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC == nullptr &&
217                             bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext == nullptr)
218                         {
219                             return false;
220                         }
221                     }
222                     break;
223                 case CODECHAL_DECODE_MODE_VP9VLD:
224                     if(bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9 == nullptr)
225                     {
226                         return false;
227                     }
228                     break;
229                 default:
230                     return false;
231             }
232             break;
233         }
234         case DDI_MEDIA_CONTEXT_TYPE_ENCODER:
235             break;
236         default:
237             break;
238     }
239 
240     return true;
241 }
242 
DdiMedia_ReleaseBpBuffer(DDI_CODEC_COM_BUFFER_MGR * bufMgr,DDI_MEDIA_BUFFER * buf)243 static bool DdiMedia_ReleaseBpBuffer(
244     DDI_CODEC_COM_BUFFER_MGR   *bufMgr,
245     DDI_MEDIA_BUFFER           *buf)
246 {
247     DDI_UNUSED(bufMgr);
248     DDI_UNUSED(buf);
249     return true;
250 }
251 
DdiMedia_ReleaseBsBuffer(DDI_CODEC_COM_BUFFER_MGR * bufMgr,DDI_MEDIA_BUFFER * buf)252 static bool DdiMedia_ReleaseBsBuffer(
253     DDI_CODEC_COM_BUFFER_MGR   *bufMgr,
254     DDI_MEDIA_BUFFER           *buf)
255 {
256     if ((bufMgr == nullptr) || (buf == nullptr))
257     {
258         return true;
259     }
260 
261     if (buf->format == Media_Format_CPU)
262     {
263         for(uint32_t i = 0; i < bufMgr->dwNumSliceData; i++)
264         {
265             if(bufMgr->pSliceData[i].pBaseAddress == buf->pData)
266             {
267                 DdiMediaUtil_FreeBuffer(buf);
268                 bufMgr->pSliceData[i].pBaseAddress = nullptr;
269                 if (bufMgr->pSliceData[i].pMappedGPUBuffer != nullptr)
270                 {
271                     DdiMediaUtil_UnlockBuffer(bufMgr->pSliceData[i].pMappedGPUBuffer);
272                     if (bufMgr->pSliceData[i].pMappedGPUBuffer->bMapped == false)
273                     {
274                         DdiMediaUtil_FreeBuffer(bufMgr->pSliceData[i].pMappedGPUBuffer);
275                         MOS_FreeMemory(bufMgr->pSliceData[i].pMappedGPUBuffer);
276                     }
277                 }
278                 MOS_ZeroMemory((void*)(&(bufMgr->pSliceData[i])), sizeof(bufMgr->pSliceData[0]));
279                 bufMgr->dwNumSliceData --;
280                 return true;
281             }
282         }
283         return false;
284     }
285     else
286     {
287         if (bufMgr->dwNumSliceData)
288             bufMgr->dwNumSliceData--;
289     }
290     return true;
291 }
292 
DdiMedia_CreateRenderTarget(PDDI_MEDIA_CONTEXT mediaDrvCtx,DDI_MEDIA_FORMAT mediaFormat,uint32_t width,uint32_t height,DDI_MEDIA_SURFACE_DESCRIPTOR * surfDesc,uint32_t surfaceUsageHint,int memType)293 static uint32_t DdiMedia_CreateRenderTarget(
294     PDDI_MEDIA_CONTEXT            mediaDrvCtx,
295     DDI_MEDIA_FORMAT              mediaFormat,
296     uint32_t                      width,
297     uint32_t                      height,
298     DDI_MEDIA_SURFACE_DESCRIPTOR *surfDesc,
299     uint32_t                      surfaceUsageHint,
300     int                           memType
301 )
302 {
303     DdiMediaUtil_LockMutex(&mediaDrvCtx->SurfaceMutex);
304 
305     PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = DdiMediaUtil_AllocPMediaSurfaceFromHeap(mediaDrvCtx->pSurfaceHeap);
306     if (nullptr == surfaceElement)
307     {
308         DdiMediaUtil_UnLockMutex(&mediaDrvCtx->SurfaceMutex);
309         return VA_INVALID_ID;
310     }
311 
312     surfaceElement->pSurface = (DDI_MEDIA_SURFACE *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_SURFACE));
313     if (nullptr == surfaceElement->pSurface)
314     {
315         DdiMediaUtil_ReleasePMediaSurfaceFromHeap(mediaDrvCtx->pSurfaceHeap, surfaceElement->uiVaSurfaceID);
316         DdiMediaUtil_UnLockMutex(&mediaDrvCtx->SurfaceMutex);
317         return VA_INVALID_ID;
318     }
319 
320     surfaceElement->pSurface->pMediaCtx       = mediaDrvCtx;
321     surfaceElement->pSurface->iWidth          = width;
322     surfaceElement->pSurface->iHeight         = height;
323     surfaceElement->pSurface->pSurfDesc       = surfDesc;
324     surfaceElement->pSurface->format          = mediaFormat;
325     surfaceElement->pSurface->uiLockedBufID   = VA_INVALID_ID;
326     surfaceElement->pSurface->uiLockedImageID = VA_INVALID_ID;
327     surfaceElement->pSurface->surfaceUsageHint= surfaceUsageHint;
328     surfaceElement->pSurface->memType         = memType;
329 
330     if(DdiMediaUtil_CreateSurface(surfaceElement->pSurface, mediaDrvCtx)!= VA_STATUS_SUCCESS)
331     {
332         MOS_FreeMemory(surfaceElement->pSurface);
333         DdiMediaUtil_ReleasePMediaSurfaceFromHeap(mediaDrvCtx->pSurfaceHeap, surfaceElement->uiVaSurfaceID);
334         DdiMediaUtil_UnLockMutex(&mediaDrvCtx->SurfaceMutex);
335         return VA_INVALID_ID;
336     }
337 
338     mediaDrvCtx->uiNumSurfaces++;
339     uint32_t surfaceID = surfaceElement->uiVaSurfaceID;
340     DdiMediaUtil_UnLockMutex(&mediaDrvCtx->SurfaceMutex);
341     return surfaceID;
342 }
343 
344 VAStatus
DdiMedia_HybridQueryBufferAttributes(VADisplay dpy,VAContextID context,VABufferType bufferType,void * outputData,uint32_t * outputDataLen)345 DdiMedia_HybridQueryBufferAttributes (
346     VADisplay    dpy,
347     VAContextID  context,
348     VABufferType bufferType,
349     void        *outputData,
350     uint32_t    *outputDataLen
351 )
352 {
353     return VA_STATUS_ERROR_UNIMPLEMENTED;
354 }
355 
356 //!
357 //! \brief  Set Frame ID
358 //!
359 //! \param  [in] dpy
360 //!         VA display
361 //! \param  [in] surface
362 //!         VA surface ID
363 //! \param  [in] frame_id
364 //!         Frame ID
365 //!
366 //! \return VAStatus
367 //!     VA_STATUS_SUCCESS if success, else fail reason
368 //!
DdiMedia_SetFrameID(VADisplay dpy,VASurfaceID surface,uint32_t frame_id)369 VAStatus DdiMedia_SetFrameID(
370     VADisplay    dpy,
371     VASurfaceID  surface,
372     uint32_t     frame_id
373 )
374 {
375     VADriverContextP ctx            = (((VADisplayContextP)dpy)->pDriverContext);
376     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
377 
378     PDDI_MEDIA_CONTEXT mediaCtx     = DdiMedia_GetMediaContext(ctx);
379     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
380 
381     DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface);
382     DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface.", VA_STATUS_ERROR_INVALID_PARAMETER);
383 
384     mediaSurface->frame_idx = frame_id;
385 
386     return VA_STATUS_SUCCESS;
387 }
388 
389 //!
390 //! \brief  Convert media format to OS format
391 //!
392 //! \param  [in] format
393 //!         Ddi media format
394 //!
395 //! \return Os format if call sucesss,else
396 //!     VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT if fail
397 //!
DdiMedia_MediaFormatToOsFormat(DDI_MEDIA_FORMAT format)398 int32_t DdiMedia_MediaFormatToOsFormat(DDI_MEDIA_FORMAT format)
399 {
400     switch (format)
401     {
402         case Media_Format_X8R8G8B8:
403             return VA_FOURCC_XRGB;
404         case Media_Format_X8B8G8R8:
405             return VA_FOURCC_XBGR;
406         case Media_Format_A8B8G8R8:
407             return VA_FOURCC_ABGR;
408         case Media_Format_R10G10B10A2:
409             return VA_FOURCC_A2B10G10R10;
410         case Media_Format_R8G8B8A8:
411             return VA_FOURCC_RGBA;
412         case Media_Format_A8R8G8B8:
413             return VA_FOURCC_ARGB;
414         case Media_Format_B10G10R10A2:
415             return VA_FOURCC_A2R10G10B10;
416         case Media_Format_R10G10B10X2:
417             return VA_FOURCC_X2B10G10R10;
418         case Media_Format_B10G10R10X2:
419             return VA_FOURCC_X2R10G10B10;
420         case Media_Format_R5G6B5:
421             return VA_FOURCC_R5G6B5;
422         case Media_Format_R8G8B8:
423             return VA_FOURCC_R8G8B8;
424         case Media_Format_NV12:
425             return VA_FOURCC_NV12;
426         case Media_Format_NV21:
427             return VA_FOURCC_NV21;
428         case  Media_Format_YUY2:
429             return VA_FOURCC_YUY2;
430         case  Media_Format_UYVY:
431             return VA_FOURCC_UYVY;
432         case Media_Format_YV12:
433             return VA_FOURCC_YV12;
434         case Media_Format_IYUV:
435             return VA_FOURCC_IYUV;
436         case Media_Format_I420:
437             return VA_FOURCC_I420;
438         case Media_Format_400P:
439             return VA_FOURCC('4','0','0','P');
440         case Media_Format_IMC3:
441             return VA_FOURCC_IMC3;
442         case Media_Format_422H:
443             return VA_FOURCC_422H;
444         case Media_Format_422V:
445             return VA_FOURCC_422V;
446         case Media_Format_411P:
447             return VA_FOURCC_411P;
448         case Media_Format_444P:
449             return VA_FOURCC_444P;
450         case Media_Format_RGBP:
451             return VA_FOURCC_RGBP;
452         case Media_Format_BGRP:
453             return VA_FOURCC_BGRP;
454         case Media_Format_Buffer:
455             return VA_FOURCC_P208;
456         case Media_Format_P010:
457             return VA_FOURCC_P010;
458         case Media_Format_P012:
459             return VA_FOURCC_P012;
460         case Media_Format_P016:
461             return VA_FOURCC_P016;
462         case Media_Format_Y210:
463             return VA_FOURCC_Y210;
464 #if VA_CHECK_VERSION(1, 9, 0)
465         case Media_Format_Y212:
466             return VA_FOURCC_Y212;
467 #endif
468         case Media_Format_Y216:
469             return VA_FOURCC_Y216;
470         case Media_Format_AYUV:
471             return VA_FOURCC_AYUV;
472 #if VA_CHECK_VERSION(1, 13, 0)
473         case Media_Format_XYUV:
474             return VA_FOURCC_XYUV;
475 #endif
476         case Media_Format_Y410:
477             return VA_FOURCC_Y410;
478 #if VA_CHECK_VERSION(1, 9, 0)
479         case Media_Format_Y412:
480             return VA_FOURCC_Y412;
481 #endif
482         case Media_Format_Y416:
483             return VA_FOURCC_Y416;
484         case Media_Format_Y8:
485             return VA_FOURCC_Y8;
486         case Media_Format_Y16S:
487             return VA_FOURCC_Y16;
488         case Media_Format_Y16U:
489             return VA_FOURCC_Y16;
490         case Media_Format_VYUY:
491             return VA_FOURCC_VYUY;
492         case Media_Format_YVYU:
493             return VA_FOURCC_YVYU;
494         case Media_Format_A16R16G16B16:
495             return VA_FOURCC_ARGB64;
496         case Media_Format_A16B16G16R16:
497             return VA_FOURCC_ABGR64;
498 
499         default:
500             return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
501     }
502 }
503 
504 //!
505 //! \brief  Convert Os format to media format
506 //!
507 //! \param  [in] fourcc
508 //!         FourCC
509 //! \param  [in] rtformatType
510 //!         Rt format type
511 //!
512 //! \return DDI_MEDIA_FORMAT
513 //!     Ddi media format
514 //!
DdiMedia_OsFormatToMediaFormat(int32_t fourcc,int32_t rtformatType)515 DDI_MEDIA_FORMAT DdiMedia_OsFormatToMediaFormat(int32_t fourcc, int32_t rtformatType)
516 {
517     switch (fourcc)
518     {
519         case VA_FOURCC_A2R10G10B10:
520             return Media_Format_B10G10R10A2;
521         case VA_FOURCC_A2B10G10R10:
522             return Media_Format_R10G10B10A2;
523         case VA_FOURCC_X2R10G10B10:
524             return Media_Format_B10G10R10X2;
525         case VA_FOURCC_X2B10G10R10:
526             return Media_Format_R10G10B10X2;
527         case VA_FOURCC_BGRA:
528         case VA_FOURCC_ARGB:
529 #ifdef VA_RT_FORMAT_RGB32_10BPP
530             if(VA_RT_FORMAT_RGB32_10BPP == rtformatType)
531             {
532                 return Media_Format_B10G10R10A2;
533             }
534 #endif
535             return Media_Format_A8R8G8B8;
536         case VA_FOURCC_RGBA:
537 #ifdef VA_RT_FORMAT_RGB32_10BPP
538             if(VA_RT_FORMAT_RGB32_10BPP == rtformatType)
539             {
540                 return Media_Format_R10G10B10A2;
541             }
542 #endif
543             return Media_Format_R8G8B8A8;
544         case VA_FOURCC_ABGR:
545 #ifdef VA_RT_FORMAT_RGB32_10BPP
546             if(VA_RT_FORMAT_RGB32_10BPP == rtformatType)
547             {
548                 return Media_Format_R10G10B10A2;
549             }
550 #endif
551             return Media_Format_A8B8G8R8;
552         case VA_FOURCC_BGRX:
553         case VA_FOURCC_XRGB:
554             return Media_Format_X8R8G8B8;
555         case VA_FOURCC_XBGR:
556         case VA_FOURCC_RGBX:
557             return Media_Format_X8B8G8R8;
558         case VA_FOURCC_R5G6B5:
559             return Media_Format_R5G6B5;
560         case VA_FOURCC_R8G8B8:
561             return Media_Format_R8G8B8;
562         case VA_FOURCC_NV12:
563             return Media_Format_NV12;
564         case VA_FOURCC_NV21:
565             return Media_Format_NV21;
566         case VA_FOURCC_YUY2:
567             return Media_Format_YUY2;
568         case VA_FOURCC_UYVY:
569             return Media_Format_UYVY;
570         case VA_FOURCC_YV12:
571             return Media_Format_YV12;
572         case VA_FOURCC_IYUV:
573             return Media_Format_IYUV;
574         case VA_FOURCC_I420:
575             return Media_Format_I420;
576         case VA_FOURCC_422H:
577             return Media_Format_422H;
578         case VA_FOURCC_422V:
579             return Media_Format_422V;
580         case VA_FOURCC('4','0','0','P'):
581         case VA_FOURCC_Y800:
582             return Media_Format_400P;
583         case VA_FOURCC_411P:
584             return Media_Format_411P;
585         case VA_FOURCC_IMC3:
586             return Media_Format_IMC3;
587         case VA_FOURCC_444P:
588             return Media_Format_444P;
589         case VA_FOURCC_BGRP:
590             return Media_Format_BGRP;
591         case VA_FOURCC_RGBP:
592             return Media_Format_RGBP;
593         case VA_FOURCC_P208:
594             return Media_Format_Buffer;
595         case VA_FOURCC_P010:
596             return Media_Format_P010;
597         case VA_FOURCC_P012:
598             return Media_Format_P012;
599         case VA_FOURCC_P016:
600             return Media_Format_P016;
601         case VA_FOURCC_Y210:
602             return Media_Format_Y210;
603 #if VA_CHECK_VERSION(1, 9, 0)
604         case VA_FOURCC_Y212:
605             return Media_Format_Y212;
606 #endif
607         case VA_FOURCC_Y216:
608             return Media_Format_Y216;
609         case VA_FOURCC_AYUV:
610             return Media_Format_AYUV;
611 #if VA_CHECK_VERSION(1, 13, 0)
612         case VA_FOURCC_XYUV:
613             return Media_Format_XYUV;
614 #endif
615         case VA_FOURCC_Y410:
616             return Media_Format_Y410;
617 #if VA_CHECK_VERSION(1, 9, 0)
618         case VA_FOURCC_Y412:
619             return Media_Format_Y412;
620 #endif
621         case VA_FOURCC_Y416:
622             return Media_Format_Y416;
623         case VA_FOURCC_Y8:
624             return Media_Format_Y8;
625         case VA_FOURCC_Y16:
626             return Media_Format_Y16S;
627         case VA_FOURCC_VYUY:
628             return Media_Format_VYUY;
629         case VA_FOURCC_YVYU:
630             return Media_Format_YVYU;
631         case VA_FOURCC_ARGB64:
632             return Media_Format_A16R16G16B16;
633         case VA_FOURCC_ABGR64:
634             return Media_Format_A16B16G16R16;
635 
636         default:
637             return Media_Format_Count;
638     }
639 }
640 
DdiMedia_GetChromaPitchHeight(uint32_t fourcc,uint32_t pitch,uint32_t height,uint32_t * chromaPitch,uint32_t * chromaHeight)641 static VAStatus DdiMedia_GetChromaPitchHeight(
642     uint32_t fourcc,
643     uint32_t pitch,
644     uint32_t height,
645     uint32_t *chromaPitch,
646     uint32_t *chromaHeight)
647 {
648     DDI_CHK_NULL(chromaPitch, "nullptr chromaPitch", VA_STATUS_ERROR_INVALID_PARAMETER);
649     DDI_CHK_NULL(chromaHeight, "nullptr chromaHeight", VA_STATUS_ERROR_INVALID_PARAMETER);
650 
651     switch(fourcc)
652     {
653         case VA_FOURCC_NV12:
654         case VA_FOURCC_P010:
655         case VA_FOURCC_P012:
656         case VA_FOURCC_P016:
657             *chromaHeight = MOS_ALIGN_CEIL(height, 2) / 2;
658             *chromaPitch = pitch;
659             break;
660         case VA_FOURCC_I420:
661         case VA_FOURCC_YV12:
662             *chromaHeight = MOS_ALIGN_CEIL(height, 2) / 2;
663             *chromaPitch = MOS_ALIGN_CEIL(pitch, 2) / 2;
664             break;
665         case VA_FOURCC_411P:
666         case VA_FOURCC_422H:
667         case VA_FOURCC_444P:
668         case VA_FOURCC_RGBP:
669             *chromaHeight = height;
670             *chromaPitch = pitch;
671             break;
672         case VA_FOURCC_422V:
673         case VA_FOURCC_IMC3:
674             *chromaHeight = MOS_ALIGN_CEIL(height, 2) / 2;
675             *chromaPitch = pitch;
676             break;
677         default:
678             *chromaPitch = 0;
679             *chromaHeight = 0;
680     }
681 
682     return VA_STATUS_SUCCESS;
683 }
684 
685 
686 #if !defined(ANDROID) && defined(X11_FOUND)
687 
688 #define X11_LIB_NAME "libX11.so.6"
689 
690 /*
691  * Close opened libX11.so lib, free related function table.
692  */
DdiMedia_DestroyX11Connection(PDDI_MEDIA_CONTEXT mediaCtx)693 static void DdiMedia_DestroyX11Connection(
694     PDDI_MEDIA_CONTEXT mediaCtx
695 )
696 {
697     if (nullptr == mediaCtx || nullptr == mediaCtx->X11FuncTable)
698     {
699         return;
700     }
701 
702     MosUtilities::MosFreeLibrary(mediaCtx->X11FuncTable->pX11LibHandle);
703     MOS_FreeMemory(mediaCtx->X11FuncTable);
704     mediaCtx->X11FuncTable = nullptr;
705 
706     return;
707 }
708 
709 /*
710  * dlopen libX11.so, setup the function table, which is used by
711  * DdiCodec_PutSurface (Linux) so far.
712  */
DdiMedia_ConnectX11(PDDI_MEDIA_CONTEXT mediaCtx)713 static VAStatus DdiMedia_ConnectX11(
714     PDDI_MEDIA_CONTEXT mediaCtx
715 )
716 {
717     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
718 
719     mediaCtx->X11FuncTable = (PDDI_X11_FUNC_TABLE)MOS_AllocAndZeroMemory(sizeof(DDI_X11_FUNC_TABLE));
720     DDI_CHK_NULL(mediaCtx->X11FuncTable, "Allocation Failed for X11FuncTable", VA_STATUS_ERROR_ALLOCATION_FAILED);
721 
722     HMODULE    h_module   = nullptr;
723     MOS_STATUS mos_status = MosUtilities::MosLoadLibrary(X11_LIB_NAME, &h_module);
724     if (MOS_STATUS_SUCCESS != mos_status || nullptr == h_module)
725     {
726         DdiMedia_DestroyX11Connection(mediaCtx);
727         return VA_STATUS_ERROR_OPERATION_FAILED;
728     }
729 
730     mediaCtx->X11FuncTable->pX11LibHandle = h_module;
731 
732     mediaCtx->X11FuncTable->pfnXCreateGC =
733         MosUtilities::MosGetProcAddress(h_module, "XCreateGC");
734     mediaCtx->X11FuncTable->pfnXFreeGC =
735         MosUtilities::MosGetProcAddress(h_module, "XFreeGC");
736     mediaCtx->X11FuncTable->pfnXCreateImage =
737         MosUtilities::MosGetProcAddress(h_module, "XCreateImage");
738     mediaCtx->X11FuncTable->pfnXDestroyImage =
739         MosUtilities::MosGetProcAddress(h_module, "XDestroyImage");
740     mediaCtx->X11FuncTable->pfnXPutImage =
741         MosUtilities::MosGetProcAddress(h_module, "XPutImage");
742 
743     if (nullptr == mediaCtx->X11FuncTable->pfnXCreateGC     ||
744         nullptr == mediaCtx->X11FuncTable->pfnXFreeGC       ||
745         nullptr == mediaCtx->X11FuncTable->pfnXCreateImage  ||
746         nullptr == mediaCtx->X11FuncTable->pfnXDestroyImage ||
747         nullptr == mediaCtx->X11FuncTable->pfnXPutImage)
748     {
749         DdiMedia_DestroyX11Connection(mediaCtx);
750         return VA_STATUS_ERROR_OPERATION_FAILED;
751     }
752 
753     return VA_STATUS_SUCCESS;
754 }
755 #endif
756 
757 /////////////////////////////////////////////////////////////////////////////
758 //! \Free allocated surfaceheap elements
759 //! \params
760 //! [in] PDDI_MEDIA_CONTEXT
761 //! [out] none
762 //! \returns
763 /////////////////////////////////////////////////////////////////////////////
DdiMedia_FreeSurfaceHeapElements(PDDI_MEDIA_CONTEXT mediaCtx)764 static void DdiMedia_FreeSurfaceHeapElements(PDDI_MEDIA_CONTEXT mediaCtx)
765 {
766     if (nullptr == mediaCtx)
767         return;
768     PDDI_MEDIA_HEAP surfaceHeap = mediaCtx->pSurfaceHeap;
769 
770     if (nullptr == surfaceHeap)
771         return;
772 
773     PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapBase = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surfaceHeap->pHeapBase;
774     if (nullptr == mediaSurfaceHeapBase)
775         return;
776 
777     int32_t surfaceNums = mediaCtx->uiNumSurfaces;
778     for (int32_t elementId = 0; surfaceNums > 0 && elementId < surfaceHeap->uiAllocatedHeapElements; elementId++)
779     {
780         PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapElmt = &mediaSurfaceHeapBase[elementId];
781         if (nullptr == mediaSurfaceHeapElmt->pSurface)
782             continue;
783 
784         DdiMediaUtil_FreeSurface(mediaSurfaceHeapElmt->pSurface);
785         MOS_FreeMemory(mediaSurfaceHeapElmt->pSurface);
786         DdiMediaUtil_ReleasePMediaSurfaceFromHeap(surfaceHeap,mediaSurfaceHeapElmt->uiVaSurfaceID);
787         surfaceNums--;
788         mediaCtx->uiNumSurfaces--;
789     }
790 }
791 
792 /////////////////////////////////////////////////////////////////////////////
793 //! \Free allocated bufferheap elements
794 //! \params
795 //! [in] VADriverContextP
796 //! [out] none
797 //! \returns
798 /////////////////////////////////////////////////////////////////////////////
DdiMedia_FreeBufferHeapElements(VADriverContextP ctx)799 static void DdiMedia_FreeBufferHeapElements(VADriverContextP    ctx)
800 {
801     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
802     if (nullptr == mediaCtx)
803         return;
804 
805     PDDI_MEDIA_HEAP  bufferHeap = mediaCtx->pBufferHeap;
806     if (nullptr == bufferHeap)
807         return;
808 
809     PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapBase = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pHeapBase;
810     if (nullptr == mediaBufferHeapBase)
811         return;
812 
813     int32_t bufNums = mediaCtx->uiNumBufs;
814     for (int32_t elementId = 0; bufNums > 0 && elementId < bufferHeap->uiAllocatedHeapElements; ++elementId)
815     {
816         PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapElmt = &mediaBufferHeapBase[elementId];
817         if (nullptr == mediaBufferHeapElmt->pBuffer)
818             continue;
819         //Note: uiNumBufs will recount in DdiMedia_DestroyBuffer
820         DdiMedia_DestroyBuffer(ctx,mediaBufferHeapElmt->uiVaBufferID);
821         //Ensure the non-empty buffer to be destroyed.
822         bufNums--;
823     }
824 }
825 
826 /////////////////////////////////////////////////////////////////////////////
827 //! \Free allocated Imageheap elements
828 //! \params
829 //! [in] VADriverContextP
830 //! [out] none
831 //! \returns
832 /////////////////////////////////////////////////////////////////////////////
DdiMedia_FreeImageHeapElements(VADriverContextP ctx)833 static void DdiMedia_FreeImageHeapElements(VADriverContextP    ctx)
834 {
835     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
836     if (nullptr == mediaCtx)
837         return;
838 
839     PDDI_MEDIA_HEAP imageHeap = mediaCtx->pImageHeap;
840     if (nullptr == imageHeap)
841         return;
842 
843     PDDI_MEDIA_IMAGE_HEAP_ELEMENT mediaImageHeapBase = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)imageHeap->pHeapBase;
844     if (nullptr == mediaImageHeapBase)
845         return;
846 
847     int32_t imageNums = mediaCtx->uiNumImages;
848     for (int32_t elementId = 0; imageNums > 0 && elementId < imageHeap->uiAllocatedHeapElements; ++elementId)
849     {
850         PDDI_MEDIA_IMAGE_HEAP_ELEMENT mediaImageHeapElmt = &mediaImageHeapBase[elementId];
851         if (nullptr == mediaImageHeapElmt->pImage)
852             continue;
853         //Note: uiNumImages will recount in DdiMedia_DestroyImage
854         DdiMedia_DestroyImage(ctx,mediaImageHeapElmt->uiVaImageID);
855         imageNums--;
856     }
857 }
858 
859 /////////////////////////////////////////////////////////////////////////////
860 //! \Execute free allocated bufferheap elements for FreeContextHeapElements function
861 //! \params
862 //! [in] VADriverContextP
863 //! [in] PDDI_MEDIA_HEAP
864 //! [out] none
865 //! \returns
866 /////////////////////////////////////////////////////////////////////////////
DdiMedia_FreeContextHeap(VADriverContextP ctx,PDDI_MEDIA_HEAP contextHeap,int32_t vaContextOffset,int32_t ctxNums)867 static void DdiMedia_FreeContextHeap(VADriverContextP ctx, PDDI_MEDIA_HEAP contextHeap,int32_t vaContextOffset, int32_t ctxNums)
868 {
869     PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT mediaContextHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)contextHeap->pHeapBase;
870     if (nullptr == mediaContextHeapBase)
871         return;
872 
873     for (int32_t elementId = 0; ctxNums > 0 && elementId < contextHeap->uiAllocatedHeapElements; ++elementId)
874     {
875         PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT mediaContextHeapElmt = &mediaContextHeapBase[elementId];
876         if (nullptr == mediaContextHeapElmt->pVaContext)
877             continue;
878         VAContextID vaCtxID = (VAContextID)(mediaContextHeapElmt->uiVaContextID + vaContextOffset);
879         DdiMedia_DestroyContext(ctx,vaCtxID);
880         ctxNums--;
881     }
882 
883 }
884 
885 /////////////////////////////////////////////////////////////////////////////
886 //! \Free allocated contextheap elements
887 //! \params
888 //! [in] VADriverContextP
889 //! [out] none
890 //! \returns
891 /////////////////////////////////////////////////////////////////////////////
DdiMedia_FreeContextHeapElements(VADriverContextP ctx)892 static void DdiMedia_FreeContextHeapElements(VADriverContextP    ctx)
893 {
894     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
895     if (nullptr == mediaCtx)
896         return;
897 
898     //Free EncoderContext
899     PDDI_MEDIA_HEAP encoderContextHeap = mediaCtx->pEncoderCtxHeap;
900     int32_t encCtxNums        = mediaCtx->uiNumEncoders;
901     if (nullptr != encoderContextHeap)
902         DdiMedia_FreeContextHeap(ctx,encoderContextHeap,DDI_MEDIA_VACONTEXTID_OFFSET_ENCODER,encCtxNums);
903 
904     //Free DecoderContext
905     PDDI_MEDIA_HEAP decoderContextHeap = mediaCtx->pDecoderCtxHeap;
906     int32_t decCtxNums        = mediaCtx->uiNumDecoders;
907     if (nullptr != decoderContextHeap)
908         DdiMedia_FreeContextHeap(ctx,decoderContextHeap,DDI_MEDIA_VACONTEXTID_OFFSET_DECODER,decCtxNums);
909 
910     //Free VpContext
911     PDDI_MEDIA_HEAP vpContextHeap      = mediaCtx->pVpCtxHeap;
912     int32_t vpctxNums         = mediaCtx->uiNumVPs;
913     if (nullptr != vpContextHeap)
914         DdiMedia_FreeContextHeap(ctx,vpContextHeap,DDI_MEDIA_VACONTEXTID_OFFSET_VP,vpctxNums);
915 
916     //Free ProtContext
917     PDDI_MEDIA_HEAP protContextHeap      = mediaCtx->pProtCtxHeap;
918     int32_t protCtxNums         = mediaCtx->uiNumProts;
919     if (nullptr != protContextHeap)
920         DdiMedia_FreeProtectedSessionHeap(ctx,protContextHeap,DDI_MEDIA_VACONTEXTID_OFFSET_PROT,protCtxNums);
921 
922     //Free MfeContext
923     PDDI_MEDIA_HEAP mfeContextHeap     = mediaCtx->pMfeCtxHeap;
924     int32_t mfeCtxNums        = mediaCtx->uiNumMfes;
925     if (nullptr != mfeContextHeap)
926         DdiMedia_FreeContextHeap(ctx, mfeContextHeap, DDI_MEDIA_VACONTEXTID_OFFSET_MFE, mfeCtxNums);
927 
928     // Free media memory decompression data structure
929     if (!mediaCtx->m_apoMosEnabled && mediaCtx->pMediaMemDecompState)
930     {
931         MediaMemDecompBaseState *mediaMemCompState =
932             static_cast<MediaMemDecompBaseState*>(mediaCtx->pMediaMemDecompState);
933         MOS_Delete(mediaMemCompState);
934     }
935     mediaCtx->pMediaMemDecompState = nullptr;
936 }
937 
938 /////////////////////////////////////////////////////////////////////////////
939 //! \Free allocated ContextCM elements
940 //! \params
941 //! [in] VADriverContextP
942 //! [out] none
943 //! \returns
944 /////////////////////////////////////////////////////////////////////////////
DdiMedia_FreeContextCMElements(VADriverContextP ctx)945 static void DdiMedia_FreeContextCMElements(VADriverContextP ctx)
946 {
947     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
948     if (nullptr == mediaCtx)
949         return;
950 
951     int32_t cmnums = mediaCtx->uiNumCMs;
952     for (int32_t elementId = 0; elementId < cmnums; elementId++)
953     {
954         VAContextID vaCtxID = elementId + DDI_MEDIA_VACONTEXTID_OFFSET_CM;
955         DdiDestroyContextCM(ctx,vaCtxID);
956     }
957 }
958 
959 //!
960 //! \brief  Get VA image from VA image ID
961 //!
962 //! \param  [in] mediaCtx
963 //!         Pointer to ddi media context
964 //! \param  [in] imageID
965 //!         VA image ID
966 //!
967 //! \return VAImage*
968 //!     Pointer to VAImage
969 //!
DdiMedia_GetVAImageFromVAImageID(PDDI_MEDIA_CONTEXT mediaCtx,VAImageID imageID)970 VAImage* DdiMedia_GetVAImageFromVAImageID (PDDI_MEDIA_CONTEXT mediaCtx, VAImageID imageID)
971 {
972     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", nullptr);
973 
974     uint32_t i       = (uint32_t)imageID;
975     DDI_CHK_LESS(i, mediaCtx->pImageHeap->uiAllocatedHeapElements, "invalid image id", nullptr);
976     DdiMediaUtil_LockMutex(&mediaCtx->ImageMutex);
977     PDDI_MEDIA_IMAGE_HEAP_ELEMENT imageElement = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)mediaCtx->pImageHeap->pHeapBase;
978     imageElement    += i;
979     VAImage *vaImage = imageElement->pImage;
980     DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex);
981 
982     return vaImage;
983 }
984 
985 //!
986 //! \brief  Get ctx from VA buffer ID
987 //!
988 //! \param  [in] mediaCtx
989 //!         pddi media context
990 //! \param  [in] bufferID
991 //!         VA Buffer ID
992 //!
993 //! \return void*
994 //!     Pointer to buffer heap element context
995 //!
DdiMedia_GetCtxFromVABufferID(PDDI_MEDIA_CONTEXT mediaCtx,VABufferID bufferID)996 void* DdiMedia_GetCtxFromVABufferID (PDDI_MEDIA_CONTEXT mediaCtx, VABufferID bufferID)
997 {
998     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", nullptr);
999 
1000     uint32_t i      = (uint32_t)bufferID;
1001     DDI_CHK_LESS(i, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "invalid buffer id", nullptr);
1002     DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
1003     PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufHeapElement  = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)mediaCtx->pBufferHeap->pHeapBase;
1004     bufHeapElement += i;
1005     void *temp      = bufHeapElement->pCtx;
1006     DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
1007 
1008     return temp;
1009 }
1010 
1011 //!
1012 //! \brief  Get ctx type from VA buffer ID
1013 //!
1014 //! \param  [in] mediaCtx
1015 //!         Pointer to ddi media context
1016 //! \param  [in] bufferID
1017 //!         VA buffer ID
1018 //!
1019 //! \return uint32_t
1020 //1     Context type
1021 //!
DdiMedia_GetCtxTypeFromVABufferID(PDDI_MEDIA_CONTEXT mediaCtx,VABufferID bufferID)1022 uint32_t DdiMedia_GetCtxTypeFromVABufferID (PDDI_MEDIA_CONTEXT mediaCtx, VABufferID bufferID)
1023 {
1024     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", DDI_MEDIA_CONTEXT_TYPE_NONE);
1025 
1026     uint32_t i       = (uint32_t)bufferID;
1027     DDI_CHK_LESS(i, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "invalid buffer id", DDI_MEDIA_CONTEXT_TYPE_NONE);
1028     DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
1029     PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufHeapElement  = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)mediaCtx->pBufferHeap->pHeapBase;
1030     bufHeapElement  += i;
1031     uint32_t ctxType = bufHeapElement->uiCtxType;
1032     DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
1033 
1034     return ctxType;
1035 
1036 }
1037 
1038 //!
1039 //! \brief  Destroy image from VA image ID
1040 //!
1041 //! \param  [in] mediaCtx
1042 //!         Pointer to ddi media context
1043 //! \param  [in] imageID
1044 //!     VA image ID
1045 //!
1046 //! \return bool
1047 //!     True if destroy image from VA image ID, else fail
1048 //!
DdiMedia_DestroyImageFromVAImageID(PDDI_MEDIA_CONTEXT mediaCtx,VAImageID imageID)1049 bool DdiMedia_DestroyImageFromVAImageID (PDDI_MEDIA_CONTEXT mediaCtx, VAImageID imageID)
1050 {
1051     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", false);
1052 
1053     DdiMediaUtil_LockMutex(&mediaCtx->ImageMutex);
1054     DdiMediaUtil_ReleasePVAImageFromHeap(mediaCtx->pImageHeap, (uint32_t)imageID);
1055     mediaCtx->uiNumImages--;
1056     DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex);
1057     return true;
1058 }
1059 #ifdef _MMC_SUPPORTED
1060 //!
1061 //! \brief  Decompress internal media memory
1062 //!
1063 //! \param  [in] mosCtx
1064 //!         Pointer to mos context
1065 //! \param  [in] osResource
1066 //!         Pointer mos resource
1067 //!
DdiMedia_MediaMemoryDecompressInternal(PMOS_CONTEXT mosCtx,PMOS_RESOURCE osResource)1068 void DdiMedia_MediaMemoryDecompressInternal(PMOS_CONTEXT mosCtx, PMOS_RESOURCE osResource)
1069 {
1070     DDI_CHK_NULL(mosCtx, "nullptr mosCtx",);
1071     DDI_CHK_NULL(osResource, "nullptr osResource",);
1072     DDI_ASSERT(osResource);
1073 
1074     MediaMemDecompBaseState *mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(*mosCtx->ppMediaMemDecompState);
1075 
1076     if (mosCtx->m_apoMosEnabled && !mediaMemDecompState)
1077     {
1078         DDI_CHK_NULL(mediaMemDecompState, "nullptr mediaMemDecompState", );
1079     }
1080 
1081     if (!mediaMemDecompState)
1082     {
1083         mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(MmdDevice::CreateFactory(mosCtx));
1084         *mosCtx->ppMediaMemDecompState = mediaMemDecompState;
1085     }
1086 
1087     if (mediaMemDecompState)
1088     {
1089         mediaMemDecompState->MemoryDecompress(osResource);
1090     }
1091     else
1092     {
1093         DDI_ASSERTMESSAGE("Invalid memory decompression state.");
1094     }
1095 }
1096 
1097 //!
1098 //! \brief  copy internal media surface to another surface
1099 //!
1100 //! \param  [in] mosCtx
1101 //!         Pointer to mos context
1102 //! \param  [in] inputOsResource
1103 //!         Pointer input mos resource
1104 //! \param  [in] outputOsResource
1105 //!         Pointer output mos resource
1106 //! \param  [in] boutputcompressed
1107 //!         output can be compressed or not
1108 //!
DdiMedia_MediaMemoryCopyInternal(PMOS_CONTEXT mosCtx,PMOS_RESOURCE inputOsResource,PMOS_RESOURCE outputOsResource,bool boutputcompressed)1109 void DdiMedia_MediaMemoryCopyInternal(PMOS_CONTEXT mosCtx, PMOS_RESOURCE inputOsResource, PMOS_RESOURCE outputOsResource, bool boutputcompressed)
1110 {
1111     DDI_CHK_NULL(mosCtx, "nullptr mosCtx",);
1112     DDI_CHK_NULL(inputOsResource, "nullptr input osResource",);
1113     DDI_CHK_NULL(outputOsResource, "nullptr output osResource",);
1114     DDI_ASSERT(inputOsResource);
1115     DDI_ASSERT(outputOsResource);
1116 
1117     MediaMemDecompBaseState *mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(*mosCtx->ppMediaMemDecompState);
1118 
1119     if (mosCtx->m_apoMosEnabled && !mediaMemDecompState)
1120     {
1121         DDI_CHK_NULL(mediaMemDecompState, "nullptr mediaMemDecompState", );
1122     }
1123 
1124     if (!mediaMemDecompState)
1125     {
1126         mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(MmdDevice::CreateFactory(mosCtx));
1127         *mosCtx->ppMediaMemDecompState = mediaMemDecompState;
1128     }
1129 
1130     if (mediaMemDecompState)
1131     {
1132         mediaMemDecompState->MediaMemoryCopy(inputOsResource, outputOsResource, boutputcompressed);
1133     }
1134     else
1135     {
1136         DDI_ASSERTMESSAGE("Invalid memory decompression state.");
1137     }
1138 }
1139 
1140 //!
1141 //! \brief  copy internal media surface/buffer to another surface/buffer
1142 //!
1143 //! \param  [in] mosCtx
1144 //!         Pointer to mos context
1145 //! \param  [in] inputOsResource
1146 //!         Pointer input mos resource
1147 //! \param  [in] outputOsResource
1148 //!         Pointer output mos resource
1149 //! \param  [in] boutputcompressed
1150 //!         output can be compressed or not
1151 //! \param  [in] copyWidth
1152 //!         The 2D surface Width
1153 //! \param  [in] copyHeight
1154 //!         The 2D surface height
1155 //! \param  [in] copyInputOffset
1156 //!         The offset of copied surface from
1157 //! \param  [in] copyOutputOffset
1158 //!         The offset of copied to
1159 //!
DdiMedia_MediaMemoryCopy2DInternal(PMOS_CONTEXT mosCtx,PMOS_RESOURCE inputOsResource,PMOS_RESOURCE outputOsResource,uint32_t copyWidth,uint32_t copyHeight,uint32_t copyInputOffset,uint32_t copyOutputOffset,uint32_t bpp,bool boutputcompressed)1160 void DdiMedia_MediaMemoryCopy2DInternal(PMOS_CONTEXT mosCtx, PMOS_RESOURCE inputOsResource, PMOS_RESOURCE outputOsResource, uint32_t copyWidth, uint32_t copyHeight, uint32_t copyInputOffset, uint32_t copyOutputOffset, uint32_t bpp, bool boutputcompressed)
1161 {
1162     DDI_CHK_NULL(mosCtx, "nullptr mosCtx",);
1163     DDI_CHK_NULL(inputOsResource, "nullptr input osResource",);
1164     DDI_CHK_NULL(outputOsResource, "nullptr output osResource",);
1165     DDI_ASSERT(inputOsResource);
1166     DDI_ASSERT(outputOsResource);
1167 
1168     MediaMemDecompBaseState *mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(*mosCtx->ppMediaMemDecompState);
1169 
1170     if (mosCtx->m_apoMosEnabled && !mediaMemDecompState)
1171     {
1172         DDI_CHK_NULL(mediaMemDecompState, "nullptr mediaMemDecompState", );
1173     }
1174 
1175     if (!mediaMemDecompState)
1176     {
1177         mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(MmdDevice::CreateFactory(mosCtx));
1178         *mosCtx->ppMediaMemDecompState = mediaMemDecompState;
1179     }
1180 
1181     if (mediaMemDecompState)
1182     {
1183         mediaMemDecompState->MediaMemoryCopy2D(
1184             inputOsResource,
1185             outputOsResource,
1186             copyWidth,
1187             copyHeight,
1188             copyInputOffset,
1189             copyOutputOffset,
1190             bpp,
1191             boutputcompressed);
1192     }
1193     else
1194     {
1195         DDI_ASSERTMESSAGE("Invalid memory decompression state.");
1196     }
1197 }
1198 
1199 //!
1200 //! \brief  Tile/Linear format conversion for media surface/buffer
1201 //!
1202 //! \param  [in] mosCtx
1203 //!         Pointer to mos context
1204 //! \param  [in] inputOsResource
1205 //!         Pointer input mos resource
1206 //! \param  [in] outputOsResource
1207 //!         Pointer output mos resource
1208 //! \param  [in] copyWidth
1209 //!         The 2D surface Width
1210 //! \param  [in] copyHeight
1211 //!         The 2D surface height
1212 //! \param  [in] copyInputOffset
1213 //!         The offset of copied surface from
1214 //! \param  [in] copyOutputOffset
1215 //!         The offset of copied to
1216 //! \param  [in] isTileToLinear
1217 //!         Convertion direction, true: tile->linear, false: linear->tile
1218 //! \param  [in] outputCompressed
1219 //!         output can be compressed or not
1220 //!
DdiMedia_MediaMemoryTileConvertInternal(PMOS_CONTEXT mosCtx,PMOS_RESOURCE inputOsResource,PMOS_RESOURCE outputOsResource,uint32_t copyWidth,uint32_t copyHeight,uint32_t copyInputOffset,uint32_t copyOutputOffset,bool isTileToLinear,bool outputCompressed)1221 VAStatus DdiMedia_MediaMemoryTileConvertInternal(
1222     PMOS_CONTEXT mosCtx,
1223     PMOS_RESOURCE inputOsResource,
1224     PMOS_RESOURCE outputOsResource,
1225     uint32_t copyWidth,
1226     uint32_t copyHeight,
1227     uint32_t copyInputOffset,
1228     uint32_t copyOutputOffset,
1229     bool isTileToLinear,
1230     bool outputCompressed)
1231 {
1232     DDI_CHK_NULL(mosCtx, "nullptr mosCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
1233     DDI_CHK_NULL(inputOsResource, "nullptr input osResource", VA_STATUS_ERROR_INVALID_PARAMETER);
1234     DDI_CHK_NULL(outputOsResource, "nullptr output osResource", VA_STATUS_ERROR_INVALID_PARAMETER);
1235     DDI_ASSERT(inputOsResource);
1236     DDI_ASSERT(outputOsResource);
1237 
1238     VAStatus vaStatus = VA_STATUS_SUCCESS;
1239 
1240     MediaMemDecompBaseState *mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(*mosCtx->ppMediaMemDecompState);
1241 
1242     if (mosCtx->m_apoMosEnabled && !mediaMemDecompState)
1243     {
1244         DDI_CHK_NULL(mediaMemDecompState, "nullptr mediaMemDecompState", VA_STATUS_ERROR_INVALID_PARAMETER);
1245     }
1246 
1247     if (!mediaMemDecompState)
1248     {
1249         mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(MmdDevice::CreateFactory(mosCtx));
1250         *mosCtx->ppMediaMemDecompState = mediaMemDecompState;
1251     }
1252 
1253     DDI_CHK_NULL(mediaMemDecompState, "Invalid memory decompression state", VA_STATUS_ERROR_INVALID_PARAMETER);
1254 
1255     MOS_STATUS mosStatus = mediaMemDecompState->MediaMemoryTileConvert(
1256             inputOsResource,
1257             outputOsResource,
1258             copyWidth,
1259             copyHeight,
1260             copyInputOffset,
1261             copyOutputOffset,
1262             isTileToLinear,
1263             outputCompressed);
1264     if (mosStatus != MOS_STATUS_SUCCESS)
1265     {
1266         vaStatus = VA_STATUS_ERROR_UNKNOWN;
1267     }
1268 
1269     return vaStatus;
1270 }
1271 #endif
1272 
1273 //!
1274 //! \brief  Decompress a compressed surface.
1275 //!
1276 //! \param  [in]     mediaCtx
1277 //!     Pointer to ddi media context
1278 //! \param  [in]     mediaSurface
1279 //!     Ddi media surface
1280 //!
1281 //! \return     VAStatus
1282 //!     VA_STATUS_SUCCESS if success, else fail reason
1283 //!
DdiMedia_MediaMemoryDecompress(PDDI_MEDIA_CONTEXT mediaCtx,DDI_MEDIA_SURFACE * mediaSurface)1284 VAStatus DdiMedia_MediaMemoryDecompress(PDDI_MEDIA_CONTEXT mediaCtx, DDI_MEDIA_SURFACE *mediaSurface)
1285 {
1286     DDI_CHK_NULL(mediaCtx, "Null mediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
1287     DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface", VA_STATUS_ERROR_INVALID_PARAMETER);
1288     DDI_CHK_NULL(mediaSurface->pGmmResourceInfo, "nullptr mediaSurface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_PARAMETER);
1289 
1290     VAStatus vaStatus = VA_STATUS_SUCCESS;
1291     GMM_RESOURCE_FLAG GmmFlags;
1292 
1293     MOS_ZeroMemory(&GmmFlags, sizeof(GmmFlags));
1294     GmmFlags = mediaSurface->pGmmResourceInfo->GetResFlags();
1295 
1296     if (((GmmFlags.Gpu.MMC                                                        ||
1297           GmmFlags.Gpu.CCS)                                                       &&
1298           GmmFlags.Info.MediaCompressed)                                          ||
1299           mediaSurface->pGmmResourceInfo->IsMediaMemoryCompressed(0))
1300     {
1301 #ifdef _MMC_SUPPORTED
1302         MOS_CONTEXT  mosCtx = {};
1303         MOS_RESOURCE surface;
1304         DdiCpInterface *pCpDdiInterface;
1305 
1306         MOS_ZeroMemory(&surface, sizeof(surface));
1307 
1308         mosCtx.bufmgr          = mediaCtx->pDrmBufMgr;
1309         mosCtx.m_gpuContextMgr = mediaCtx->m_gpuContextMgr;
1310         mosCtx.m_cmdBufMgr     = mediaCtx->m_cmdBufMgr;
1311         mosCtx.fd              = mediaCtx->fd;
1312         mosCtx.iDeviceId       = mediaCtx->iDeviceId;
1313         mosCtx.m_skuTable      = mediaCtx->SkuTable;
1314         mosCtx.m_waTable       = mediaCtx->WaTable;
1315         mosCtx.m_gtSystemInfo  = *mediaCtx->pGtSystemInfo;
1316         mosCtx.m_platform      = mediaCtx->platform;
1317 
1318         mosCtx.ppMediaMemDecompState = &mediaCtx->pMediaMemDecompState;
1319         mosCtx.pfnMemoryDecompress   = mediaCtx->pfnMemoryDecompress;
1320         mosCtx.pfnMediaMemoryCopy    = mediaCtx->pfnMediaMemoryCopy;
1321         mosCtx.pfnMediaMemoryCopy2D  = mediaCtx->pfnMediaMemoryCopy2D;
1322         mosCtx.m_gtSystemInfo        = *mediaCtx->pGtSystemInfo;
1323         mosCtx.m_auxTableMgr         = mediaCtx->m_auxTableMgr;
1324         mosCtx.pGmmClientContext     = mediaCtx->pGmmClientContext;
1325 
1326         mosCtx.m_osDeviceContext     = mediaCtx->m_osDeviceContext;
1327         mosCtx.m_apoMosEnabled       = mediaCtx->m_apoMosEnabled;
1328         mosCtx.m_userSettingPtr      = mediaCtx->m_userSettingPtr;
1329 
1330         pCpDdiInterface = Create_DdiCpInterface(mosCtx);
1331 
1332         if (nullptr == pCpDdiInterface)
1333         {
1334             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1335         }
1336         else
1337         {
1338             DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
1339             DdiMediaUtil_LockMutex(&mediaCtx->MemDecompMutex);
1340 
1341             DdiMedia_MediaSurfaceToMosResource(mediaSurface, &surface);
1342             DdiMedia_MediaMemoryDecompressInternal(&mosCtx, &surface);
1343 
1344             DdiMediaUtil_UnLockMutex(&mediaCtx->MemDecompMutex);
1345             DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
1346 
1347             if (pCpDdiInterface)
1348             {
1349                 Delete_DdiCpInterface(pCpDdiInterface);
1350                 pCpDdiInterface = NULL;
1351             }
1352         }
1353 #else
1354         vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1355         DDI_ASSERTMESSAGE("MMC unsupported! [%d].", vaStatus);
1356 #endif
1357     }
1358 
1359     return vaStatus;
1360 }
1361 
1362 /*
1363  * Initialize the library
1364  */
1365 
1366 // Global mutex
1367 MEDIA_MUTEX_T  GlobalMutex = MEDIA_MUTEX_INITIALIZER;
1368 
1369 //!
1370 //! \brief  Initialize
1371 //!
1372 //! \param  [in] mediaCtx
1373 //!         Pointer to DDI media driver context
1374 //!
1375 //! \return VAStatus
1376 //!     VA_STATUS_SUCCESS if success, else fail reason
1377 //!
DdiMedia_HeapInitialize(PDDI_MEDIA_CONTEXT mediaCtx)1378 static VAStatus DdiMedia_HeapInitialize(
1379     PDDI_MEDIA_CONTEXT mediaCtx)
1380 {
1381     DDI_CHK_NULL(mediaCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
1382 
1383     // Heap initialization here
1384     mediaCtx->pSurfaceHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP));
1385     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr pSurfaceHeap", VA_STATUS_ERROR_ALLOCATION_FAILED);
1386     mediaCtx->pSurfaceHeap->uiHeapElementSize = sizeof(DDI_MEDIA_SURFACE_HEAP_ELEMENT);
1387 
1388     mediaCtx->pBufferHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP));
1389     DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr BufferHeap", VA_STATUS_ERROR_ALLOCATION_FAILED);
1390     mediaCtx->pBufferHeap->uiHeapElementSize = sizeof(DDI_MEDIA_BUFFER_HEAP_ELEMENT);
1391 
1392     mediaCtx->pImageHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP));
1393     DDI_CHK_NULL(mediaCtx->pImageHeap, "nullptr ImageHeap", VA_STATUS_ERROR_ALLOCATION_FAILED);
1394     mediaCtx->pImageHeap->uiHeapElementSize = sizeof(DDI_MEDIA_IMAGE_HEAP_ELEMENT);
1395 
1396     mediaCtx->pDecoderCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP));
1397     DDI_CHK_NULL(mediaCtx->pDecoderCtxHeap, "nullptr DecoderCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED);
1398     mediaCtx->pDecoderCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT);
1399 
1400     mediaCtx->pEncoderCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP));
1401     DDI_CHK_NULL(mediaCtx->pEncoderCtxHeap, "nullptr EncoderCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED);
1402     mediaCtx->pEncoderCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT);
1403 
1404     mediaCtx->pVpCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP));
1405     DDI_CHK_NULL(mediaCtx->pVpCtxHeap, "nullptr VpCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED);
1406     mediaCtx->pVpCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT);
1407 
1408     mediaCtx->pProtCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP));
1409     DDI_CHK_NULL(mediaCtx->pProtCtxHeap, "nullptr pProtCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED);
1410     mediaCtx->pProtCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT);
1411 
1412     mediaCtx->pCmCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP));
1413     DDI_CHK_NULL(mediaCtx->pCmCtxHeap, "nullptr CmCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED);
1414     mediaCtx->pCmCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT);
1415 
1416     mediaCtx->pMfeCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP));
1417     DDI_CHK_NULL(mediaCtx->pMfeCtxHeap, "nullptr MfeCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED);
1418     mediaCtx->pMfeCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT);
1419 
1420     // init the mutexs
1421     DdiMediaUtil_InitMutex(&mediaCtx->SurfaceMutex);
1422     DdiMediaUtil_InitMutex(&mediaCtx->BufferMutex);
1423     DdiMediaUtil_InitMutex(&mediaCtx->ImageMutex);
1424     DdiMediaUtil_InitMutex(&mediaCtx->DecoderMutex);
1425     DdiMediaUtil_InitMutex(&mediaCtx->EncoderMutex);
1426     DdiMediaUtil_InitMutex(&mediaCtx->VpMutex);
1427     DdiMediaUtil_InitMutex(&mediaCtx->ProtMutex);
1428     DdiMediaUtil_InitMutex(&mediaCtx->CmMutex);
1429     DdiMediaUtil_InitMutex(&mediaCtx->MfeMutex);
1430 
1431     return VA_STATUS_SUCCESS;
1432 }
1433 
1434 //!
1435 //! \brief  Initialize
1436 //!
1437 //! \param  [in] mediaCtx
1438 //!         Pointer to DDI media driver context
1439 //!
1440 //! \return VAStatus
1441 //!     VA_STATUS_SUCCESS if success, else fail reason
1442 //!
DdiMedia_HeapDestroy(PDDI_MEDIA_CONTEXT mediaCtx)1443 static VAStatus DdiMedia_HeapDestroy(
1444     PDDI_MEDIA_CONTEXT mediaCtx)
1445 {
1446     DDI_CHK_NULL(mediaCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
1447     // destroy heaps
1448     MOS_FreeMemory(mediaCtx->pSurfaceHeap->pHeapBase);
1449     MOS_FreeMemory(mediaCtx->pSurfaceHeap);
1450 
1451     MOS_FreeMemory(mediaCtx->pBufferHeap->pHeapBase);
1452     MOS_FreeMemory(mediaCtx->pBufferHeap);
1453 
1454     MOS_FreeMemory(mediaCtx->pImageHeap->pHeapBase);
1455     MOS_FreeMemory(mediaCtx->pImageHeap);
1456 
1457     MOS_FreeMemory(mediaCtx->pDecoderCtxHeap->pHeapBase);
1458     MOS_FreeMemory(mediaCtx->pDecoderCtxHeap);
1459 
1460     MOS_FreeMemory(mediaCtx->pEncoderCtxHeap->pHeapBase);
1461     MOS_FreeMemory(mediaCtx->pEncoderCtxHeap);
1462 
1463     MOS_FreeMemory(mediaCtx->pVpCtxHeap->pHeapBase);
1464     MOS_FreeMemory(mediaCtx->pVpCtxHeap);
1465 
1466     MOS_FreeMemory(mediaCtx->pProtCtxHeap->pHeapBase);
1467     MOS_FreeMemory(mediaCtx->pProtCtxHeap);
1468 
1469     MOS_FreeMemory(mediaCtx->pCmCtxHeap->pHeapBase);
1470     MOS_FreeMemory(mediaCtx->pCmCtxHeap);
1471 
1472     MOS_FreeMemory(mediaCtx->pMfeCtxHeap->pHeapBase);
1473     MOS_FreeMemory(mediaCtx->pMfeCtxHeap);
1474     // destroy the mutexs
1475     DdiMediaUtil_DestroyMutex(&mediaCtx->SurfaceMutex);
1476     DdiMediaUtil_DestroyMutex(&mediaCtx->BufferMutex);
1477     DdiMediaUtil_DestroyMutex(&mediaCtx->ImageMutex);
1478     DdiMediaUtil_DestroyMutex(&mediaCtx->DecoderMutex);
1479     DdiMediaUtil_DestroyMutex(&mediaCtx->EncoderMutex);
1480     DdiMediaUtil_DestroyMutex(&mediaCtx->VpMutex);
1481     DdiMediaUtil_DestroyMutex(&mediaCtx->ProtMutex);
1482     DdiMediaUtil_DestroyMutex(&mediaCtx->CmMutex);
1483     DdiMediaUtil_DestroyMutex(&mediaCtx->MfeMutex);
1484 
1485     //resource checking
1486     if (mediaCtx->uiNumSurfaces != 0)
1487     {
1488         DDI_ASSERTMESSAGE("APP does not destroy all the surfaces.");
1489     }
1490     if (mediaCtx->uiNumBufs != 0)
1491     {
1492         DDI_ASSERTMESSAGE("APP does not destroy all the buffers.");
1493     }
1494     if (mediaCtx->uiNumImages != 0)
1495     {
1496         DDI_ASSERTMESSAGE("APP does not destroy all the images.");
1497     }
1498     if (mediaCtx->uiNumDecoders != 0)
1499     {
1500         DDI_ASSERTMESSAGE("APP does not destroy all the decoders.");
1501     }
1502     if (mediaCtx->uiNumEncoders != 0)
1503     {
1504         DDI_ASSERTMESSAGE("APP does not destroy all the encoders.");
1505     }
1506     if (mediaCtx->uiNumVPs != 0)
1507     {
1508         DDI_ASSERTMESSAGE("APP does not destroy all the VPs.");
1509     }
1510     if (mediaCtx->uiNumProts != 0)
1511     {
1512         DDI_ASSERTMESSAGE("APP does not destroy all the Prots.");
1513     }
1514     if (mediaCtx->uiNumCMs != 0)
1515     {
1516         DDI_ASSERTMESSAGE("APP does not destroy all the CMs.");
1517     }
1518     return VA_STATUS_SUCCESS;
1519 }
1520 
1521 //!
1522 //! \brief  Free for media context
1523 //!
1524 //! \param  [in] mediaCtx
1525 //!         Pointer to ddi media context
1526 //!
FreeForMediaContext(PDDI_MEDIA_CONTEXT mediaCtx)1527 void FreeForMediaContext(PDDI_MEDIA_CONTEXT mediaCtx)
1528 {
1529     DdiMediaUtil_UnLockMutex(&GlobalMutex);
1530 
1531     if (mediaCtx)
1532     {
1533         mediaCtx->SkuTable.reset();
1534         mediaCtx->WaTable.reset();
1535         MOS_FreeMemory(mediaCtx->pSurfaceHeap);
1536         MOS_FreeMemory(mediaCtx->pBufferHeap);
1537         MOS_FreeMemory(mediaCtx->pImageHeap);
1538         MOS_FreeMemory(mediaCtx->pDecoderCtxHeap);
1539         MOS_FreeMemory(mediaCtx->pEncoderCtxHeap);
1540         MOS_FreeMemory(mediaCtx->pVpCtxHeap);
1541         MOS_FreeMemory(mediaCtx->pProtCtxHeap);
1542         MOS_FreeMemory(mediaCtx->pMfeCtxHeap);
1543         mediaCtx->m_userSettingPtr.reset();
1544         MOS_Delete(mediaCtx);
1545     }
1546 
1547     return;
1548 }
1549 
DestroyMediaContextMutex(PDDI_MEDIA_CONTEXT mediaCtx)1550 void DestroyMediaContextMutex(PDDI_MEDIA_CONTEXT mediaCtx)
1551 {
1552     // destroy the mutexs
1553     DdiMediaUtil_DestroyMutex(&mediaCtx->SurfaceMutex);
1554     DdiMediaUtil_DestroyMutex(&mediaCtx->BufferMutex);
1555     DdiMediaUtil_DestroyMutex(&mediaCtx->ImageMutex);
1556     DdiMediaUtil_DestroyMutex(&mediaCtx->DecoderMutex);
1557     DdiMediaUtil_DestroyMutex(&mediaCtx->EncoderMutex);
1558     DdiMediaUtil_DestroyMutex(&mediaCtx->VpMutex);
1559     DdiMediaUtil_DestroyMutex(&mediaCtx->CmMutex);
1560     DdiMediaUtil_DestroyMutex(&mediaCtx->MfeMutex);
1561 #if !defined(ANDROID) && defined(X11_FOUND)
1562     DdiMediaUtil_DestroyMutex(&mediaCtx->PutSurfaceRenderMutex);
1563     DdiMediaUtil_DestroyMutex(&mediaCtx->PutSurfaceSwapBufferMutex);
1564 #endif
1565     return;
1566 }
1567 
DdiMedia_GetDeviceFD(VADriverContextP ctx,int32_t * pDevicefd)1568 VAStatus DdiMedia_GetDeviceFD (
1569     VADriverContextP ctx,
1570     int32_t         *pDevicefd
1571 )
1572 {
1573     struct drm_state *pDRMState = (struct drm_state *)ctx->drm_state;
1574     DDI_CHK_NULL(pDRMState,    "nullptr pDRMState", VA_STATUS_ERROR_INVALID_CONTEXT);
1575     DDI_CHK_NULL(pDevicefd,    "nullptr pDevicefd", VA_STATUS_ERROR_INVALID_CONTEXT);
1576 
1577     // If libva failes to open the graphics card, try to open it again within Media Driver
1578     if(pDRMState->fd < 0)
1579     {
1580         DDI_ASSERTMESSAGE("DDI:LIBVA Wrapper doesn't pass file descriptor for graphics adaptor, trying to open the graphics... ");
1581         pDRMState->fd = DdiMediaUtil_OpenGraphicsAdaptor((char *)DEVICE_NAME);
1582         if (pDRMState->fd < 0) {
1583             DDI_ASSERTMESSAGE("DDI: Still failed to open the graphic adaptor, return failure");
1584             return VA_STATUS_ERROR_INVALID_PARAMETER;
1585         }
1586     }
1587     *pDevicefd = pDRMState->fd;
1588 
1589     return VA_STATUS_SUCCESS;
1590 }
1591 
1592 #ifdef _MANUAL_SOFTLET_
1593 
DdiMedia_CleanUpSoftlet(PDDI_MEDIA_CONTEXT mediaCtx)1594 VAStatus DdiMedia_CleanUpSoftlet(PDDI_MEDIA_CONTEXT mediaCtx)
1595 {
1596     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
1597 
1598     if (mediaCtx->m_capsNext)
1599     {
1600         MOS_Delete(mediaCtx->m_capsNext);
1601         mediaCtx->m_capsNext = nullptr;
1602     }
1603 
1604     MediaLibvaInterfaceNext::ReleaseCompList(mediaCtx);
1605     if(mediaCtx->m_hwInfo)
1606     {
1607         MOS_Delete(mediaCtx->m_hwInfo);
1608         mediaCtx->m_hwInfo = nullptr;
1609     }
1610 
1611     return VA_STATUS_SUCCESS;
1612 }
1613 
DdiMedia__InitializeSoftlet(PDDI_MEDIA_CONTEXT mediaCtx,bool apoDdiEnabled)1614 VAStatus DdiMedia__InitializeSoftlet(
1615     PDDI_MEDIA_CONTEXT mediaCtx,
1616     bool               apoDdiEnabled)
1617 {
1618     VAStatus status = VA_STATUS_SUCCESS;
1619 
1620     if (nullptr == mediaCtx)
1621     {
1622         FreeForMediaContext(mediaCtx);
1623         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1624     }
1625 
1626     do
1627     {
1628         if(apoDdiEnabled)
1629         {
1630             mediaCtx->m_hwInfo = MediaInterfacesHwInfoDevice::CreateFactory(mediaCtx->platform);
1631             if (nullptr == mediaCtx->m_hwInfo)
1632             {
1633                 DDI_ASSERTMESSAGE("Unregister hwinfo platform.");
1634                 status = VA_STATUS_ERROR_ALLOCATION_FAILED;
1635                 break;
1636             }
1637 
1638             mediaCtx->m_capsNext = MediaLibvaCapsNext::CreateCaps(mediaCtx);
1639             if (!mediaCtx->m_capsNext)
1640             {
1641                 DDI_ASSERTMESSAGE("Caps next create failed. Not supported GFX device.");
1642                 status = VA_STATUS_ERROR_ALLOCATION_FAILED;
1643                 break;
1644             }
1645 
1646             if(mediaCtx->m_capsNext->Init() != VA_STATUS_SUCCESS)
1647             {
1648                 DDI_ASSERTMESSAGE("Caps next init failed.");
1649                 status = VA_STATUS_ERROR_ALLOCATION_FAILED;
1650                 break;
1651             }
1652 
1653             if (MediaLibvaInterfaceNext::InitCompList(mediaCtx) != VA_STATUS_SUCCESS)
1654             {
1655                 DDI_ASSERTMESSAGE("Init CompList failed. Not supported GFX device.");
1656                 status =  VA_STATUS_ERROR_ALLOCATION_FAILED;
1657                 break;
1658             }
1659         }
1660     } while(false);
1661 
1662     if (status != VA_STATUS_SUCCESS)
1663     {
1664         DdiMedia_CleanUp(mediaCtx);
1665         DestroyMediaContextMutex(mediaCtx);
1666         FreeForMediaContext(mediaCtx);
1667     }
1668 
1669     return status;
1670 }
1671 
1672 #endif
1673 
DdiMedia__Initialize(VADriverContextP ctx,int32_t * major_version,int32_t * minor_version)1674 VAStatus DdiMedia__Initialize (
1675     VADriverContextP ctx,
1676     int32_t         *major_version,
1677     int32_t         *minor_version
1678 )
1679 {
1680 #if !defined(ANDROID) && defined(X11_FOUND)
1681     // ATRACE code in <cutils/trace.h> started from KitKat, version = 440
1682     // ENABLE_TRACE is defined only for eng build so release build won't leak perf data
1683     // thus trace code enabled only on KitKat (and newer) && eng build
1684 #if ANDROID_VERSION > 439 && defined(ENABLE_ATRACE)
1685     char switch_value[PROPERTY_VALUE_MAX];
1686 
1687     property_get("debug.DdiCodec_.umd", switch_value, "0");
1688     atrace_switch = atoi(switch_value);
1689 #endif
1690 #endif
1691 
1692     DDI_CHK_NULL(ctx,          "nullptr ctx",       VA_STATUS_ERROR_INVALID_CONTEXT);
1693 
1694     VAStatus status = VA_STATUS_SUCCESS;
1695     bool    apoDdiEnabled = false;
1696     int32_t devicefd = 0;
1697     if(DdiMedia_GetDeviceFD(ctx, &devicefd) != VA_STATUS_SUCCESS)
1698     {
1699         DDI_ASSERTMESSAGE("Unable to get device FD");
1700         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1701     }
1702 
1703     status           = DdiMedia_InitMediaContext(ctx, devicefd, major_version, minor_version, apoDdiEnabled);
1704     if(status != VA_STATUS_SUCCESS)
1705     {
1706         DDI_ASSERTMESSAGE("Failed to init media context");
1707         return status;
1708     }
1709 
1710     if(!apoDdiEnabled)
1711     {
1712         if(DdiMedia_LoadFuncion(ctx) != VA_STATUS_SUCCESS)
1713         {
1714             DDI_ASSERTMESSAGE("Failed to load function pointer");
1715             return VA_STATUS_ERROR_ALLOCATION_FAILED;
1716         }
1717     }
1718 #ifdef _MANUAL_SOFTLET_
1719     else
1720     {
1721         if(MediaLibvaInterface::LoadFunction(ctx) != VA_STATUS_SUCCESS)
1722         {
1723             DDI_ASSERTMESSAGE("Failed to load function pointer");
1724             return VA_STATUS_ERROR_ALLOCATION_FAILED;
1725         }
1726     }
1727 #endif
1728 
1729     return status;
1730 }
1731 
DdiMedia_InitMediaContext(VADriverContextP ctx,int32_t devicefd,int32_t * major_version,int32_t * minor_version,bool & apoDdiEnabled)1732 VAStatus DdiMedia_InitMediaContext (
1733     VADriverContextP ctx,
1734     int32_t          devicefd,
1735     int32_t          *major_version,
1736     int32_t          *minor_version,
1737     bool             &apoDdiEnabled
1738 )
1739 {
1740     DDI_FUNCTION_ENTER();
1741 
1742     if(major_version)
1743     {
1744         *major_version = VA_MAJOR_VERSION;
1745     }
1746 
1747     if(minor_version)
1748     {
1749         *minor_version = VA_MINOR_VERSION;
1750     }
1751 
1752     DdiMediaUtil_LockMutex(&GlobalMutex);
1753     // media context is already created, return directly to support multiple entry
1754     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
1755     if(mediaCtx)
1756     {
1757         FreeForMediaContext(mediaCtx);
1758     }
1759 
1760     mediaCtx = DdiMedia_CreateMediaDriverContext();
1761     if (nullptr == mediaCtx)
1762     {
1763         FreeForMediaContext(mediaCtx);
1764         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1765     }
1766     mediaCtx->uiRef++;
1767     ctx->pDriverData = (void *)mediaCtx;
1768     mediaCtx->fd     = devicefd;
1769 
1770     mediaCtx->m_userSettingPtr = std::make_shared<MediaUserSetting::MediaUserSetting>();
1771 
1772     MOS_CONTEXT mosCtx     = {};
1773     mosCtx.fd              = mediaCtx->fd;
1774     mosCtx.m_userSettingPtr = mediaCtx->m_userSettingPtr;
1775 
1776     MosInterface::InitOsUtilities(&mosCtx);
1777     mediaCtx->m_apoMosEnabled = SetupApoMosSwitch(devicefd, mediaCtx->m_userSettingPtr);
1778 
1779 #ifdef _MMC_SUPPORTED
1780     mediaCtx->pfnMemoryDecompress  = DdiMedia_MediaMemoryDecompressInternal;
1781     mediaCtx->pfnMediaMemoryCopy   = DdiMedia_MediaMemoryCopyInternal;
1782     mediaCtx->pfnMediaMemoryCopy2D = DdiMedia_MediaMemoryCopy2DInternal;
1783     mediaCtx->pfnMediaMemoryTileConvert = DdiMedia_MediaMemoryTileConvertInternal;
1784 #endif
1785     mediaCtx->modularizedGpuCtxEnabled = true;
1786 
1787     if (mediaCtx->m_apoMosEnabled)
1788     {
1789         mosCtx.fd              = mediaCtx->fd;
1790         mosCtx.m_apoMosEnabled = mediaCtx->m_apoMosEnabled;
1791 
1792         MosOcaInterfaceSpecific::InitInterface(&mosCtx);
1793 
1794         mediaCtx->pGtSystemInfo = (MEDIA_SYSTEM_INFO *)MOS_AllocAndZeroMemory(sizeof(MEDIA_SYSTEM_INFO));
1795         if (nullptr == mediaCtx->pGtSystemInfo)
1796         {
1797             FreeForMediaContext(mediaCtx);
1798             return VA_STATUS_ERROR_ALLOCATION_FAILED;
1799         }
1800 
1801         if (MosInterface::CreateOsDeviceContext(&mosCtx, &mediaCtx->m_osDeviceContext) != MOS_STATUS_SUCCESS)
1802         {
1803             DDI_ASSERTMESSAGE("Unable to create MOS device context.");
1804             FreeForMediaContext(mediaCtx);
1805             return VA_STATUS_ERROR_OPERATION_FAILED;
1806         }
1807         mediaCtx->pDrmBufMgr                = mosCtx.bufmgr;
1808         mediaCtx->iDeviceId                 = mosCtx.iDeviceId;
1809         mediaCtx->SkuTable                  = mosCtx.m_skuTable;
1810         mediaCtx->WaTable                   = mosCtx.m_waTable;
1811         *mediaCtx->pGtSystemInfo            = mosCtx.m_gtSystemInfo;
1812         mediaCtx->platform                  = mosCtx.m_platform;
1813         mediaCtx->m_auxTableMgr             = mosCtx.m_auxTableMgr;
1814         mediaCtx->pGmmClientContext         = mosCtx.pGmmClientContext;
1815         mediaCtx->m_useSwSwizzling          = mosCtx.bUseSwSwizzling;
1816         mediaCtx->m_tileYFlag               = mosCtx.bTileYFlag;
1817         mediaCtx->bIsAtomSOC                = mosCtx.bIsAtomSOC;
1818         mediaCtx->perfData                  = mosCtx.pPerfData;
1819 
1820 #ifdef _MMC_SUPPORTED
1821         if (mosCtx.ppMediaMemDecompState == nullptr)
1822         {
1823             DDI_ASSERTMESSAGE("media decomp state is null.");
1824             FreeForMediaContext(mediaCtx);
1825             return VA_STATUS_ERROR_OPERATION_FAILED;
1826         }
1827         mediaCtx->pMediaMemDecompState      = *mosCtx.ppMediaMemDecompState;
1828 #endif
1829         mediaCtx->pMediaCopyState           = *mosCtx.ppMediaCopyState;
1830     }
1831     else if (mediaCtx->modularizedGpuCtxEnabled)
1832     {
1833         mediaCtx->pDrmBufMgr = mos_bufmgr_gem_init(mediaCtx->fd, DDI_CODEC_BATCH_BUFFER_SIZE);
1834         if (nullptr == mediaCtx->pDrmBufMgr)
1835         {
1836             DDI_ASSERTMESSAGE("DDI:No able to allocate buffer manager, fd=0x%d", mediaCtx->fd);
1837             FreeForMediaContext(mediaCtx);
1838             return VA_STATUS_ERROR_INVALID_PARAMETER;
1839         }
1840         mos_bufmgr_enable_reuse(mediaCtx->pDrmBufMgr);
1841 
1842         //Latency reducation:replace HWGetDeviceID to get device using ioctl from drm.
1843         mediaCtx->iDeviceId = mos_bufmgr_get_devid(mediaCtx->pDrmBufMgr);
1844 
1845         //TO--DO, apo set it to FALSE by default, to remove the logic in apo mos controlled by it????
1846         mediaCtx->bIsAtomSOC = IS_ATOMSOC(mediaCtx->iDeviceId);
1847 
1848         MEDIA_FEATURE_TABLE *skuTable = &mediaCtx->SkuTable;
1849         MEDIA_WA_TABLE *     waTable  = &mediaCtx->WaTable;
1850         skuTable->reset();
1851         waTable->reset();
1852         // get Sku/Wa tables and platform information
1853         PLATFORM platform = {};
1854         // Allocate memory for Media System Info
1855         mediaCtx->pGtSystemInfo = (MEDIA_SYSTEM_INFO *)MOS_AllocAndZeroMemory(sizeof(MEDIA_SYSTEM_INFO));
1856         if (nullptr == mediaCtx->pGtSystemInfo)
1857         {
1858             FreeForMediaContext(mediaCtx);
1859             return VA_STATUS_ERROR_ALLOCATION_FAILED;
1860         }
1861         MOS_STATUS eStatus = HWInfo_GetGfxInfo(mediaCtx->fd, mediaCtx->pDrmBufMgr, &platform, skuTable, waTable, mediaCtx->pGtSystemInfo, mediaCtx->m_userSettingPtr);
1862         if (MOS_STATUS_SUCCESS != eStatus)
1863         {
1864             DDI_ASSERTMESSAGE("Fatal error - unsuccesfull Sku/Wa/GtSystemInfo initialization");
1865             FreeForMediaContext(mediaCtx);
1866             return VA_STATUS_ERROR_OPERATION_FAILED;
1867         }
1868         mediaCtx->platform = platform;
1869 
1870         MosUtilities::MosTraceSetupInfo(
1871             (VA_MAJOR_VERSION << 16) | VA_MINOR_VERSION,
1872             platform.eProductFamily,
1873             platform.eRenderCoreFamily,
1874             (platform.usRevId << 16) | platform.usDeviceID);
1875 
1876         //TO--DO, gen12+ still need this wa????, not porting yet
1877         if (MEDIA_IS_SKU(skuTable, FtrEnableMediaKernels) == 0)
1878         {
1879             MEDIA_WR_WA(waTable, WaHucStreamoutOnlyDisable, 0);
1880         }
1881 
1882         GMM_SKU_FEATURE_TABLE gmmSkuTable;
1883         memset(&gmmSkuTable, 0, sizeof(gmmSkuTable));
1884 
1885         GMM_WA_TABLE gmmWaTable;
1886         memset(&gmmWaTable, 0, sizeof(gmmWaTable));
1887 
1888         GMM_GT_SYSTEM_INFO gmmGtInfo;
1889         memset(&gmmGtInfo, 0, sizeof(gmmGtInfo));
1890 
1891         GMM_ADAPTER_BDF gmmAdapterBDF;
1892         memset(&gmmAdapterBDF, 0, sizeof(gmmAdapterBDF));
1893 
1894         eStatus = HWInfo_GetGmmInfo(mediaCtx->pDrmBufMgr, &gmmSkuTable, &gmmWaTable, &gmmGtInfo);
1895         if (MOS_STATUS_SUCCESS != eStatus)
1896         {
1897             DDI_ASSERTMESSAGE("Fatal error - unsuccesfull Gmm Sku/Wa/GtSystemInfo initialization");
1898             FreeForMediaContext(mediaCtx);
1899             return VA_STATUS_ERROR_OPERATION_FAILED;
1900         }
1901 
1902         eStatus = Mos_Solo_DdiInitializeDeviceId(
1903             (void *)mediaCtx->pDrmBufMgr,
1904             &mediaCtx->SkuTable,
1905             &mediaCtx->WaTable,
1906             &gmmSkuTable,
1907             &gmmWaTable,
1908             &gmmGtInfo,
1909             &mediaCtx->iDeviceId,
1910             &mediaCtx->fd,
1911             &mediaCtx->platform,
1912             mediaCtx->m_userSettingPtr);
1913         if (eStatus != MOS_STATUS_SUCCESS)
1914         {
1915             FreeForMediaContext(mediaCtx);
1916             return VA_STATUS_ERROR_OPERATION_FAILED;
1917         }
1918 
1919         // fill in the mos context struct as input to initialize m_osContext
1920         mosCtx.bufmgr                = mediaCtx->pDrmBufMgr;
1921         mosCtx.fd                    = mediaCtx->fd;
1922         mosCtx.iDeviceId             = mediaCtx->iDeviceId;
1923         mosCtx.m_skuTable            = mediaCtx->SkuTable;
1924         mosCtx.m_waTable             = mediaCtx->WaTable;
1925         mosCtx.m_gtSystemInfo        = *mediaCtx->pGtSystemInfo;
1926         mosCtx.m_platform            = mediaCtx->platform;
1927         mosCtx.ppMediaMemDecompState = &mediaCtx->pMediaMemDecompState;
1928         mosCtx.pfnMemoryDecompress   = mediaCtx->pfnMemoryDecompress;
1929         mosCtx.pfnMediaMemoryCopy    = mediaCtx->pfnMediaMemoryCopy;
1930         mosCtx.pfnMediaMemoryCopy2D  = mediaCtx->pfnMediaMemoryCopy2D;
1931         mosCtx.ppMediaCopyState      = &mediaCtx->pMediaCopyState;
1932 
1933         eStatus = MosInterface::GetAdapterBDF(&mosCtx, &gmmAdapterBDF);
1934         if (MOS_STATUS_SUCCESS != eStatus)
1935         {
1936             DDI_ASSERTMESSAGE("Fatal error - unsuccesfull Gmm Adapter BDF initialization");
1937             FreeForMediaContext(mediaCtx);
1938             return VA_STATUS_ERROR_OPERATION_FAILED;
1939         }
1940 
1941         // Initialize Gmm context
1942         GMM_INIT_IN_ARGS  gmmInitAgrs = {};
1943         GMM_INIT_OUT_ARGS gmmOutArgs  = {};
1944         gmmInitAgrs.Platform          = mediaCtx->platform;
1945         gmmInitAgrs.pSkuTable         = &gmmSkuTable;
1946         gmmInitAgrs.pWaTable          = &gmmWaTable;
1947         gmmInitAgrs.pGtSysInfo        = &gmmGtInfo;
1948         gmmInitAgrs.FileDescriptor    = gmmAdapterBDF.Data;
1949         gmmInitAgrs.ClientType        = (GMM_CLIENT)GMM_LIBVA_LINUX;
1950 
1951         GMM_STATUS status = InitializeGmm(&gmmInitAgrs, &gmmOutArgs);
1952         if (status != GMM_SUCCESS)
1953         {
1954             DDI_ASSERTMESSAGE("InitializeGmm fail.");
1955             FreeForMediaContext(mediaCtx);
1956             return VA_STATUS_ERROR_OPERATION_FAILED;
1957         }
1958         mediaCtx->pGmmClientContext = gmmOutArgs.pGmmClientContext;
1959 
1960         // Create GMM page table manager
1961         mediaCtx->m_auxTableMgr = AuxTableMgr::CreateAuxTableMgr(mediaCtx->pDrmBufMgr, &mediaCtx->SkuTable, mediaCtx->pGmmClientContext);
1962 
1963         bool bSimulationEnable = false;
1964 #if (_DEBUG || _RELEASE_INTERNAL)
1965         ReadUserSettingForDebug(
1966             mediaCtx->m_userSettingPtr,
1967             bSimulationEnable,
1968             __MEDIA_USER_FEATURE_VALUE_SIM_ENABLE,
1969             MediaUserSetting::Group::Device);
1970 #endif
1971 
1972         mediaCtx->m_useSwSwizzling = bSimulationEnable || MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrUseSwSwizzling);
1973         mediaCtx->m_tileYFlag      = MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrTileY);
1974 
1975         mediaCtx->m_osContext = OsContext::GetOsContextObject();
1976         if (mediaCtx->m_osContext == nullptr)
1977         {
1978             MOS_OS_ASSERTMESSAGE("Unable to get the active OS context.");
1979             FreeForMediaContext(mediaCtx);
1980             return VA_STATUS_ERROR_OPERATION_FAILED;
1981         }
1982 
1983         mosCtx.m_auxTableMgr         = mediaCtx->m_auxTableMgr;
1984         mosCtx.pGmmClientContext     = mediaCtx->pGmmClientContext;
1985 
1986         eStatus = mediaCtx->m_osContext->Init(&mosCtx);
1987         if (MOS_STATUS_SUCCESS != eStatus)
1988         {
1989             MOS_OS_ASSERTMESSAGE("Unable to initialize OS context.");
1990             FreeForMediaContext(mediaCtx);
1991             return VA_STATUS_ERROR_OPERATION_FAILED;
1992         }
1993 
1994         // Prepare the command buffer manager
1995         mediaCtx->m_cmdBufMgr = CmdBufMgr::GetObject();
1996         if (mediaCtx->m_cmdBufMgr == nullptr)
1997         {
1998             MOS_OS_ASSERTMESSAGE(" nullptr returned by CmdBufMgr::GetObject");
1999             FreeForMediaContext(mediaCtx);
2000             return VA_STATUS_ERROR_OPERATION_FAILED;
2001         }
2002 
2003         MOS_STATUS ret = mediaCtx->m_cmdBufMgr->Initialize(mediaCtx->m_osContext, COMMAND_BUFFER_SIZE/2);
2004         if (ret != MOS_STATUS_SUCCESS)
2005         {
2006             MOS_OS_ASSERTMESSAGE(" cmdBufMgr Initialization failed");
2007             FreeForMediaContext(mediaCtx);
2008             return VA_STATUS_ERROR_OPERATION_FAILED;
2009         }
2010 
2011         // Prepare the gpu Context manager
2012         mediaCtx->m_gpuContextMgr = GpuContextMgr::GetObject(mediaCtx->pGtSystemInfo, mediaCtx->m_osContext);
2013         if (mediaCtx->m_gpuContextMgr == nullptr)
2014         {
2015             MOS_OS_ASSERTMESSAGE(" nullptr returned by GpuContextMgr::GetObject");
2016             FreeForMediaContext(mediaCtx);
2017             return VA_STATUS_ERROR_OPERATION_FAILED;
2018         }
2019     }
2020     else
2021     {
2022         MOS_OS_ASSERTMESSAGE(" Invalid mos module state");
2023         FreeForMediaContext(mediaCtx);
2024         return VA_STATUS_ERROR_INVALID_PARAMETER;
2025     }
2026 
2027     if (DdiMedia_HeapInitialize(mediaCtx) != VA_STATUS_SUCCESS)
2028     {
2029         DestroyMediaContextMutex(mediaCtx);
2030         FreeForMediaContext(mediaCtx);
2031         return VA_STATUS_ERROR_ALLOCATION_FAILED;
2032     }
2033 
2034     //Caps need platform and sku table, especially in MediaLibvaCapsCp::IsDecEncryptionSupported
2035 #ifdef _MANUAL_SOFTLET_
2036     apoDdiEnabled = MediaLibvaApoDecision::InitDdiApoState(devicefd, mediaCtx->m_userSettingPtr);
2037     mediaCtx->m_apoDdiEnabled = apoDdiEnabled;
2038     if(mediaCtx->m_apoDdiEnabled)
2039     {
2040         if (DdiMedia__InitializeSoftlet(mediaCtx, apoDdiEnabled) != VA_STATUS_SUCCESS)
2041         {
2042             DDI_ASSERTMESSAGE("Softlet initialize failed");
2043             return VA_STATUS_ERROR_ALLOCATION_FAILED;
2044         }
2045         ctx->max_image_formats = mediaCtx->m_capsNext->GetImageFormatsMaxNum();
2046     }
2047     else
2048 #endif
2049     {
2050         mediaCtx->m_caps = MediaLibvaCaps::CreateMediaLibvaCaps(mediaCtx);
2051         if (!mediaCtx->m_caps)
2052         {
2053             DDI_ASSERTMESSAGE("Caps create failed. Not supported GFX device.");
2054             DestroyMediaContextMutex(mediaCtx);
2055             FreeForMediaContext(mediaCtx);
2056             return VA_STATUS_ERROR_ALLOCATION_FAILED;
2057         }
2058 
2059         if (mediaCtx->m_caps->Init() != VA_STATUS_SUCCESS)
2060         {
2061             DDI_ASSERTMESSAGE("Caps init failed. Not supported GFX device.");
2062             DdiMedia_CleanUp(mediaCtx);
2063             DestroyMediaContextMutex(mediaCtx);
2064             FreeForMediaContext(mediaCtx);
2065             return VA_STATUS_ERROR_ALLOCATION_FAILED;
2066         }
2067         ctx->max_image_formats = mediaCtx->m_caps->GetImageFormatsMaxNum();
2068     }
2069 
2070 #if !defined(ANDROID) && defined(X11_FOUND)
2071     DdiMediaUtil_InitMutex(&mediaCtx->PutSurfaceRenderMutex);
2072     DdiMediaUtil_InitMutex(&mediaCtx->PutSurfaceSwapBufferMutex);
2073 
2074     // try to open X11 lib, if fail, assume no X11 environment
2075     if (VA_STATUS_SUCCESS != DdiMedia_ConnectX11(mediaCtx))
2076     {
2077         // assume no X11 environment. In current implementation,
2078         // PutSurface (Linux) needs X11 support, so just replace
2079         // it with a dummy version. DdiCodec_PutSurfaceDummy() will
2080         // return VA_STATUS_ERROR_UNIMPLEMENTED directly.
2081         ctx->vtable->vaPutSurface = NULL;
2082     }
2083     output_dri_init(ctx);
2084 #endif
2085 
2086     DdiMediaUtil_SetMediaResetEnableFlag(mediaCtx);
2087 
2088     DdiMediaUtil_UnLockMutex(&GlobalMutex);
2089 
2090     return VA_STATUS_SUCCESS;
2091 }
2092 
DdiMedia_LoadFuncion(VADriverContextP ctx)2093 VAStatus DdiMedia_LoadFuncion (VADriverContextP ctx)
2094 {
2095     DDI_CHK_NULL(ctx,         "nullptr ctx",          VA_STATUS_ERROR_INVALID_CONTEXT);
2096 
2097     struct VADriverVTable    *pVTable     = DDI_CODEC_GET_VTABLE(ctx);
2098     DDI_CHK_NULL(pVTable,     "nullptr pVTable",      VA_STATUS_ERROR_INVALID_CONTEXT);
2099 
2100     struct VADriverVTableVPP *pVTableVpp  = DDI_CODEC_GET_VTABLE_VPP(ctx);
2101     DDI_CHK_NULL(pVTableVpp,  "nullptr pVTableVpp",   VA_STATUS_ERROR_INVALID_CONTEXT);
2102 
2103 #if VA_CHECK_VERSION(1,11,0)
2104     struct VADriverVTableProt *pVTableProt = DDI_CODEC_GET_VTABLE_PROT(ctx);
2105     DDI_CHK_NULL(pVTableProt,  "nullptr pVTableProt",   VA_STATUS_ERROR_INVALID_CONTEXT);
2106 #endif
2107 
2108     ctx->version_major                       = VA_MAJOR_VERSION;
2109     ctx->version_minor                       = VA_MINOR_VERSION;
2110     ctx->max_profiles                        = DDI_CODEC_GEN_MAX_PROFILES;
2111     ctx->max_entrypoints                     = DDI_CODEC_GEN_MAX_ENTRYPOINTS;
2112     ctx->max_attributes                      = (int32_t)VAConfigAttribTypeMax;
2113     ctx->max_subpic_formats                  = DDI_CODEC_GEN_MAX_SUBPIC_FORMATS;
2114     ctx->max_display_attributes              = DDI_MEDIA_GEN_MAX_DISPLAY_ATTRIBUTES;
2115     ctx->str_vendor                          = DDI_CODEC_GEN_STR_VENDOR;
2116     ctx->vtable_tpi                          = nullptr;
2117 
2118     pVTable->vaTerminate                     = DdiMedia_Terminate;
2119     pVTable->vaQueryConfigEntrypoints        = DdiMedia_QueryConfigEntrypoints;
2120     pVTable->vaQueryConfigProfiles           = DdiMedia_QueryConfigProfiles;
2121     pVTable->vaQueryConfigAttributes         = DdiMedia_QueryConfigAttributes;
2122     pVTable->vaCreateConfig                  = DdiMedia_CreateConfig;
2123     pVTable->vaDestroyConfig                 = DdiMedia_DestroyConfig;
2124     pVTable->vaGetConfigAttributes           = DdiMedia_GetConfigAttributes;
2125 
2126     pVTable->vaCreateSurfaces                = DdiMedia_CreateSurfaces;
2127     pVTable->vaDestroySurfaces               = DdiMedia_DestroySurfaces;
2128     pVTable->vaCreateSurfaces2               = DdiMedia_CreateSurfaces2;
2129 
2130     pVTable->vaCreateContext                 = DdiMedia_CreateContext;
2131     pVTable->vaDestroyContext                = DdiMedia_DestroyContext;
2132     pVTable->vaCreateBuffer                  = DdiMedia_CreateBuffer;
2133     pVTable->vaBufferSetNumElements          = DdiMedia_BufferSetNumElements;
2134     pVTable->vaMapBuffer                     = DdiMedia_MapBuffer;
2135     pVTable->vaUnmapBuffer                   = DdiMedia_UnmapBuffer;
2136     pVTable->vaDestroyBuffer                 = DdiMedia_DestroyBuffer;
2137     pVTable->vaBeginPicture                  = DdiMedia_BeginPicture;
2138     pVTable->vaRenderPicture                 = DdiMedia_RenderPicture;
2139     pVTable->vaEndPicture                    = DdiMedia_EndPicture;
2140     pVTable->vaSyncSurface                   = DdiMedia_SyncSurface;
2141 #if VA_CHECK_VERSION(1, 9, 0)
2142     pVTable->vaSyncSurface2                  = DdiMedia_SyncSurface2;
2143     pVTable->vaSyncBuffer                    = DdiMedia_SyncBuffer;
2144 #endif
2145     pVTable->vaQuerySurfaceStatus            = DdiMedia_QuerySurfaceStatus;
2146     pVTable->vaQuerySurfaceError             = DdiMedia_QuerySurfaceError;
2147     pVTable->vaQuerySurfaceAttributes        = DdiMedia_QuerySurfaceAttributes;
2148     pVTable->vaPutSurface                    = DdiMedia_PutSurface;
2149     pVTable->vaQueryImageFormats             = DdiMedia_QueryImageFormats;
2150 
2151     pVTable->vaCreateImage                   = DdiMedia_CreateImage;
2152     pVTable->vaDeriveImage                   = DdiMedia_DeriveImage;
2153     pVTable->vaDestroyImage                  = DdiMedia_DestroyImage;
2154     pVTable->vaSetImagePalette               = DdiMedia_SetImagePalette;
2155     pVTable->vaGetImage                      = DdiMedia_GetImage;
2156     pVTable->vaPutImage                      = DdiMedia_PutImage;
2157     pVTable->vaQuerySubpictureFormats        = DdiMedia_QuerySubpictureFormats;
2158     pVTable->vaCreateSubpicture              = DdiMedia_CreateSubpicture;
2159     pVTable->vaDestroySubpicture             = DdiMedia_DestroySubpicture;
2160     pVTable->vaSetSubpictureImage            = DdiMedia_SetSubpictureImage;
2161     pVTable->vaSetSubpictureChromakey        = DdiMedia_SetSubpictureChromakey;
2162     pVTable->vaSetSubpictureGlobalAlpha      = DdiMedia_SetSubpictureGlobalAlpha;
2163     pVTable->vaAssociateSubpicture           = DdiMedia_AssociateSubpicture;
2164     pVTable->vaDeassociateSubpicture         = DdiMedia_DeassociateSubpicture;
2165     pVTable->vaQueryDisplayAttributes        = DdiMedia_QueryDisplayAttributes;
2166     pVTable->vaGetDisplayAttributes          = DdiMedia_GetDisplayAttributes;
2167     pVTable->vaSetDisplayAttributes          = DdiMedia_SetDisplayAttributes;
2168     pVTable->vaQueryProcessingRate           = DdiMedia_QueryProcessingRate;
2169 #if VA_CHECK_VERSION(1,10,0)
2170     pVTable->vaCopy                          = DdiMedia_Copy;
2171 #endif
2172 
2173     // vaTrace
2174     pVTable->vaBufferInfo                    = DdiMedia_BufferInfo;
2175     pVTable->vaLockSurface                   = DdiMedia_LockSurface;
2176     pVTable->vaUnlockSurface                 = DdiMedia_UnlockSurface;
2177 
2178     pVTableVpp->vaQueryVideoProcFilters      = DdiMedia_QueryVideoProcFilters;
2179     pVTableVpp->vaQueryVideoProcFilterCaps   = DdiMedia_QueryVideoProcFilterCaps;
2180     pVTableVpp->vaQueryVideoProcPipelineCaps = DdiMedia_QueryVideoProcPipelineCaps;
2181 
2182 #if VA_CHECK_VERSION(1,11,0)
2183     pVTableProt->vaCreateProtectedSession    = DdiMediaProtected::DdiMedia_CreateProtectedSession;
2184     pVTableProt->vaDestroyProtectedSession   = DdiMediaProtected::DdiMedia_DestroyProtectedSession;
2185     pVTableProt->vaAttachProtectedSession    = DdiMediaProtected::DdiMedia_AttachProtectedSession;
2186     pVTableProt->vaDetachProtectedSession    = DdiMediaProtected::DdiMedia_DetachProtectedSession;
2187     pVTableProt->vaProtectedSessionExecute   = DdiMediaProtected::DdiMedia_ProtectedSessionExecute;
2188 #endif
2189 
2190     //pVTable->vaSetSurfaceAttributes          = DdiMedia_SetSurfaceAttributes;
2191     pVTable->vaGetSurfaceAttributes          = DdiMedia_GetSurfaceAttributes;
2192     //Export PRIMEFD/FLINK to application for buffer sharing with OpenCL/GL
2193     pVTable->vaAcquireBufferHandle           = DdiMedia_AcquireBufferHandle;
2194     pVTable->vaReleaseBufferHandle           = DdiMedia_ReleaseBufferHandle;
2195     pVTable->vaExportSurfaceHandle           = DdiMedia_ExportSurfaceHandle;
2196 #ifndef ANDROID
2197     pVTable->vaCreateMFContext               = DdiMedia_CreateMfeContextInternal;
2198     pVTable->vaMFAddContext                  = DdiMedia_AddContextInternal;
2199     pVTable->vaMFReleaseContext              = DdiMedia_ReleaseContextInternal;
2200     pVTable->vaMFSubmit                      = DdiEncode_MfeSubmit;
2201 #endif
2202     return VA_STATUS_SUCCESS;
2203 }
2204 
DdiMedia_CleanUp(PDDI_MEDIA_CONTEXT mediaCtx)2205 VAStatus DdiMedia_CleanUp (PDDI_MEDIA_CONTEXT mediaCtx)
2206 {
2207     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
2208 
2209     if (mediaCtx->m_caps)
2210     {
2211         MOS_Delete(mediaCtx->m_caps);
2212         mediaCtx->m_caps = nullptr;
2213     }
2214 
2215 #ifdef _MANUAL_SOFTLET_
2216     DdiMedia_CleanUpSoftlet(mediaCtx);
2217 #endif
2218     return VA_STATUS_SUCCESS;
2219 }
2220 
DdiMedia_Terminate(VADriverContextP ctx)2221 VAStatus DdiMedia_Terminate (
2222     VADriverContextP ctx
2223 )
2224 {
2225     DDI_FUNCTION_ENTER();
2226     MOS_CONTEXT mosCtx = {};
2227 
2228 #if CLASS_TRACE
2229     ClassTrace::Dump("#In DdiMedia_Terminate", "temp/class_trace.log");
2230 #endif
2231     DDI_CHK_NULL(ctx,       "nullptr ctx",       VA_STATUS_ERROR_INVALID_CONTEXT);
2232 
2233     PDDI_MEDIA_CONTEXT mediaCtx   = DdiMedia_GetMediaContext(ctx);
2234     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
2235 
2236     DdiMediaUtil_LockMutex(&GlobalMutex);
2237 
2238 #if !defined(ANDROID) && defined(X11_FOUND)
2239     DdiMedia_DestroyX11Connection(mediaCtx);
2240     DdiMediaUtil_DestroyMutex(&mediaCtx->PutSurfaceRenderMutex);
2241     DdiMediaUtil_DestroyMutex(&mediaCtx->PutSurfaceSwapBufferMutex);
2242 
2243     if (mediaCtx->m_caps
2244 #ifdef _MANUAL_SOFTLET_
2245     || mediaCtx->m_capsNext
2246 #endif
2247     )
2248     {
2249         if (mediaCtx->dri_output != nullptr) {
2250             if (mediaCtx->dri_output->handle)
2251                 dso_close(mediaCtx->dri_output->handle);
2252 
2253             free(mediaCtx->dri_output);
2254             mediaCtx->dri_output = nullptr;
2255         }
2256     }
2257 #endif
2258 
2259     DdiMedia_CleanUp(mediaCtx);
2260 
2261     //destory resources
2262     DdiMedia_FreeSurfaceHeapElements(mediaCtx);
2263     DdiMedia_FreeBufferHeapElements(ctx);
2264     DdiMedia_FreeImageHeapElements(ctx);
2265     DdiMedia_FreeContextHeapElements(ctx);
2266     DdiMedia_FreeContextCMElements(ctx);
2267 
2268     DdiMedia_HeapDestroy(mediaCtx);
2269     DdiMediaProtected::FreeInstances();
2270 
2271     mosCtx.fd               = mediaCtx->fd;
2272     mosCtx.m_userSettingPtr = mediaCtx->m_userSettingPtr;
2273 
2274     if (mediaCtx->m_apoMosEnabled)
2275     {
2276         MosInterface::DestroyOsDeviceContext(mediaCtx->m_osDeviceContext);
2277         mediaCtx->m_osDeviceContext = MOS_INVALID_HANDLE;
2278         MOS_FreeMemory(mediaCtx->pGtSystemInfo);
2279         MosOcaInterfaceSpecific::UninitInterface();
2280         MosInterface::CloseOsUtilities(&mosCtx);
2281     }
2282     else if (mediaCtx->modularizedGpuCtxEnabled)
2283     {
2284         if (mediaCtx->m_auxTableMgr != nullptr)
2285         {
2286             MOS_Delete(mediaCtx->m_auxTableMgr);
2287             mediaCtx->m_auxTableMgr = nullptr;
2288         }
2289 
2290         if (mediaCtx->m_gpuContextMgr)
2291         {
2292             mediaCtx->m_gpuContextMgr->CleanUp();
2293             MOS_Delete(mediaCtx->m_gpuContextMgr);
2294         }
2295 
2296         if (mediaCtx->m_cmdBufMgr)
2297         {
2298             mediaCtx->m_cmdBufMgr->CleanUp();
2299             MOS_Delete(mediaCtx->m_cmdBufMgr);
2300         }
2301 
2302         if (mediaCtx->m_osContext)
2303         {
2304             mediaCtx->m_osContext->CleanUp();
2305             MOS_Delete(mediaCtx->m_osContext);
2306         }
2307 
2308         // destroy libdrm buffer manager
2309         mos_bufmgr_destroy(mediaCtx->pDrmBufMgr);
2310 
2311         // Destroy memory allocated to store Media System Info
2312         MOS_FreeMemory(mediaCtx->pGtSystemInfo);
2313         // Free GMM memory.
2314         GMM_INIT_OUT_ARGS gmmOutArgs = {};
2315         gmmOutArgs.pGmmClientContext = mediaCtx->pGmmClientContext;
2316         GmmAdapterDestroy(&gmmOutArgs);
2317         mediaCtx->pGmmClientContext = nullptr;
2318         MosUtilities::MosUtilitiesClose(mediaCtx->m_userSettingPtr);
2319     }
2320 
2321     mediaCtx->m_userSettingPtr.reset();
2322 
2323     if (mediaCtx->uiRef > 1)
2324     {
2325         mediaCtx->uiRef--;
2326         DdiMediaUtil_UnLockMutex(&GlobalMutex);
2327 
2328         return VA_STATUS_SUCCESS;
2329     }
2330     mediaCtx->SkuTable.reset();
2331     mediaCtx->WaTable.reset();
2332 
2333     // release media driver context, ctx creation is behind the mos_utilities_init
2334     // If free earilier than MOS_utilities_close, memnja count error.
2335     MOS_Delete(mediaCtx);
2336     mediaCtx         = nullptr;
2337     ctx->pDriverData = nullptr;
2338 
2339     DdiMediaUtil_UnLockMutex(&GlobalMutex);
2340 
2341     return VA_STATUS_SUCCESS;
2342 }
2343 
DdiMedia_QueryConfigEntrypoints(VADriverContextP ctx,VAProfile profile,VAEntrypoint * entrypoint_list,int32_t * num_entrypoints)2344 VAStatus DdiMedia_QueryConfigEntrypoints(
2345     VADriverContextP    ctx,
2346     VAProfile           profile,
2347     VAEntrypoint       *entrypoint_list,
2348     int32_t            *num_entrypoints
2349 )
2350 {
2351     DDI_FUNCTION_ENTER();
2352 
2353     PERF_UTILITY_START_ONCE("First Frame Time", PERF_MOS, PERF_LEVEL_DDI);
2354 
2355     DDI_CHK_NULL(ctx, "nullptr Ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
2356     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
2357     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
2358     DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
2359 
2360     DDI_CHK_NULL(entrypoint_list, "nullptr entrypoint_list", VA_STATUS_ERROR_INVALID_PARAMETER);
2361     DDI_CHK_NULL(num_entrypoints, "nullptr num_entrypoints", VA_STATUS_ERROR_INVALID_PARAMETER);
2362 
2363     return mediaCtx->m_caps->QueryConfigEntrypoints(profile,
2364             entrypoint_list, num_entrypoints);
2365 }
2366 
DdiMedia_QueryConfigProfiles(VADriverContextP ctx,VAProfile * profile_list,int32_t * num_profiles)2367 VAStatus DdiMedia_QueryConfigProfiles (
2368     VADriverContextP    ctx,
2369     VAProfile          *profile_list,
2370     int32_t            *num_profiles
2371 )
2372 {
2373     DDI_FUNCTION_ENTER();
2374 
2375     DDI_CHK_NULL(ctx, "nullptr Ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
2376     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
2377 
2378     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
2379     DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
2380     DDI_CHK_NULL(profile_list, "nullptr profile_list", VA_STATUS_ERROR_INVALID_PARAMETER);
2381     DDI_CHK_NULL(num_profiles, "nullptr num_profiles", VA_STATUS_ERROR_INVALID_PARAMETER);
2382 
2383     return mediaCtx->m_caps->QueryConfigProfiles(profile_list, num_profiles);
2384 }
2385 
DdiMedia_QueryConfigAttributes(VADriverContextP ctx,VAConfigID config_id,VAProfile * profile,VAEntrypoint * entrypoint,VAConfigAttrib * attrib_list,int32_t * num_attribs)2386 VAStatus DdiMedia_QueryConfigAttributes (
2387     VADriverContextP    ctx,
2388     VAConfigID          config_id,
2389     VAProfile          *profile,
2390     VAEntrypoint       *entrypoint,
2391     VAConfigAttrib     *attrib_list,
2392     int32_t            *num_attribs
2393 )
2394 {
2395     DDI_FUNCTION_ENTER();
2396 
2397     DDI_CHK_NULL(profile,     "nullptr profile", VA_STATUS_ERROR_INVALID_PARAMETER);
2398     DDI_CHK_NULL(entrypoint,  "nullptr entrypoint", VA_STATUS_ERROR_INVALID_PARAMETER);
2399     DDI_CHK_NULL(ctx,         "nullptr Ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
2400     DDI_CHK_NULL(num_attribs, "nullptr num_attribs", VA_STATUS_ERROR_INVALID_PARAMETER);
2401 
2402     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
2403     DDI_CHK_NULL(mediaCtx,   "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
2404     DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
2405 
2406     return mediaCtx->m_caps->QueryConfigAttributes(
2407                 config_id, profile, entrypoint, attrib_list, num_attribs);
2408 }
2409 
DdiMedia_CreateConfig(VADriverContextP ctx,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int32_t num_attribs,VAConfigID * config_id)2410 VAStatus DdiMedia_CreateConfig (
2411     VADriverContextP    ctx,
2412     VAProfile           profile,
2413     VAEntrypoint        entrypoint,
2414     VAConfigAttrib     *attrib_list,
2415     int32_t             num_attribs,
2416     VAConfigID         *config_id
2417 )
2418 {
2419     DDI_FUNCTION_ENTER();
2420 
2421     DDI_CHK_NULL(ctx,       "nullptr ctx",       VA_STATUS_ERROR_INVALID_CONTEXT);
2422     DDI_CHK_NULL(config_id, "nullptr config_id", VA_STATUS_ERROR_INVALID_PARAMETER);
2423 
2424     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
2425     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
2426     DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
2427 
2428     return mediaCtx->m_caps->CreateConfig(
2429             profile, entrypoint, attrib_list, num_attribs, config_id);
2430 }
2431 
DdiMedia_DestroyConfig(VADriverContextP ctx,VAConfigID config_id)2432 VAStatus DdiMedia_DestroyConfig (
2433     VADriverContextP    ctx,
2434     VAConfigID          config_id
2435 )
2436 {
2437     DDI_FUNCTION_ENTER();
2438 
2439     DDI_CHK_NULL(ctx,       "nullptr ctx",       VA_STATUS_ERROR_INVALID_CONTEXT);
2440 
2441     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
2442     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
2443     DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
2444 
2445     return mediaCtx->m_caps->DestroyConfig(config_id);
2446 }
2447 
DdiMedia_GetConfigAttributes(VADriverContextP ctx,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int32_t num_attribs)2448 VAStatus DdiMedia_GetConfigAttributes(
2449     VADriverContextP    ctx,
2450     VAProfile           profile,
2451     VAEntrypoint        entrypoint,
2452     VAConfigAttrib     *attrib_list,
2453     int32_t             num_attribs
2454 )
2455 {
2456     DDI_FUNCTION_ENTER();
2457 
2458     DDI_CHK_NULL(ctx,       "nullptr ctx",       VA_STATUS_ERROR_INVALID_CONTEXT);
2459 
2460     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
2461     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
2462     DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
2463 
2464     return mediaCtx->m_caps->GetConfigAttributes(
2465             profile, entrypoint, attrib_list, num_attribs);
2466 }
2467 
DdiMedia_CreateSurfaces(VADriverContextP ctx,int32_t width,int32_t height,int32_t format,int32_t num_surfaces,VASurfaceID * surfaces)2468 VAStatus DdiMedia_CreateSurfaces (
2469     VADriverContextP    ctx,
2470     int32_t             width,
2471     int32_t             height,
2472     int32_t             format,
2473     int32_t             num_surfaces,
2474     VASurfaceID        *surfaces
2475 )
2476 {
2477     DDI_FUNCTION_ENTER();
2478     return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
2479 }
2480 
DdiMedia_DestroySurfaces(VADriverContextP ctx,VASurfaceID * surfaces,int32_t num_surfaces)2481 VAStatus DdiMedia_DestroySurfaces (
2482     VADriverContextP    ctx,
2483     VASurfaceID        *surfaces,
2484     int32_t             num_surfaces
2485 )
2486 {
2487     DDI_FUNCTION_ENTER();
2488 
2489     DDI_CHK_NULL  (ctx,             "nullptr ctx",             VA_STATUS_ERROR_INVALID_CONTEXT);
2490     DDI_CHK_LARGER(num_surfaces, 0, "Invalid num_surfaces", VA_STATUS_ERROR_INVALID_PARAMETER);
2491     DDI_CHK_NULL  (surfaces,        "nullptr surfaces",        VA_STATUS_ERROR_INVALID_PARAMETER);
2492     MOS_TraceEventExt(EVENT_VA_FREE_SURFACE, EVENT_TYPE_START, &num_surfaces, sizeof(int32_t), surfaces, num_surfaces*sizeof(VAGenericID));
2493 
2494     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
2495     DDI_CHK_NULL  (mediaCtx,                  "nullptr mediaCtx",               VA_STATUS_ERROR_INVALID_CONTEXT);
2496     DDI_CHK_NULL  (mediaCtx->pSurfaceHeap,    "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
2497 
2498     PDDI_MEDIA_SURFACE surface = nullptr;
2499     for(int32_t i = 0; i < num_surfaces; i++)
2500     {
2501         DDI_CHK_LESS((uint32_t)surfaces[i], mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surfaces", VA_STATUS_ERROR_INVALID_SURFACE);
2502         surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surfaces[i]);
2503         DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
2504         if(surface->pCurrentFrameSemaphore)
2505         {
2506             DdiMediaUtil_WaitSemaphore(surface->pCurrentFrameSemaphore);
2507             DdiMediaUtil_PostSemaphore(surface->pCurrentFrameSemaphore);
2508         }
2509         if(surface->pReferenceFrameSemaphore)
2510         {
2511             DdiMediaUtil_WaitSemaphore(surface->pReferenceFrameSemaphore);
2512             DdiMediaUtil_PostSemaphore(surface->pReferenceFrameSemaphore);
2513         }
2514     }
2515 
2516     for(int32_t i = 0; i < num_surfaces; i++)
2517     {
2518         DDI_CHK_LESS((uint32_t)surfaces[i], mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surfaces", VA_STATUS_ERROR_INVALID_SURFACE);
2519         surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surfaces[i]);
2520         DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
2521         if(surface->pCurrentFrameSemaphore)
2522         {
2523             DdiMediaUtil_DestroySemaphore(surface->pCurrentFrameSemaphore);
2524             surface->pCurrentFrameSemaphore = nullptr;
2525         }
2526 
2527         if(surface->pReferenceFrameSemaphore)
2528         {
2529             DdiMediaUtil_DestroySemaphore(surface->pReferenceFrameSemaphore);
2530             surface->pReferenceFrameSemaphore = nullptr;
2531         }
2532 
2533         DdiMediaUtil_UnRegisterRTSurfaces(ctx, surface);
2534 
2535         if (surface->pMediaCtx && surface->pMediaCtx->m_auxTableMgr)
2536         {
2537             uint64_t freq = 1, countStart = 0, countCur = 0;
2538             MosUtilities::MosQueryPerformanceFrequency(&freq);
2539             uint64_t countTimeout = freq * BO_BUSY_TIMEOUT_LIMIT / 1000;
2540             MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
2541             MosUtilities::MosQueryPerformanceCounter(&countStart);
2542             while (1)
2543             {
2544                 uint32_t timeout_NS = 10;
2545                 int ret = mos_bo_wait(surface->bo, timeout_NS);
2546                 MosUtilities::MosQueryPerformanceCounter(&countCur);
2547                 if(ret == 0 || countCur - countStart > countTimeout)
2548                 {
2549                     break;
2550                 }
2551             }
2552             MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
2553         }
2554 
2555         DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
2556         DdiMediaUtil_FreeSurface(surface);
2557         MOS_FreeMemory(surface);
2558         DdiMediaUtil_ReleasePMediaSurfaceFromHeap(mediaCtx->pSurfaceHeap, (uint32_t)surfaces[i]);
2559         mediaCtx->uiNumSurfaces--;
2560         DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
2561     }
2562 
2563     MOS_TraceEventExt(EVENT_VA_FREE_SURFACE, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
2564     return VA_STATUS_SUCCESS;
2565 }
2566 
DdiMedia_CreateSurfaces2(VADriverContextP ctx,uint32_t format,uint32_t width,uint32_t height,VASurfaceID * surfaces,uint32_t num_surfaces,VASurfaceAttrib * attrib_list,uint32_t num_attribs)2567 VAStatus DdiMedia_CreateSurfaces2(
2568     VADriverContextP    ctx,
2569     uint32_t            format,
2570     uint32_t            width,
2571     uint32_t            height,
2572     VASurfaceID        *surfaces,
2573     uint32_t            num_surfaces,
2574     VASurfaceAttrib    *attrib_list,
2575     uint32_t            num_attribs
2576     )
2577 {
2578     DDI_FUNCTION_ENTER();
2579     uint32_t event[] = {width, height, format};
2580     MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_START, event, sizeof(event), nullptr, 0);
2581 
2582     DDI_CHK_NULL  (ctx,             "nullptr ctx",             VA_STATUS_ERROR_INVALID_CONTEXT);
2583     DDI_CHK_LARGER(num_surfaces, 0, "Invalid num_surfaces", VA_STATUS_ERROR_INVALID_PARAMETER);
2584     DDI_CHK_NULL  (surfaces,        "nullptr surfaces",        VA_STATUS_ERROR_INVALID_PARAMETER);
2585     DDI_CHK_LARGER(width,        0, "Invalid width",        VA_STATUS_ERROR_INVALID_PARAMETER);
2586     DDI_CHK_LARGER(height,       0, "Invalid height",       VA_STATUS_ERROR_INVALID_PARAMETER);
2587 
2588     if(num_attribs > 0)
2589     {
2590         DDI_CHK_NULL(attrib_list, "nullptr attrib_list", VA_STATUS_ERROR_INVALID_PARAMETER);
2591     }
2592 
2593     PDDI_MEDIA_CONTEXT mediaCtx    = DdiMedia_GetMediaContext(ctx);
2594     DDI_CHK_NULL(mediaCtx,       "nullptr mediaCtx",   VA_STATUS_ERROR_INVALID_CONTEXT);
2595 
2596     int32_t expected_fourcc = VA_FOURCC_NV12;
2597     switch(format)
2598     {
2599         case VA_RT_FORMAT_YUV420:
2600             expected_fourcc = VA_FOURCC_NV12;
2601             break;
2602         case VA_RT_FORMAT_YUV420_12:
2603             expected_fourcc = VA_FOURCC_P012;
2604             break;
2605         case VA_RT_FORMAT_YUV422:
2606             expected_fourcc = VA_FOURCC_YUY2;
2607             break;
2608         case VA_RT_FORMAT_YUV422_10:
2609             expected_fourcc = VA_FOURCC_Y210;
2610             break;
2611         case VA_RT_FORMAT_YUV422_12:
2612 #if VA_CHECK_VERSION(1, 9, 0)
2613             expected_fourcc = VA_FOURCC_Y212;
2614 #else
2615             expected_fourcc = VA_FOURCC_Y216;
2616 #endif
2617             break;
2618         case VA_RT_FORMAT_YUV444:
2619             expected_fourcc = VA_FOURCC_444P;
2620             break;
2621         case VA_RT_FORMAT_YUV444_10:
2622             expected_fourcc = VA_FOURCC_Y410;
2623             break;
2624         case VA_RT_FORMAT_YUV444_12:
2625 #if VA_CHECK_VERSION(1, 9, 0)
2626             expected_fourcc = VA_FOURCC_Y412;
2627 #else
2628             expected_fourcc = VA_FOURCC_Y416;
2629 #endif
2630             break;
2631         case VA_RT_FORMAT_YUV411:
2632             expected_fourcc = VA_FOURCC_411P;
2633             break;
2634         case VA_RT_FORMAT_YUV400:
2635             expected_fourcc = VA_FOURCC('4','0','0','P');
2636             break;
2637         case VA_RT_FORMAT_YUV420_10BPP:
2638             expected_fourcc = VA_FOURCC_P010;
2639             break;
2640         case VA_RT_FORMAT_RGB16:
2641             expected_fourcc = VA_FOURCC_R5G6B5;
2642             break;
2643         case VA_RT_FORMAT_RGB32:
2644             expected_fourcc = VA_FOURCC_BGRA;
2645             break;
2646         case VA_RT_FORMAT_RGBP:
2647             expected_fourcc = VA_FOURCC_RGBP;
2648             break;
2649 #ifdef VA_RT_FORMAT_RGB32_10BPP
2650         case VA_RT_FORMAT_RGB32_10BPP:
2651             expected_fourcc = VA_FOURCC_BGRA;
2652             break;
2653 #endif
2654 #if 1 //added for having MDF sanity test pass, will be removed after MDF formal patch checked in
2655         case VA_FOURCC_NV12:
2656             expected_fourcc = VA_FOURCC_NV12;
2657             break;
2658         case VA_FOURCC_NV21:
2659             expected_fourcc = VA_FOURCC_NV21;
2660             break;
2661         case VA_FOURCC_ABGR:
2662             expected_fourcc = VA_FOURCC_ABGR;
2663             break;
2664         case VA_FOURCC_ARGB:
2665             expected_fourcc = VA_FOURCC_ARGB;
2666             break;
2667         case VA_FOURCC_XBGR:
2668             expected_fourcc = VA_FOURCC_XBGR;
2669             break;
2670         case VA_FOURCC_XRGB:
2671             expected_fourcc = VA_FOURCC_XRGB;
2672             break;
2673         case VA_FOURCC_R5G6B5:
2674             expected_fourcc = VA_FOURCC_R5G6B5;
2675             break;
2676         case VA_FOURCC_R8G8B8:
2677             expected_fourcc = VA_FOURCC_R8G8B8;
2678             break;
2679         case VA_FOURCC_YUY2:
2680             expected_fourcc = VA_FOURCC_YUY2;
2681             break;
2682         case VA_FOURCC_YV12:
2683             expected_fourcc = VA_FOURCC_YV12;
2684             break;
2685         case VA_FOURCC_422H:
2686             expected_fourcc = VA_FOURCC_422H;
2687             break;
2688         case VA_FOURCC_422V:
2689             expected_fourcc = VA_FOURCC_422V;
2690             break;
2691         case VA_FOURCC_P208:
2692             expected_fourcc = VA_FOURCC_P208;
2693             break;
2694         case VA_FOURCC_P010:
2695             expected_fourcc = VA_FOURCC_P010;
2696             break;
2697         case VA_FOURCC_P012:
2698             expected_fourcc = VA_FOURCC_P012;
2699             break;
2700         case VA_FOURCC_P016:
2701             expected_fourcc = VA_FOURCC_P016;
2702             break;
2703         case VA_FOURCC_Y210:
2704             expected_fourcc = VA_FOURCC_Y210;
2705             break;
2706 #if VA_CHECK_VERSION(1, 9, 0)
2707         case VA_FOURCC_Y212:
2708             expected_fourcc = VA_FOURCC_Y212;
2709             break;
2710 #endif
2711         case VA_FOURCC_Y216:
2712             expected_fourcc = VA_FOURCC_Y216;
2713             break;
2714         case VA_FOURCC_AYUV:
2715             expected_fourcc = VA_FOURCC_AYUV;
2716             break;
2717 #if VA_CHECK_VERSION(1, 13, 0)
2718         case VA_FOURCC_XYUV:
2719             expected_fourcc = VA_FOURCC_XYUV;
2720             break;
2721 #endif
2722         case VA_FOURCC_Y410:
2723             expected_fourcc = VA_FOURCC_Y410;
2724             break;
2725 #if VA_CHECK_VERSION(1, 9, 0)
2726         case VA_FOURCC_Y412:
2727             expected_fourcc = VA_FOURCC_Y412;
2728             break;
2729 #endif
2730         case VA_FOURCC_Y416:
2731             expected_fourcc = VA_FOURCC_Y416;
2732             break;
2733         case VA_FOURCC_I420:
2734             expected_fourcc = VA_FOURCC_I420;
2735             break;
2736         case VA_FOURCC_UYVY:
2737             expected_fourcc = VA_FOURCC_UYVY;
2738             break;
2739 #endif
2740         default:
2741             DDI_ASSERTMESSAGE("Invalid VAConfigAttribRTFormat: 0x%x. Please uses the format defined in libva/va.h", format);
2742             return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
2743     }
2744 
2745     VASurfaceAttribExternalBuffers externalBufDescripor;
2746     VADRMPRIMESurfaceDescriptor drmPrimeSurfaceDescriptor;
2747     MOS_ZeroMemory(&externalBufDescripor, sizeof(VASurfaceAttribExternalBuffers));
2748     MOS_ZeroMemory(&drmPrimeSurfaceDescriptor, sizeof(VADRMPRIMESurfaceDescriptor));
2749 #if VA_CHECK_VERSION(1, 21, 0)
2750     VADRMPRIME3SurfaceDescriptor drmPrime3SurfaceDescriptor;
2751     MOS_ZeroMemory(&drmPrime3SurfaceDescriptor, sizeof(VADRMPRIME3SurfaceDescriptor));
2752 #endif
2753 
2754     int32_t  memTypeFlag      = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
2755     int32_t  descFlag         = 0;
2756     uint32_t surfaceUsageHint = VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC;
2757     bool     surfDescProvided = false;
2758     bool     surfIsUserPtr    = false;
2759 
2760     for (uint32_t i = 0; i < num_attribs && attrib_list; i++)
2761     {
2762         if (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)
2763         {
2764             switch (attrib_list[i].type)
2765             {
2766             case VASurfaceAttribUsageHint:
2767                 DDI_ASSERT(attrib_list[i].value.type == VAGenericValueTypeInteger);
2768                 surfaceUsageHint = attrib_list[i].value.value.i;
2769                 break;
2770             case VASurfaceAttribPixelFormat:
2771                 DDI_ASSERT(attrib_list[i].value.type == VAGenericValueTypeInteger);
2772                 expected_fourcc = attrib_list[i].value.value.i;
2773                 break;
2774             case VASurfaceAttribMemoryType:
2775                 DDI_ASSERT(attrib_list[i].value.type == VAGenericValueTypeInteger);
2776                 if ((attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_VA)          ||
2777                     (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)  ||
2778                     (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)   ||
2779                     (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) ||
2780 #if VA_CHECK_VERSION(1, 21, 0)
2781                     (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3) ||
2782 #endif
2783                     (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR))
2784                 {
2785                     memTypeFlag = attrib_list[i].value.value.i;
2786                     surfIsUserPtr = (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR);
2787                 }
2788                 else
2789                 {
2790                     DDI_ASSERTMESSAGE("Not supported external buffer type.");
2791                     return VA_STATUS_ERROR_INVALID_PARAMETER;
2792                 }
2793                 break;
2794             case (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor:
2795                 DDI_ASSERT(attrib_list[i].value.type == VAGenericValueTypePointer);
2796                 if( nullptr == attrib_list[i].value.value.p )
2797                 {
2798                     DDI_ASSERTMESSAGE("Invalid VASurfaceAttribExternalBuffers used.");
2799                     //remove the check for libva-utils conformance test, need libva-utils change cases
2800                     //after libva-utils fix the case, return VA_STATUS_ERROR_INVALID_PARAMETER;
2801                     break;
2802                 }
2803                 surfDescProvided = true;
2804                 if (memTypeFlag == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
2805                 {
2806                     MOS_SecureMemcpy(&drmPrimeSurfaceDescriptor, sizeof(VADRMPRIMESurfaceDescriptor),  attrib_list[i].value.value.p, sizeof(VADRMPRIMESurfaceDescriptor));
2807                     expected_fourcc  = drmPrimeSurfaceDescriptor.fourcc;
2808                     width            = drmPrimeSurfaceDescriptor.width;
2809                     height           = drmPrimeSurfaceDescriptor.height;
2810                 }
2811 #if VA_CHECK_VERSION(1, 21, 0)
2812                 else if (memTypeFlag == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3 )
2813                 {
2814                     MosUtilities::MosSecureMemcpy(&drmPrime3SurfaceDescriptor, sizeof(VADRMPRIME3SurfaceDescriptor), attrib_list[i].value.value.p, sizeof(VADRMPRIME3SurfaceDescriptor));
2815                     expected_fourcc           = drmPrime3SurfaceDescriptor.fourcc;
2816                     width                     = drmPrime3SurfaceDescriptor.width;
2817                     height                    = drmPrime3SurfaceDescriptor.height;
2818                     drmPrimeSurfaceDescriptor = *((VADRMPRIMESurfaceDescriptor *)&drmPrime3SurfaceDescriptor);
2819                     descFlag                  = drmPrime3SurfaceDescriptor.flags;
2820                 }
2821 #endif
2822                 else
2823                 {
2824                     MOS_SecureMemcpy(&externalBufDescripor, sizeof(VASurfaceAttribExternalBuffers),  attrib_list[i].value.value.p, sizeof(VASurfaceAttribExternalBuffers));
2825 
2826                     expected_fourcc  = externalBufDescripor.pixel_format;
2827                     width            = externalBufDescripor.width;
2828                     height           = externalBufDescripor.height;
2829                     // the following code is for backward compatible and it will be removed in the future
2830                     // new implemention should use VASurfaceAttribMemoryType attrib and set its value to VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM
2831                     if ((externalBufDescripor.flags & VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM )||
2832                         (externalBufDescripor.flags & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)||
2833                         (externalBufDescripor.flags & VA_SURFACE_EXTBUF_DESC_PROTECTED)||
2834                         (externalBufDescripor.flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING))
2835                     {
2836                         if (externalBufDescripor.flags & VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
2837                         {
2838                             memTypeFlag = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
2839                         }
2840                         else if (externalBufDescripor.flags & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)
2841                         {
2842                             memTypeFlag = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
2843                         }
2844 
2845                         descFlag      = (externalBufDescripor.flags & ~(VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM | VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME));
2846                         surfIsUserPtr = false;
2847                     }
2848                 }
2849 
2850                 break;
2851             default:
2852                 DDI_ASSERTMESSAGE("Unsupported type.");
2853                 break;
2854             }
2855         }
2856     }
2857 
2858     DDI_MEDIA_FORMAT mediaFmt = DdiMedia_OsFormatToMediaFormat(expected_fourcc,format);
2859     if (mediaFmt == Media_Format_Count)
2860     {
2861         DDI_ASSERTMESSAGE("DDI: unsupported surface type in DdiMedia_CreateSurfaces2.");
2862         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
2863     }
2864 
2865     for (uint32_t i = 0; i < num_surfaces; i++)
2866     {
2867         PDDI_MEDIA_SURFACE_DESCRIPTOR surfDesc = nullptr;
2868         MOS_STATUS                    eStatus = MOS_STATUS_SUCCESS;
2869 
2870         if (surfDescProvided == true)
2871         {
2872             surfDesc = (PDDI_MEDIA_SURFACE_DESCRIPTOR)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_SURFACE_DESCRIPTOR));
2873             if (surfDesc == nullptr)
2874             {
2875                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2876             }
2877             surfDesc->uiFlags        = descFlag;
2878             surfDesc->uiVaMemType    = memTypeFlag;
2879 
2880             if (
2881 #if VA_CHECK_VERSION(1, 21, 0)
2882                 memTypeFlag == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3 ||
2883 #endif
2884                 memTypeFlag == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
2885             {
2886                 surfDesc->ulBuffer       = drmPrimeSurfaceDescriptor.objects[0].fd;
2887                 surfDesc->modifier       = drmPrimeSurfaceDescriptor.objects[0].drm_format_modifier;
2888                 surfDesc->uiSize         = drmPrimeSurfaceDescriptor.objects[0].size;
2889                 surfDesc->uiBuffserSize  = drmPrimeSurfaceDescriptor.objects[0].size;
2890                 if(drmPrimeSurfaceDescriptor.num_layers > 1)
2891                 {
2892                      surfDesc->uiPlanes = drmPrimeSurfaceDescriptor.num_layers;
2893                      for (uint32_t k = 0; k < surfDesc->uiPlanes; k ++)
2894                      {
2895                          surfDesc->uiPitches[k] = drmPrimeSurfaceDescriptor.layers[k].pitch[0];
2896                          surfDesc->uiOffsets[k] = drmPrimeSurfaceDescriptor.layers[k].offset[0];
2897                      }
2898                 }
2899                 else
2900                 {
2901                     surfDesc->uiPlanes       = drmPrimeSurfaceDescriptor.layers[0].num_planes;
2902                     for(uint32_t k = 0; k < surfDesc->uiPlanes; k ++)
2903                     {
2904                         surfDesc->uiPitches[k] = drmPrimeSurfaceDescriptor.layers[0].pitch[k];
2905                         surfDesc->uiOffsets[k] = drmPrimeSurfaceDescriptor.layers[0].offset[k];
2906                     }
2907                 }
2908             }
2909             else if (memTypeFlag != VA_SURFACE_ATTRIB_MEM_TYPE_VA) {
2910                 surfDesc->uiPlanes       = externalBufDescripor.num_planes;
2911                 surfDesc->ulBuffer       = externalBufDescripor.buffers[i];
2912                 surfDesc->uiSize         = externalBufDescripor.data_size;
2913                 surfDesc->uiBuffserSize  = externalBufDescripor.data_size;
2914 
2915                 eStatus = MOS_SecureMemcpy(surfDesc->uiPitches, sizeof(surfDesc->uiPitches), externalBufDescripor.pitches, sizeof(externalBufDescripor.pitches));
2916                 if (eStatus != MOS_STATUS_SUCCESS)
2917                 {
2918                     DDI_VERBOSEMESSAGE("DDI:Failed to copy surface buffer data!");
2919                     MOS_FreeMemAndSetNull(surfDesc);
2920                     return VA_STATUS_ERROR_OPERATION_FAILED;
2921                 }
2922                 eStatus = MOS_SecureMemcpy(surfDesc->uiOffsets, sizeof(surfDesc->uiOffsets), externalBufDescripor.offsets, sizeof(externalBufDescripor.offsets));
2923                 if (eStatus != MOS_STATUS_SUCCESS)
2924                 {
2925                     DDI_VERBOSEMESSAGE("DDI:Failed to copy surface buffer data!");
2926                     MOS_FreeMemAndSetNull(surfDesc);
2927                     return VA_STATUS_ERROR_OPERATION_FAILED;
2928                 }
2929 
2930                 if( surfIsUserPtr )
2931                 {
2932                     surfDesc->uiTile = TILING_NONE;
2933                     if (surfDesc->ulBuffer % 4096 != 0)
2934                     {
2935                         MOS_FreeMemory(surfDesc);
2936                         DDI_VERBOSEMESSAGE("Buffer Address is invalid");
2937                         return VA_STATUS_ERROR_INVALID_PARAMETER;
2938                     }
2939                 }
2940             }
2941         }
2942         VASurfaceID vaSurfaceID = (VASurfaceID)DdiMedia_CreateRenderTarget(mediaCtx, mediaFmt, width, height, surfDesc, surfaceUsageHint, MOS_MEMPOOL_VIDEOMEMORY);
2943         if (VA_INVALID_ID != vaSurfaceID)
2944         {
2945             surfaces[i] = vaSurfaceID;
2946         }
2947         else
2948         {
2949             // here to release the successful allocated surfaces?
2950             if( nullptr != surfDesc )
2951             {
2952                 MOS_FreeMemory(surfDesc);
2953             }
2954             return VA_STATUS_ERROR_ALLOCATION_FAILED;
2955         }
2956     }
2957 
2958     MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_END, &num_surfaces, sizeof(uint32_t), surfaces, num_surfaces*sizeof(VAGenericID));
2959     return VA_STATUS_SUCCESS;
2960 }
2961 
DdiMedia_CreateMfeContextInternal(VADriverContextP ctx,VAMFContextID * mfe_context)2962 VAStatus DdiMedia_CreateMfeContextInternal(
2963     VADriverContextP    ctx,
2964     VAMFContextID      *mfe_context
2965 )
2966 {
2967     DDI_FUNCTION_ENTER();
2968 
2969     PDDI_MEDIA_CONTEXT mediaDrvCtx   = DdiMedia_GetMediaContext(ctx);
2970     DDI_CHK_NULL(mediaDrvCtx, "nullptr pMediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
2971 
2972     DDI_CHK_NULL(mfe_context, "nullptr mfe_context", VA_STATUS_ERROR_INVALID_PARAMETER);
2973     *mfe_context        = DDI_MEDIA_INVALID_VACONTEXTID;
2974 
2975     if (!mediaDrvCtx->m_caps->IsMfeSupportedOnPlatform(mediaDrvCtx->platform))
2976     {
2977         DDI_VERBOSEMESSAGE("MFE is not supported on the platform!");
2978         return VA_STATUS_ERROR_UNIMPLEMENTED;
2979     }
2980 
2981     PDDI_ENCODE_MFE_CONTEXT encodeMfeContext = (PDDI_ENCODE_MFE_CONTEXT)MOS_AllocAndZeroMemory(sizeof(DDI_ENCODE_MFE_CONTEXT));
2982     if (nullptr == encodeMfeContext)
2983     {
2984         MOS_FreeMemory(encodeMfeContext);
2985         return VA_STATUS_ERROR_ALLOCATION_FAILED;
2986     }
2987 
2988     DdiMediaUtil_LockMutex(&mediaDrvCtx->MfeMutex);
2989     PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaContextHeapElmt = DdiMediaUtil_AllocPVAContextFromHeap(mediaDrvCtx->pMfeCtxHeap);
2990     if (nullptr == vaContextHeapElmt)
2991     {
2992         DdiMediaUtil_UnLockMutex(&mediaDrvCtx->MfeMutex);
2993         MOS_FreeMemory(encodeMfeContext);
2994         return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2995     }
2996 
2997     vaContextHeapElmt->pVaContext    = (void*)encodeMfeContext;
2998     mediaDrvCtx->uiNumMfes++;
2999     *mfe_context                     = (VAMFContextID)(vaContextHeapElmt->uiVaContextID + DDI_MEDIA_VACONTEXTID_OFFSET_MFE);
3000     DdiMediaUtil_UnLockMutex(&mediaDrvCtx->MfeMutex);
3001 
3002     // Create shared state, which is used by all the sub contexts
3003     MfeSharedState *mfeEncodeSharedState   = (MfeSharedState*)MOS_AllocAndZeroMemory(sizeof(MfeSharedState));
3004     if (nullptr == mfeEncodeSharedState)
3005     {
3006         MOS_FreeMemory(encodeMfeContext);
3007         return VA_STATUS_ERROR_ALLOCATION_FAILED;
3008     }
3009 
3010     encodeMfeContext->mfeEncodeSharedState = mfeEncodeSharedState;
3011 
3012     DdiMediaUtil_InitMutex(&encodeMfeContext->encodeMfeMutex);
3013 
3014     return VA_STATUS_SUCCESS;
3015 }
3016 
DdiMedia_DestoryMfeContext(VADriverContextP ctx,VAMFContextID mfe_context)3017 static VAStatus DdiMedia_DestoryMfeContext (
3018     VADriverContextP    ctx,
3019     VAMFContextID      mfe_context
3020 )
3021 {
3022     DDI_FUNCTION_ENTER();
3023 
3024     PDDI_MEDIA_CONTEXT mediaCtx              = DdiMedia_GetMediaContext(ctx);
3025     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
3026 
3027     uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
3028     PDDI_ENCODE_MFE_CONTEXT encodeMfeContext = (PDDI_ENCODE_MFE_CONTEXT)DdiMedia_GetContextFromContextID(ctx, mfe_context, &ctxType);
3029     DDI_CHK_NULL(encodeMfeContext, "nullptr encodeMfeContext", VA_STATUS_ERROR_INVALID_CONTEXT);
3030 
3031     // Release std::vector memory
3032     encodeMfeContext->pDdiEncodeContexts.clear();
3033     encodeMfeContext->pDdiEncodeContexts.shrink_to_fit();
3034 
3035     encodeMfeContext->mfeEncodeSharedState->encoders.clear();
3036     encodeMfeContext->mfeEncodeSharedState->encoders.shrink_to_fit();
3037 
3038     DdiMediaUtil_DestroyMutex(&encodeMfeContext->encodeMfeMutex);
3039     MOS_FreeMemory(encodeMfeContext->mfeEncodeSharedState);
3040     MOS_FreeMemory(encodeMfeContext);
3041 
3042     DdiMediaUtil_LockMutex(&mediaCtx->MfeMutex);
3043     DdiMediaUtil_ReleasePVAContextFromHeap(mediaCtx->pMfeCtxHeap, (mfe_context & DDI_MEDIA_MASK_VACONTEXTID));
3044     mediaCtx->uiNumMfes--;
3045     DdiMediaUtil_UnLockMutex(&mediaCtx->MfeMutex);
3046     return VA_STATUS_SUCCESS;
3047 }
3048 
DdiMedia_AddContextInternal(VADriverContextP ctx,VAContextID context,VAMFContextID mfe_context)3049 VAStatus DdiMedia_AddContextInternal(
3050     VADriverContextP    ctx,
3051     VAContextID         context,
3052     VAMFContextID      mfe_context
3053 )
3054 {
3055     DDI_FUNCTION_ENTER();
3056 
3057     PDDI_MEDIA_CONTEXT      mediaCtx         = DdiMedia_GetMediaContext(ctx);
3058     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
3059 
3060     uint32_t                ctxType          = DDI_MEDIA_CONTEXT_TYPE_NONE;
3061     PDDI_ENCODE_MFE_CONTEXT encodeMfeContext = (PDDI_ENCODE_MFE_CONTEXT)DdiMedia_GetContextFromContextID(ctx, mfe_context, &ctxType);
3062     DDI_CHK_NULL(encodeMfeContext, "nullptr encodeMfeContext", VA_STATUS_ERROR_INVALID_CONTEXT);
3063 
3064     if (ctxType != DDI_MEDIA_CONTEXT_TYPE_MFE)
3065     {
3066         return VA_STATUS_ERROR_OPERATION_FAILED;
3067     }
3068 
3069     PDDI_ENCODE_CONTEXT     encodeContext    = DdiEncode_GetEncContextFromContextID(ctx, context);
3070     DDI_CHK_NULL(encodeContext, "nullptr encodeContext", VA_STATUS_ERROR_INVALID_CONTEXT);
3071 
3072     CodechalEncoderState    *encoder         = dynamic_cast<CodechalEncoderState *>(encodeContext->pCodecHal);
3073     DDI_CHK_NULL(encoder, "nullptr codechal encoder", VA_STATUS_ERROR_INVALID_CONTEXT);
3074 
3075     if (!mediaCtx->m_caps->IsMfeSupportedEntrypoint(encodeContext->vaEntrypoint))
3076     {
3077         return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
3078     }
3079 
3080     if (!mediaCtx->m_caps->IsMfeSupportedProfile(encodeContext->vaProfile))
3081     {
3082         return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
3083     }
3084 
3085     DdiMediaUtil_LockMutex(&encodeMfeContext->encodeMfeMutex);
3086     encodeMfeContext->pDdiEncodeContexts.push_back(encodeContext);
3087 
3088     if (encodeMfeContext->currentStreamId == 0)
3089     {
3090         encodeMfeContext->isFEI = (encodeContext->vaEntrypoint == VAEntrypointFEI) ? true : false;
3091     }
3092 
3093     //MFE cannot support legacy and FEI together
3094     if ((encodeContext->vaEntrypoint != VAEntrypointFEI && encodeMfeContext->isFEI) ||
3095         (encodeContext->vaEntrypoint == VAEntrypointFEI && !encodeMfeContext->isFEI))
3096     {
3097         DdiMediaUtil_UnLockMutex(&encodeMfeContext->encodeMfeMutex);
3098         return VA_STATUS_ERROR_INVALID_CONTEXT;
3099     }
3100 
3101     encoder->m_mfeEnabled = true;
3102     // Assign one unique id to this sub context/stream
3103     encoder->m_mfeEncodeParams.streamId = encodeMfeContext->currentStreamId;
3104 
3105     MOS_STATUS eStatus = encoder->SetMfeSharedState(encodeMfeContext->mfeEncodeSharedState);
3106     if (eStatus != MOS_STATUS_SUCCESS)
3107     {
3108         DDI_ASSERTMESSAGE(
3109             "Failed to set MFE Shared State for encoder #%d",
3110             encodeMfeContext->currentStreamId);
3111 
3112         encoder->m_mfeEnabled = false;
3113 
3114         DdiMediaUtil_UnLockMutex(&encodeMfeContext->encodeMfeMutex);
3115         return VA_STATUS_ERROR_OPERATION_FAILED;
3116     }
3117 
3118     encodeMfeContext->currentStreamId++;
3119     DdiMediaUtil_UnLockMutex(&encodeMfeContext->encodeMfeMutex);
3120     return VA_STATUS_SUCCESS;
3121 }
3122 
DdiMedia_ReleaseContextInternal(VADriverContextP ctx,VAContextID context,VAMFContextID mfe_context)3123 VAStatus DdiMedia_ReleaseContextInternal(
3124     VADriverContextP    ctx,
3125     VAContextID         context,
3126     VAMFContextID      mfe_context
3127 )
3128 {
3129     DDI_FUNCTION_ENTER();
3130 
3131     PDDI_MEDIA_CONTEXT mediaCtx   = DdiMedia_GetMediaContext(ctx);
3132     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
3133 
3134     uint32_t  ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
3135     PDDI_ENCODE_MFE_CONTEXT encodeMfeContext  = (PDDI_ENCODE_MFE_CONTEXT)DdiMedia_GetContextFromContextID(ctx, mfe_context, &ctxType);
3136     DDI_CHK_NULL(encodeMfeContext, "nullptr encodeMfeContext", VA_STATUS_ERROR_INVALID_CONTEXT);
3137 
3138     if (ctxType != DDI_MEDIA_CONTEXT_TYPE_MFE ||
3139         encodeMfeContext->pDdiEncodeContexts.size() == 0)
3140     {
3141         return VA_STATUS_ERROR_OPERATION_FAILED;
3142     }
3143 
3144     PDDI_ENCODE_CONTEXT encodeContext  = DdiEncode_GetEncContextFromContextID(ctx, context);
3145     DDI_CHK_NULL(encodeMfeContext, "nullptr encodeContext", VA_STATUS_ERROR_INVALID_CONTEXT);
3146 
3147     bool contextErased = false;
3148     DdiMediaUtil_LockMutex(&encodeMfeContext->encodeMfeMutex);
3149     for (uint32_t i = 0; i < encodeMfeContext->pDdiEncodeContexts.size(); i++)
3150     {
3151         if (encodeMfeContext->pDdiEncodeContexts[i] == encodeContext)
3152         {
3153             encodeMfeContext->pDdiEncodeContexts.erase(encodeMfeContext->pDdiEncodeContexts.begin() + i);
3154             contextErased = true;
3155             break;
3156         }
3157     }
3158 
3159     if (!contextErased)
3160     {
3161         DdiMediaUtil_UnLockMutex(&encodeMfeContext->encodeMfeMutex);
3162         return VA_STATUS_ERROR_OPERATION_FAILED;
3163     }
3164 
3165     DdiMediaUtil_UnLockMutex(&encodeMfeContext->encodeMfeMutex);
3166 
3167     return VA_STATUS_SUCCESS;
3168 }
3169 
DdiMedia_CreateContext(VADriverContextP ctx,VAConfigID config_id,int32_t picture_width,int32_t picture_height,int32_t flag,VASurfaceID * render_targets,int32_t num_render_targets,VAContextID * context)3170 VAStatus DdiMedia_CreateContext (
3171     VADriverContextP    ctx,
3172     VAConfigID          config_id,
3173     int32_t             picture_width,
3174     int32_t             picture_height,
3175     int32_t             flag,
3176     VASurfaceID        *render_targets,
3177     int32_t             num_render_targets,
3178     VAContextID        *context
3179 )
3180 {
3181     DDI_FUNCTION_ENTER();
3182 
3183     DDI_CHK_NULL(ctx,     "nullptr ctx",          VA_STATUS_ERROR_INVALID_CONTEXT);
3184     DDI_CHK_NULL(context, "nullptr context",      VA_STATUS_ERROR_INVALID_PARAMETER);
3185 
3186     PDDI_MEDIA_CONTEXT mediaDrvCtx = DdiMedia_GetMediaContext(ctx);
3187     DDI_CHK_NULL(mediaDrvCtx,     "nullptr mediaDrvCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
3188 
3189     if(num_render_targets > 0)
3190     {
3191         DDI_CHK_NULL(render_targets,             "nullptr render_targets",             VA_STATUS_ERROR_INVALID_PARAMETER);
3192         DDI_CHK_NULL(mediaDrvCtx->pSurfaceHeap, "nullptr mediaDrvCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
3193         for(int32_t i = 0; i < num_render_targets; i++)
3194         {
3195             uint32_t surfaceId = (uint32_t)render_targets[i];
3196             DDI_CHK_LESS(surfaceId, mediaDrvCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid Surface", VA_STATUS_ERROR_INVALID_SURFACE);
3197         }
3198     }
3199 
3200     VAStatus vaStatus = VA_STATUS_SUCCESS;
3201     if(mediaDrvCtx->m_caps->IsDecConfigId(config_id))
3202     {
3203         vaStatus = DdiDecode_CreateContext(ctx, config_id - DDI_CODEC_GEN_CONFIG_ATTRIBUTES_DEC_BASE, picture_width, picture_height, flag, render_targets, num_render_targets, context);
3204     }
3205     else if(mediaDrvCtx->m_caps->IsEncConfigId(config_id))
3206     {
3207         vaStatus = DdiEncode_CreateContext(ctx, config_id - DDI_CODEC_GEN_CONFIG_ATTRIBUTES_ENC_BASE, picture_width, picture_height, flag, render_targets, num_render_targets, context);
3208     }
3209     else if(mediaDrvCtx->m_caps->IsVpConfigId(config_id))
3210     {
3211         vaStatus = DdiVp_CreateContext(ctx, config_id - DDI_VP_GEN_CONFIG_ATTRIBUTES_BASE, picture_width, picture_height, flag, render_targets, num_render_targets, context);
3212     }
3213     else
3214     {
3215         DDI_ASSERTMESSAGE("DDI: Invalid config_id");
3216         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
3217     }
3218 
3219     return vaStatus;
3220 }
3221 
DdiMedia_DestroyContext(VADriverContextP ctx,VAContextID context)3222 VAStatus DdiMedia_DestroyContext (
3223     VADriverContextP    ctx,
3224     VAContextID         context
3225 )
3226 {
3227     DDI_FUNCTION_ENTER();
3228 
3229     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
3230 
3231     uint32_t            ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
3232     void *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType);
3233 
3234     switch (ctxType)
3235     {
3236         case DDI_MEDIA_CONTEXT_TYPE_DECODER:
3237             return DdiDecode_DestroyContext(ctx, context);
3238         case DDI_MEDIA_CONTEXT_TYPE_ENCODER:
3239             return DdiEncode_DestroyContext(ctx, context);
3240         case DDI_MEDIA_CONTEXT_TYPE_VP:
3241             return DdiVp_DestroyContext(ctx, context);
3242         case DDI_MEDIA_CONTEXT_TYPE_MFE:
3243             return DdiMedia_DestoryMfeContext(ctx, context);
3244         default:
3245             DDI_ASSERTMESSAGE("DDI: unsupported context in DdiCodec_DestroyContext.");
3246             return VA_STATUS_ERROR_INVALID_CONTEXT;
3247     }
3248 }
3249 
DdiMedia_CreateBuffer(VADriverContextP ctx,VAContextID context,VABufferType type,uint32_t size,uint32_t num_elements,void * data,VABufferID * bufId)3250 VAStatus DdiMedia_CreateBuffer (
3251     VADriverContextP    ctx,
3252     VAContextID         context,
3253     VABufferType        type,
3254     uint32_t            size,
3255     uint32_t            num_elements,
3256     void                *data,
3257     VABufferID          *bufId
3258 )
3259 {
3260     DDI_FUNCTION_ENTER();
3261     int32_t event[] = {size, num_elements, type};
3262     MOS_TraceEventExt(EVENT_VA_BUFFER, EVENT_TYPE_START, event, sizeof(event), nullptr, 0);
3263 
3264     DDI_CHK_NULL(ctx,        "nullptr ctx",     VA_STATUS_ERROR_INVALID_CONTEXT);
3265     DDI_CHK_NULL(bufId,     "nullptr buf_id",  VA_STATUS_ERROR_INVALID_PARAMETER);
3266     DDI_CHK_LARGER(size, 0,  "Invalid size", VA_STATUS_ERROR_INVALID_PARAMETER);
3267 
3268     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
3269     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
3270 
3271     uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
3272     void     *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType);
3273     DDI_CHK_NULL(ctxPtr,      "nullptr ctxPtr",      VA_STATUS_ERROR_INVALID_CONTEXT);
3274 
3275     *bufId     = VA_INVALID_ID;
3276 
3277     DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
3278     VAStatus va = VA_STATUS_SUCCESS;
3279     switch (ctxType)
3280     {
3281         case DDI_MEDIA_CONTEXT_TYPE_DECODER:
3282             va = DdiDecode_CreateBuffer(ctx, DdiDecode_GetDecContextFromPVOID(ctxPtr), type, size, num_elements, data, bufId);
3283             break;
3284         case DDI_MEDIA_CONTEXT_TYPE_ENCODER:
3285             va = DdiEncode_CreateBuffer(ctx, context, type, size, num_elements, data, bufId);
3286             break;
3287         case DDI_MEDIA_CONTEXT_TYPE_VP:
3288             va = DdiVp_CreateBuffer(ctx, ctxPtr, type, size, num_elements, data, bufId);
3289             break;
3290         case DDI_MEDIA_CONTEXT_TYPE_PROTECTED:
3291             va = DdiMediaProtected::DdiMedia_ProtectedSessionCreateBuffer(ctx, context, type, size, num_elements, data, bufId);
3292             break;
3293         default:
3294             va = VA_STATUS_ERROR_INVALID_CONTEXT;
3295     }
3296 
3297     DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
3298     MOS_TraceEventExt(EVENT_VA_BUFFER, EVENT_TYPE_END, bufId, sizeof(bufId), nullptr, 0);
3299     return va;
3300 }
3301 
DdiMedia_BufferSetNumElements(VADriverContextP ctx,VABufferID buf_id,uint32_t num_elements)3302 VAStatus DdiMedia_BufferSetNumElements (
3303     VADriverContextP    ctx,
3304     VABufferID          buf_id,
3305     uint32_t            num_elements
3306 )
3307 {
3308     DDI_FUNCTION_ENTER();
3309 
3310     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
3311 
3312     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
3313     DDI_CHK_NULL(mediaCtx,              "nullptr mediaCtx",              VA_STATUS_ERROR_INVALID_CONTEXT);
3314 
3315     DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
3316     DDI_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid buf_id", VA_STATUS_ERROR_INVALID_BUFFER);
3317 
3318     DDI_MEDIA_BUFFER *buf       = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id);
3319     DDI_CHK_NULL(buf, "Invalid buffer.", VA_STATUS_ERROR_INVALID_BUFFER);
3320 
3321     // only for VASliceParameterBufferType of buffer, the number of elements can be greater than 1
3322     if(buf->uiType != VASliceParameterBufferType &&
3323        num_elements > 1)
3324     {
3325         return VA_STATUS_ERROR_INVALID_PARAMETER;
3326     }
3327 
3328     if(buf->uiType == VASliceParameterBufferType &&
3329        buf->uiNumElements < num_elements)
3330     {
3331         MOS_FreeMemory(buf->pData);
3332         buf->iSize = buf->iSize / buf->uiNumElements;
3333         buf->pData = (uint8_t*)MOS_AllocAndZeroMemory(buf->iSize * num_elements);
3334         buf->iSize = buf->iSize * num_elements;
3335     }
3336 
3337     return VA_STATUS_SUCCESS;
3338 }
3339 
3340 //!
3341 //! \brief  Map data store of the buffer into the client's address space
3342 //!         vaCreateBuffer() needs to be called with "data" set to nullptr before
3343 //!         calling vaMapBuffer()
3344 //!
3345 //! \param  [in] ctx
3346 //!         Pointer to VA driver context
3347 //! \param  [in] buf_id
3348 //!         VA buffer ID
3349 //! \param  [out] pbuf
3350 //!         Pointer to buffer
3351 //! \param  [in] flag
3352 //!         Flag
3353 //!
3354 //! \return VAStatus
3355 //!     VA_STATUS_SUCCESS if success, else fail reason
3356 //!
DdiMedia_MapBufferInternal(VADriverContextP ctx,VABufferID buf_id,void ** pbuf,uint32_t flag)3357 VAStatus DdiMedia_MapBufferInternal (
3358     VADriverContextP    ctx,
3359     VABufferID          buf_id,
3360     void              **pbuf,
3361     uint32_t            flag
3362 )
3363 {
3364     DDI_FUNCTION_ENTER();
3365     MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_START, &buf_id, sizeof(buf_id), &flag, sizeof(flag));
3366 
3367     DDI_CHK_NULL(ctx,   "nullptr ctx",     VA_STATUS_ERROR_INVALID_CONTEXT);
3368     DDI_CHK_NULL(pbuf,  "nullptr pbuf",    VA_STATUS_ERROR_INVALID_PARAMETER);
3369 
3370     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
3371     DDI_CHK_NULL(mediaCtx,              "nullptr mediaCtx",              VA_STATUS_ERROR_INVALID_CONTEXT);
3372 
3373     DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
3374     DDI_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid bufferId", VA_STATUS_ERROR_INVALID_CONTEXT);
3375 
3376     DDI_MEDIA_BUFFER   *buf     = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id);
3377     DDI_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_BUFFER);
3378 
3379     // The context is nullptr when the buffer is created from DdiMedia_DeriveImage
3380     // So doesn't need to check the context for all cases
3381     // Only check the context in dec/enc mode
3382     VAStatus                 vaStatus  = VA_STATUS_SUCCESS;
3383     uint32_t                 ctxType = DdiMedia_GetCtxTypeFromVABufferID(mediaCtx, buf_id);
3384     void                     *ctxPtr = nullptr;
3385     DDI_CODEC_COM_BUFFER_MGR *bufMgr = nullptr;
3386     PDDI_ENCODE_CONTEXT      encCtx  = nullptr;
3387     PDDI_DECODE_CONTEXT      decCtx  = nullptr;
3388     switch (ctxType)
3389     {
3390         case DDI_MEDIA_CONTEXT_TYPE_VP:
3391         case DDI_MEDIA_CONTEXT_TYPE_PROTECTED:
3392             break;
3393         case DDI_MEDIA_CONTEXT_TYPE_DECODER:
3394             ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx, buf_id);
3395             DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
3396 
3397             decCtx = DdiDecode_GetDecContextFromPVOID(ctxPtr);
3398             bufMgr = &(decCtx->BufMgr);
3399             break;
3400         case DDI_MEDIA_CONTEXT_TYPE_ENCODER:
3401             ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx, buf_id);
3402             DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
3403 
3404             encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr);
3405             DDI_CHK_NULL(encCtx, "nullptr encCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
3406             bufMgr = &(encCtx->BufMgr);
3407             break;
3408         case DDI_MEDIA_CONTEXT_TYPE_MEDIA:
3409             break;
3410         default:
3411             return VA_STATUS_ERROR_INVALID_BUFFER;
3412     }
3413 
3414     MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_INFO, &ctxType, sizeof(ctxType), &buf->uiType, sizeof(uint32_t));
3415     switch ((int32_t)buf->uiType)
3416     {
3417         case VASliceDataBufferType:
3418         case VAProtectedSliceDataBufferType:
3419         case VABitPlaneBufferType:
3420             *pbuf = (void *)(buf->pData + buf->uiOffset);
3421             break;
3422 
3423         case VASliceParameterBufferType:
3424             ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx, buf_id);
3425             DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
3426 
3427             decCtx = DdiDecode_GetDecContextFromPVOID(ctxPtr);
3428             bufMgr = &(decCtx->BufMgr);
3429             switch (decCtx->wMode)
3430             {
3431                 case CODECHAL_DECODE_MODE_AVCVLD:
3432                     if(decCtx->bShortFormatInUse)
3433                         *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base) + buf->uiOffset);
3434                     else
3435                         *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264) + buf->uiOffset);
3436                     break;
3437                 case CODECHAL_DECODE_MODE_MPEG2VLD:
3438                     *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_MPEG2.pVASliceParaBufMPEG2) + buf->uiOffset);
3439                     break;
3440                 case CODECHAL_DECODE_MODE_VC1VLD:
3441                     *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1) + buf->uiOffset);
3442                     break;
3443                 case CODECHAL_DECODE_MODE_JPEG:
3444                     *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG) + buf->uiOffset);
3445                     break;
3446                 case CODECHAL_DECODE_MODE_VP8VLD:
3447                     *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_VP8.pVASliceParaBufVP8) + buf->uiOffset);
3448                     break;
3449                 case CODECHAL_DECODE_MODE_HEVCVLD:
3450                     if(decCtx->bShortFormatInUse)
3451                         *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC) + buf->uiOffset);
3452                     else
3453                     {
3454                         if(!decCtx->m_ddiDecode->IsRextProfile())
3455                            *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC) + buf->uiOffset);
3456                         else
3457                            *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext) + buf->uiOffset);
3458                      }
3459                     break;
3460                 case CODECHAL_DECODE_MODE_VP9VLD:
3461                     *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9) + buf->uiOffset);
3462                     break;
3463                 case CODECHAL_DECODE_MODE_AV1VLD:
3464                 case CODECHAL_DECODE_MODE_VVCVLD:
3465                     *pbuf = (void *)((uint8_t*)(bufMgr->pCodecSlcParamReserved) + buf->uiOffset);
3466                     break;
3467                 default:
3468                     break;
3469             }
3470             break;
3471 
3472         case VAEncCodedBufferType:
3473             DDI_CHK_NULL(encCtx, "nullptr encCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
3474 
3475             if( DdiEncode_CodedBufferExistInStatusReport( encCtx, buf ) )
3476             {
3477                 vaStatus = DdiEncode_StatusReport(encCtx, buf, pbuf);
3478                 MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
3479                 return vaStatus;
3480             }
3481             // so far a coded buffer that has NOT been added into status report is skipped frame in non-CP case
3482             // but this can change in future if new usage models come up
3483             encCtx->BufMgr.pCodedBufferSegment->buf  = DdiMediaUtil_LockBuffer(buf, flag);
3484             encCtx->BufMgr.pCodedBufferSegment->size = buf->iSize;
3485             *pbuf =  encCtx->BufMgr.pCodedBufferSegment;
3486 
3487             break;
3488 
3489         case VAStatsStatisticsBufferType:
3490         case VAStatsStatisticsBottomFieldBufferType:
3491         case VAStatsMVBufferType:
3492             {
3493                 DDI_CHK_NULL(encCtx, "nullptr encCtx", VA_STATUS_ERROR_INVALID_CONTEXT)
3494                 DDI_ENCODE_PRE_ENC_BUFFER_TYPE idx = (buf->uiType == VAStatsMVBufferType) ? PRE_ENC_BUFFER_TYPE_MVDATA :
3495                                                     ((buf->uiType == VAStatsStatisticsBufferType)   ? PRE_ENC_BUFFER_TYPE_STATS
3496                                                                                                           : PRE_ENC_BUFFER_TYPE_STATS_BOT);
3497                 if((encCtx->codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC) && DdiEncode_PreEncBufferExistInStatusReport( encCtx, buf, idx))
3498                 {
3499                     vaStatus = DdiEncode_PreEncStatusReport(encCtx, buf, pbuf);
3500                     MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
3501                     return vaStatus;
3502                 }
3503                 if(buf->bo)
3504                 {
3505                     *pbuf = DdiMediaUtil_LockBuffer(buf, flag);
3506                 }
3507                 break;
3508             }
3509         case VAStatsMVPredictorBufferType:
3510         case VAEncFEIMBControlBufferType:
3511         case VAEncFEIMVPredictorBufferType:
3512         case VAEncQPBufferType:
3513             if(buf->bo)
3514             {
3515                 *pbuf = DdiMediaUtil_LockBuffer(buf, flag);
3516             }
3517             break;
3518         case VADecodeStreamoutBufferType:
3519             if(buf->bo)
3520             {
3521                  uint32_t timeout_NS = 100000000;
3522                  while (0 != mos_bo_wait(buf->bo, timeout_NS))
3523                  {
3524                      // Just loop while gem_bo_wait times-out.
3525                  }
3526                  *pbuf = DdiMediaUtil_LockBuffer(buf, flag);
3527             }
3528             break;
3529         case VAEncFEIMVBufferType:
3530         case VAEncFEIMBCodeBufferType:
3531         case VAEncFEICURecordBufferType:
3532         case VAEncFEICTBCmdBufferType:
3533         case VAEncFEIDistortionBufferType:
3534             {
3535                 DDI_CHK_NULL(encCtx, "nullptr encCtx", VA_STATUS_ERROR_INVALID_CONTEXT)
3536                 if(encCtx->wModeType == CODECHAL_ENCODE_MODE_AVC)
3537                 {
3538                     CodecEncodeAvcFeiPicParams *feiPicParams = (CodecEncodeAvcFeiPicParams *)encCtx->pFeiPicParams;
3539 
3540                     DDI_ENCODE_FEI_ENC_BUFFER_TYPE idx = (buf->uiType == VAEncFEIMVBufferType) ? FEI_ENC_BUFFER_TYPE_MVDATA :
3541                                        ((buf->uiType == VAEncFEIMBCodeBufferType) ? FEI_ENC_BUFFER_TYPE_MBCODE :
3542                                                                                         FEI_ENC_BUFFER_TYPE_DISTORTION);
3543                     if((feiPicParams != nullptr) && (encCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC) && DdiEncode_EncBufferExistInStatusReport( encCtx, buf, idx))
3544                     {
3545                         vaStatus = DdiEncode_EncStatusReport(encCtx, buf, pbuf);
3546                         MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
3547                         return vaStatus;
3548                     }
3549                 }
3550                 else if(encCtx->wModeType == CODECHAL_ENCODE_MODE_HEVC)
3551 
3552                 {
3553                     CodecEncodeHevcFeiPicParams *feiPicParams = (CodecEncodeHevcFeiPicParams *)encCtx->pFeiPicParams;
3554                     DDI_ENCODE_FEI_ENC_BUFFER_TYPE idx = (buf->uiType == VAEncFEICTBCmdBufferType) ? FEI_ENC_BUFFER_TYPE_MVDATA   :
3555                                                       ((buf->uiType == VAEncFEICURecordBufferType) ? FEI_ENC_BUFFER_TYPE_MBCODE :
3556                                                                                                       FEI_ENC_BUFFER_TYPE_DISTORTION);
3557                     if((feiPicParams != nullptr) && (encCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC) && DdiEncode_EncBufferExistInStatusReport( encCtx, buf, idx))
3558                     {
3559                         vaStatus = DdiEncode_EncStatusReport(encCtx, buf, pbuf);
3560                         MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
3561                         return vaStatus;
3562                     }
3563                 }
3564                 if(buf->bo)
3565                 {
3566                     *pbuf = DdiMediaUtil_LockBuffer(buf, flag);
3567                 }
3568             }
3569             break;
3570         case VAStatsStatisticsParameterBufferType:
3571             *pbuf = (void *)(buf->pData + buf->uiOffset);
3572             break;
3573         case VAEncMacroblockMapBufferType:
3574             DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
3575             *pbuf = DdiMediaUtil_LockBuffer(buf, flag);
3576             DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
3577             MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
3578             if (nullptr == (*pbuf))
3579             {
3580                 return VA_STATUS_ERROR_OPERATION_FAILED;
3581             }
3582             else
3583             {
3584                 return VA_STATUS_SUCCESS;
3585             }
3586             break;
3587 
3588         case VAProbabilityBufferType:
3589             *pbuf = (void *)(buf->pData + buf->uiOffset);
3590 
3591             break;
3592 
3593         case VAEncMacroblockDisableSkipMapBufferType:
3594             if(buf->bo)
3595             {
3596                 *pbuf = DdiMediaUtil_LockBuffer(buf, flag);
3597             }
3598             break;
3599 
3600         case VAImageBufferType:
3601         default:
3602             if((buf->format != Media_Format_CPU) && (DdiMedia_MediaFormatToOsFormat(buf->format) != VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT))
3603             {
3604                 DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
3605                 // A critical section starts.
3606                 // Make sure not to bailout with a return until the section ends.
3607 
3608                 if (nullptr != buf->pSurface && Media_Format_CPU != buf->format)
3609                 {
3610                     vaStatus = DdiMedia_MediaMemoryDecompress(mediaCtx, buf->pSurface);
3611                 }
3612 
3613                 if (VA_STATUS_SUCCESS == vaStatus)
3614                 {
3615                     *pbuf = DdiMediaUtil_LockBuffer(buf, flag);
3616 
3617                     if (nullptr == *pbuf)
3618                     {
3619                         vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
3620                     }
3621                 }
3622 
3623                 // The critical section ends.
3624                 DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
3625             }
3626             else
3627             {
3628                 *pbuf = (void *)(buf->pData + buf->uiOffset);
3629             }
3630             break;
3631     }
3632 
3633     MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
3634     return vaStatus;
3635 }
3636 
DdiMedia_MapBuffer(VADriverContextP ctx,VABufferID buf_id,void ** pbuf)3637 VAStatus DdiMedia_MapBuffer (
3638     VADriverContextP    ctx,
3639     VABufferID          buf_id,
3640     void                **pbuf
3641 )
3642 {
3643     return DdiMedia_MapBufferInternal(ctx, buf_id, pbuf, MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY);
3644 }
3645 
DdiMedia_UnmapBuffer(VADriverContextP ctx,VABufferID buf_id)3646 VAStatus DdiMedia_UnmapBuffer (
3647     VADriverContextP    ctx,
3648     VABufferID          buf_id
3649 )
3650 {
3651     DDI_FUNCTION_ENTER();
3652     MOS_TraceEventExt(EVENT_VA_UNMAP, EVENT_TYPE_START, &buf_id, sizeof(buf_id), nullptr, 0);
3653 
3654     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
3655 
3656     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
3657     DDI_CHK_NULL(mediaCtx,               "nullptr mediaCtx",               VA_STATUS_ERROR_INVALID_CONTEXT);
3658 
3659     DDI_CHK_NULL( mediaCtx->pBufferHeap, "nullptr  mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
3660     DDI_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid buf_id", VA_STATUS_ERROR_INVALID_BUFFER);
3661 
3662     DDI_MEDIA_BUFFER   *buf     = DdiMedia_GetBufferFromVABufferID(mediaCtx,  buf_id);
3663     DDI_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_BUFFER);
3664 
3665     // The context is nullptr when the buffer is created from DdiMedia_DeriveImage
3666     // So doesn't need to check the context for all cases
3667     // Only check the context in dec/enc mode
3668     void     *ctxPtr = nullptr;
3669     uint32_t ctxType = DdiMedia_GetCtxTypeFromVABufferID(mediaCtx, buf_id);
3670     DDI_CODEC_COM_BUFFER_MGR *bufMgr = nullptr;
3671     PDDI_DECODE_CONTEXT decCtx = nullptr;
3672     PDDI_ENCODE_CONTEXT encCtx = nullptr;
3673     switch (ctxType)
3674     {
3675         case DDI_MEDIA_CONTEXT_TYPE_VP:
3676         case DDI_MEDIA_CONTEXT_TYPE_PROTECTED:
3677             break;
3678         case DDI_MEDIA_CONTEXT_TYPE_DECODER:
3679             ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx, buf_id);
3680             DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
3681 
3682             decCtx = DdiDecode_GetDecContextFromPVOID(ctxPtr);
3683             bufMgr = &(decCtx->BufMgr);
3684             break;
3685         case DDI_MEDIA_CONTEXT_TYPE_ENCODER:
3686             ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx, buf_id);
3687             DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
3688 
3689             encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr);
3690             bufMgr = &(encCtx->BufMgr);
3691             break;
3692         case DDI_MEDIA_CONTEXT_TYPE_MEDIA:
3693             break;
3694         default:
3695             return VA_STATUS_ERROR_INVALID_BUFFER;
3696     }
3697 
3698     switch ((int32_t)buf->uiType)
3699     {
3700         case VASliceDataBufferType:
3701         case VAProtectedSliceDataBufferType:
3702         case VABitPlaneBufferType:
3703             break;
3704         case VAEncCodedBufferType:
3705         case VAStatsStatisticsBufferType:
3706         case VAStatsStatisticsBottomFieldBufferType:
3707         case VAStatsMVBufferType:
3708         case VAStatsMVPredictorBufferType:
3709         case VAEncFEIMBControlBufferType:
3710         case VAEncFEIMVPredictorBufferType:
3711         case VAEncFEIMVBufferType:
3712         case VAEncFEIMBCodeBufferType:
3713         case VAEncFEICURecordBufferType:
3714         case VAEncFEICTBCmdBufferType:
3715         case VAEncFEIDistortionBufferType:
3716         case VAEncQPBufferType:
3717         case VADecodeStreamoutBufferType:
3718             if(buf->bo)
3719             {
3720                 DdiMediaUtil_UnlockBuffer(buf);
3721             }
3722             break;
3723         case VAEncMacroblockDisableSkipMapBufferType:
3724             if(buf->bo)
3725             {
3726                 DdiMediaUtil_UnlockBuffer(buf);
3727             }
3728             break;
3729 
3730         case VAImageBufferType:
3731         default:
3732             if((buf->format != Media_Format_CPU) &&(DdiMedia_MediaFormatToOsFormat(buf->format) != VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT))
3733             {
3734                 DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
3735                 DdiMediaUtil_UnlockBuffer(buf);
3736                 DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
3737             }
3738             break;
3739     }
3740 
3741     MOS_TraceEventExt(EVENT_VA_UNMAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
3742     return VA_STATUS_SUCCESS;
3743 }
3744 
DdiMedia_DestroyBuffer(VADriverContextP ctx,VABufferID buffer_id)3745 VAStatus DdiMedia_DestroyBuffer (
3746     VADriverContextP    ctx,
3747     VABufferID          buffer_id
3748 )
3749 {
3750     DDI_FUNCTION_ENTER();
3751     MOS_TraceEventExt(EVENT_VA_FREE_BUFFER, EVENT_TYPE_START, &buffer_id, sizeof(buffer_id), nullptr, 0);
3752 
3753     DDI_CHK_NULL(ctx,                    "nullptr ctx",                    VA_STATUS_ERROR_INVALID_CONTEXT);
3754 
3755     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
3756     DDI_CHK_NULL(mediaCtx,              "nullptr mediaCtx",              VA_STATUS_ERROR_INVALID_CONTEXT);
3757 
3758     DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
3759     DDI_CHK_LESS((uint32_t)buffer_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid bufferId", VA_STATUS_ERROR_INVALID_CONTEXT);
3760 
3761     DDI_MEDIA_BUFFER   *buf     = DdiMedia_GetBufferFromVABufferID(mediaCtx,  buffer_id);
3762     DDI_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_BUFFER);
3763 
3764     void     *ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx,     buffer_id);
3765     uint32_t ctxType = DdiMedia_GetCtxTypeFromVABufferID(mediaCtx, buffer_id);
3766 
3767     DDI_CODEC_COM_BUFFER_MGR     *bufMgr  = nullptr;
3768     PDDI_ENCODE_CONTEXT           encCtx  = nullptr;
3769     PDDI_DECODE_CONTEXT           decCtx  = nullptr;
3770     switch (ctxType)
3771     {
3772         case DDI_MEDIA_CONTEXT_TYPE_DECODER:
3773             DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
3774             decCtx = DdiDecode_GetDecContextFromPVOID(ctxPtr);
3775             bufMgr = &(decCtx->BufMgr);
3776             break;
3777         case DDI_MEDIA_CONTEXT_TYPE_ENCODER:
3778             DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
3779             encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr);
3780             bufMgr = &(encCtx->BufMgr);
3781             break;
3782         case DDI_MEDIA_CONTEXT_TYPE_VP:
3783             break;
3784         case DDI_MEDIA_CONTEXT_TYPE_MEDIA:
3785             break;
3786         case DDI_MEDIA_CONTEXT_TYPE_PROTECTED:
3787             break;
3788         default:
3789             return VA_STATUS_ERROR_INVALID_BUFFER;
3790     }
3791     switch ((int32_t)buf->uiType)
3792     {
3793         case VASliceDataBufferType:
3794         case VAProtectedSliceDataBufferType:
3795             DdiMedia_ReleaseBsBuffer(bufMgr, buf);
3796             break;
3797         case VABitPlaneBufferType:
3798             DdiMedia_ReleaseBpBuffer(bufMgr, buf);
3799             break;
3800         case VAProbabilityBufferType:
3801             DdiMedia_ReleaseBpBuffer(bufMgr, buf);
3802             break;
3803 
3804         case VASliceParameterBufferType:
3805             DdiMedia_ReleaseSliceControlBuffer(ctxType, ctxPtr, buf);
3806             break;
3807         case VAPictureParameterBufferType:
3808             break;
3809         case VAImageBufferType:
3810             if(buf->format == Media_Format_CPU)
3811             {
3812                 MOS_FreeMemory(buf->pData);
3813             }
3814             else
3815             {
3816                 DdiMediaUtil_UnRefBufObjInMediaBuffer(buf);
3817 
3818                 if (buf->uiExportcount) {
3819                     buf->bPostponedBufFree = true;
3820                     MOS_TraceEventExt(EVENT_VA_FREE_BUFFER, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
3821                     return VA_STATUS_SUCCESS;
3822                 }
3823             }
3824             break;
3825         case VAProcPipelineParameterBufferType:
3826         case VAProcFilterParameterBufferType:
3827             MOS_FreeMemory(buf->pData);
3828             break;
3829         case VASubsetsParameterBufferType:
3830         case VAIQMatrixBufferType:
3831         case VAHuffmanTableBufferType:
3832         case VAEncSliceParameterBufferType:
3833         case VAEncPictureParameterBufferType:
3834         case VAEncSequenceParameterBufferType:
3835         case VAEncPackedHeaderDataBufferType:
3836         case VAEncPackedHeaderParameterBufferType:
3837             MOS_FreeMemory(buf->pData);
3838             break;
3839         case VAEncMacroblockMapBufferType:
3840             DdiMediaUtil_FreeBuffer(buf);
3841             break;
3842 #ifdef ENABLE_ENC_UNLIMITED_OUTPUT
3843         case VAEncCodedBufferType:
3844             if(nullptr == encCtx)
3845             {
3846                 encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr);
3847                 if(nullptr == encCtx)
3848                     return VA_STATUS_ERROR_INVALID_CONTEXT;
3849             }
3850             DdiMediaUtil_FreeBuffer(buf);
3851             break;
3852 #endif
3853         case VAStatsStatisticsParameterBufferType:
3854             MOS_FreeMemory(buf->pData);
3855             break;
3856         case VAStatsStatisticsBufferType:
3857         case VAStatsStatisticsBottomFieldBufferType:
3858         case VAStatsMVBufferType:
3859             {
3860                 if(nullptr == encCtx)
3861                 {
3862                     encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr);
3863                     if(nullptr == encCtx)
3864                         return VA_STATUS_ERROR_INVALID_CONTEXT;
3865                 }
3866                 if(encCtx->codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC)
3867                 {
3868                     DDI_ENCODE_PRE_ENC_BUFFER_TYPE idx = (buf->uiType == VAStatsMVBufferType) ? PRE_ENC_BUFFER_TYPE_MVDATA :
3869                                                         ((buf->uiType == VAStatsStatisticsBufferType)   ? PRE_ENC_BUFFER_TYPE_STATS
3870                                                                                                               : PRE_ENC_BUFFER_TYPE_STATS_BOT);
3871                     DdiEncode_RemoveFromPreEncStatusReportQueue(encCtx, buf, idx);
3872                 }
3873             }
3874             DdiMediaUtil_FreeBuffer(buf);
3875             break;
3876         case VAStatsMVPredictorBufferType:
3877         case VAEncFEIMBControlBufferType:
3878         case VAEncFEIMVPredictorBufferType:
3879         case VAEncQPBufferType:
3880         case VADecodeStreamoutBufferType:
3881             DdiMediaUtil_FreeBuffer(buf);
3882             break;
3883         case VAEncFEIMVBufferType:
3884         case VAEncFEIMBCodeBufferType:
3885         case VAEncFEICURecordBufferType:
3886         case VAEncFEICTBCmdBufferType:
3887         case VAEncFEIDistortionBufferType:
3888             {
3889                 if(nullptr == encCtx)
3890                 {
3891                     encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr);
3892                     if(nullptr == encCtx)
3893                         return VA_STATUS_ERROR_INVALID_CONTEXT;
3894                 }
3895                 if(encCtx->wModeType == CODECHAL_ENCODE_MODE_AVC)
3896                 {
3897                     CodecEncodeAvcFeiPicParams *feiPicParams;
3898                     feiPicParams = (CodecEncodeAvcFeiPicParams *)(encCtx->pFeiPicParams);
3899                     if((feiPicParams != nullptr) && (encCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC))
3900                     {
3901                         DDI_ENCODE_FEI_ENC_BUFFER_TYPE idx = (buf->uiType == VAEncFEIMVBufferType) ? FEI_ENC_BUFFER_TYPE_MVDATA :
3902                                                         ((buf->uiType == VAEncFEIMBCodeBufferType) ? FEI_ENC_BUFFER_TYPE_MBCODE :
3903                                                                                                       FEI_ENC_BUFFER_TYPE_DISTORTION);
3904                         DdiEncode_RemoveFromEncStatusReportQueue(encCtx, buf, idx);
3905                     }
3906 
3907                 }
3908                 else if(encCtx->wModeType == CODECHAL_ENCODE_MODE_HEVC)
3909                 {
3910                     CodecEncodeHevcFeiPicParams *feiPicParams;
3911                     feiPicParams = (CodecEncodeHevcFeiPicParams *)(encCtx->pFeiPicParams);
3912                     if((feiPicParams != nullptr) && (encCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC))
3913                     {
3914                         DDI_ENCODE_FEI_ENC_BUFFER_TYPE idx = (buf->uiType == VAEncFEICTBCmdBufferType) ? FEI_ENC_BUFFER_TYPE_MVDATA   :
3915                                                           ((buf->uiType == VAEncFEICURecordBufferType) ? FEI_ENC_BUFFER_TYPE_MBCODE :
3916                                                                                                           FEI_ENC_BUFFER_TYPE_DISTORTION);
3917                         DdiEncode_RemoveFromEncStatusReportQueue(encCtx, buf, idx);
3918                     }
3919                 }
3920             }
3921             DdiMediaUtil_FreeBuffer(buf);
3922             break;
3923         default: // do not handle any un-listed buffer type
3924             MOS_FreeMemory(buf->pData);
3925             break;
3926             //return va_STATUS_SUCCESS;
3927     }
3928     MOS_FreeMemory(buf);
3929 
3930     DdiMedia_DestroyBufFromVABufferID(mediaCtx, buffer_id);
3931     MOS_TraceEventExt(EVENT_VA_FREE_BUFFER, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
3932     return VA_STATUS_SUCCESS;
3933 }
3934 
DdiMedia_BeginPicture(VADriverContextP ctx,VAContextID context,VASurfaceID render_target)3935 VAStatus DdiMedia_BeginPicture (
3936     VADriverContextP    ctx,
3937     VAContextID         context,
3938     VASurfaceID         render_target
3939 )
3940 {
3941     DDI_FUNCTION_ENTER();
3942 
3943     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
3944 
3945     PDDI_MEDIA_CONTEXT mediaCtx   = DdiMedia_GetMediaContext(ctx);
3946 
3947     DDI_CHK_NULL(mediaCtx,               "nullptr mediaCtx",               VA_STATUS_ERROR_INVALID_CONTEXT);
3948     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
3949     DDI_CHK_LESS((uint32_t)render_target, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "render_target", VA_STATUS_ERROR_INVALID_SURFACE);
3950 
3951     uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
3952     void     *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType);
3953     uint32_t event[] = {(uint32_t)context, ctxType, (uint32_t)render_target};
3954     MOS_TraceEventExt(EVENT_VA_PICTURE, EVENT_TYPE_START, event, sizeof(event), nullptr, 0);
3955 
3956     PDDI_MEDIA_SURFACE surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, render_target);
3957     DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
3958 
3959     DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
3960     surface->curCtxType = ctxType;
3961     surface->curStatusReportQueryState = DDI_MEDIA_STATUS_REPORT_QUERY_STATE_PENDING;
3962     if(ctxType == DDI_MEDIA_CONTEXT_TYPE_VP)
3963     {
3964         surface->curStatusReport.vpp.status = VPREP_NOTAVAILABLE;
3965     }
3966     DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
3967 
3968     switch (ctxType)
3969     {
3970         case DDI_MEDIA_CONTEXT_TYPE_DECODER:
3971             return DdiDecode_BeginPicture(ctx, context, render_target);
3972         case DDI_MEDIA_CONTEXT_TYPE_ENCODER:
3973             return DdiEncode_BeginPicture(ctx, context, render_target);
3974         case DDI_MEDIA_CONTEXT_TYPE_VP:
3975             return DdiVp_BeginPicture(ctx, context, render_target);
3976         default:
3977             DDI_ASSERTMESSAGE("DDI: unsupported context in DdiCodec_BeginPicture.");
3978             return VA_STATUS_ERROR_INVALID_CONTEXT;
3979     }
3980 }
3981 
DdiMedia_RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t num_buffers)3982 VAStatus DdiMedia_RenderPicture (
3983     VADriverContextP    ctx,
3984     VAContextID         context,
3985     VABufferID         *buffers,
3986     int32_t             num_buffers
3987 )
3988 {
3989 
3990     DDI_FUNCTION_ENTER();
3991 
3992     DDI_CHK_NULL(  ctx,            "nullptr ctx",                   VA_STATUS_ERROR_INVALID_CONTEXT);
3993     DDI_CHK_NULL(  buffers,        "nullptr buffers",               VA_STATUS_ERROR_INVALID_PARAMETER);
3994     DDI_CHK_LARGER(num_buffers, 0, "Invalid number buffers",     VA_STATUS_ERROR_INVALID_PARAMETER);
3995     uint32_t event[] = {(uint32_t)context, (uint32_t)num_buffers};
3996     MOS_TraceEventExt(EVENT_VA_PICTURE, EVENT_TYPE_INFO, event, sizeof(event), buffers, num_buffers*sizeof(VAGenericID));
3997 
3998     PDDI_MEDIA_CONTEXT mediaCtx   = DdiMedia_GetMediaContext(ctx);
3999     DDI_CHK_NULL(mediaCtx,              "nullptr mediaCtx",              VA_STATUS_ERROR_INVALID_CONTEXT);
4000     DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
4001 
4002     for(int32_t i = 0; i < num_buffers; i++)
4003     {
4004        DDI_CHK_LESS((uint32_t)buffers[i], mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid Buffer", VA_STATUS_ERROR_INVALID_BUFFER);
4005     }
4006 
4007     uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
4008     void     *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType);
4009 
4010     switch (ctxType)
4011     {
4012         case DDI_MEDIA_CONTEXT_TYPE_DECODER:
4013             return DdiDecode_RenderPicture(ctx, context, buffers, num_buffers);
4014         case DDI_MEDIA_CONTEXT_TYPE_ENCODER:
4015             return DdiEncode_RenderPicture(ctx, context, buffers, num_buffers);
4016         case DDI_MEDIA_CONTEXT_TYPE_VP:
4017             return DdiVp_RenderPicture(ctx, context, buffers, num_buffers);
4018         default:
4019             DDI_ASSERTMESSAGE("DDI: unsupported context in DdiCodec_RenderPicture.");
4020             return VA_STATUS_ERROR_INVALID_CONTEXT;
4021     }
4022 
4023 }
4024 
DdiMedia_EndPicture(VADriverContextP ctx,VAContextID context)4025 VAStatus DdiMedia_EndPicture (
4026     VADriverContextP    ctx,
4027     VAContextID         context
4028 )
4029 {
4030     DDI_FUNCTION_ENTER();
4031 
4032     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
4033 
4034     uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
4035     void     *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType);
4036     VAStatus  vaStatus = VA_STATUS_SUCCESS;
4037     switch (ctxType)
4038     {
4039         case DDI_MEDIA_CONTEXT_TYPE_DECODER:
4040             vaStatus = DdiDecode_EndPicture(ctx, context);
4041             break;
4042         case DDI_MEDIA_CONTEXT_TYPE_ENCODER:
4043             vaStatus = DdiEncode_EndPicture(ctx, context);
4044             break;
4045         case DDI_MEDIA_CONTEXT_TYPE_VP:
4046             vaStatus = DdiVp_EndPicture(ctx, context);
4047             break;
4048         default:
4049             DDI_ASSERTMESSAGE("DDI: unsupported context in DdiCodec_EndPicture.");
4050             vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
4051     }
4052 
4053     MOS_TraceEventExt(EVENT_VA_PICTURE, EVENT_TYPE_END, &context, sizeof(context), &vaStatus, sizeof(vaStatus));
4054     PERF_UTILITY_STOP_ONCE("First Frame Time", PERF_MOS, PERF_LEVEL_DDI);
4055 
4056     return vaStatus;
4057 }
4058 
DdiMedia_StatusCheck(PDDI_MEDIA_CONTEXT mediaCtx,DDI_MEDIA_SURFACE * surface,VASurfaceID surface_id)4059 static VAStatus DdiMedia_StatusCheck (
4060     PDDI_MEDIA_CONTEXT mediaCtx,
4061     DDI_MEDIA_SURFACE  *surface,
4062     VASurfaceID surface_id
4063 )
4064 {
4065     DDI_FUNCTION_ENTER();
4066 
4067     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
4068     DDI_CHK_NULL(surface,  "nullptr surface",  VA_STATUS_ERROR_INVALID_CONTEXT);
4069 
4070     uint32_t i = 0;
4071     PDDI_DECODE_CONTEXT decCtx = (PDDI_DECODE_CONTEXT)surface->pDecCtx;
4072     if (decCtx && surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_DECODER)
4073     {
4074         DdiMediaUtil_LockGuard guard(&mediaCtx->SurfaceMutex);
4075 
4076         Codechal *codecHal = decCtx->pCodecHal;
4077         //return success just avoid vaDestroyContext is ahead of vaSyncSurface
4078         DDI_CHK_NULL(codecHal, "nullptr decCtx->pCodecHal", VA_STATUS_SUCCESS);
4079 
4080         //return success just avoid vaDestroyContext is ahead of vaSyncSurface
4081         if (codecHal->IsApogeiosEnabled())
4082         {
4083             DecodePipelineAdapter *decoder = dynamic_cast<DecodePipelineAdapter *>(codecHal);
4084             DDI_CHK_NULL(decoder, "nullptr (DecodePipelineAdapter *decoder) ", VA_STATUS_SUCCESS);
4085             return DdiDecode_StatusReport(mediaCtx, decoder, surface);
4086         }
4087         else
4088         {
4089             CodechalDecode *decoder = dynamic_cast<CodechalDecode *>(codecHal);
4090             DDI_CHK_NULL(decoder, "nullptr (CodechalDecode *decoder)", VA_STATUS_SUCCESS);
4091             return DdiDecode_StatusReport(mediaCtx, decoder, surface);
4092         }
4093     }
4094 
4095     if (surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_VP)
4096     {
4097         PDDI_VP_CONTEXT vpCtx = (PDDI_VP_CONTEXT)surface->pVpCtx;
4098         DDI_CHK_NULL(vpCtx ,        "nullptr vpCtx",         VA_STATUS_ERROR_INVALID_CONTEXT);
4099         DDI_CHK_NULL(vpCtx->pVpHal ,"nullptr vpCtx->pVpHal", VA_STATUS_ERROR_INVALID_CONTEXT);
4100 
4101         QUERY_STATUS_REPORT_APP tempVpReport;
4102         MOS_ZeroMemory(&tempVpReport, sizeof(QUERY_STATUS_REPORT_APP));
4103 
4104         // Get reported surfaces' count
4105         uint32_t tableLen = 0;
4106         vpCtx->pVpHal->GetStatusReportEntryLength(&tableLen);
4107 
4108         if (tableLen > 0 && surface->curStatusReportQueryState == DDI_MEDIA_STATUS_REPORT_QUERY_STATE_PENDING)
4109         {
4110             // Query the status for all of surfaces which have finished
4111             for(i = 0; i < tableLen; i++)
4112             {
4113                 MOS_ZeroMemory(&tempVpReport, sizeof(QUERY_STATUS_REPORT_APP));
4114                 vpCtx->pVpHal->GetStatusReport(&tempVpReport, 1);
4115 
4116                 // StatusFeedBackID is last time submitted Target Surface ID which is set in BeginPicture,
4117                 // So we can know the report is for which surface here.
4118                 DDI_MEDIA_SURFACE *tempSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, tempVpReport.StatusFeedBackID);
4119                 if(tempSurface == nullptr)
4120                 {
4121                     return VA_STATUS_ERROR_OPERATION_FAILED;
4122                 }
4123 
4124                 // Update the status of the surface which is reported.
4125                 tempSurface->curStatusReport.vpp.status = (uint32_t)tempVpReport.dwStatus;
4126                 tempSurface->curStatusReportQueryState  = DDI_MEDIA_STATUS_REPORT_QUERY_STATE_COMPLETED;
4127 
4128                 if(tempVpReport.StatusFeedBackID == surface_id)
4129                 {
4130                     break;
4131                 }
4132             }
4133         }
4134 
4135         if (surface->curStatusReportQueryState == DDI_MEDIA_STATUS_REPORT_QUERY_STATE_COMPLETED)
4136         {
4137             if(surface->curStatusReport.vpp.status == VPREP_OK)
4138             {
4139                 return VA_STATUS_SUCCESS;
4140             }
4141             else if(surface->curStatusReport.vpp.status == VPREP_NOTREADY)
4142             {
4143                 return mediaCtx->bMediaResetEnable ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_HW_BUSY;
4144             }
4145             else
4146             {
4147                 return VA_STATUS_ERROR_OPERATION_FAILED;
4148             }
4149         }
4150         else
4151         {
4152             return VA_STATUS_ERROR_OPERATION_FAILED;
4153         }
4154     }
4155 
4156     return VA_STATUS_SUCCESS;
4157 
4158 }
4159 
DdiMedia_SyncSurface(VADriverContextP ctx,VASurfaceID render_target)4160 VAStatus DdiMedia_SyncSurface (
4161     VADriverContextP    ctx,
4162     VASurfaceID         render_target
4163 )
4164 {
4165     PERF_UTILITY_AUTO(__FUNCTION__, "ENCODE", "DDI");
4166 
4167     DDI_FUNCTION_ENTER();
4168     MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_START, &render_target, sizeof(VAGenericID), nullptr, 0);
4169 
4170     DDI_CHK_NULL(ctx,    "nullptr ctx",    VA_STATUS_ERROR_INVALID_CONTEXT);
4171 
4172     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
4173     DDI_CHK_NULL(mediaCtx,               "nullptr mediaCtx",               VA_STATUS_ERROR_INVALID_CONTEXT);
4174     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
4175 
4176     DDI_CHK_LESS((uint32_t)render_target, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid render_target", VA_STATUS_ERROR_INVALID_SURFACE);
4177 
4178     DDI_MEDIA_SURFACE  *surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, render_target);
4179     DDI_CHK_NULL(surface,    "nullptr surface",      VA_STATUS_ERROR_INVALID_CONTEXT);
4180     if (surface->pCurrentFrameSemaphore)
4181     {
4182         DdiMediaUtil_WaitSemaphore(surface->pCurrentFrameSemaphore);
4183         DdiMediaUtil_PostSemaphore(surface->pCurrentFrameSemaphore);
4184     }
4185 
4186     MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_INFO, surface->bo? &surface->bo->handle:nullptr, sizeof(uint32_t), nullptr, 0);
4187     // check the bo here?
4188     // zero is a expected return value
4189     uint32_t timeout_NS = 100000000;
4190     while (0 != mos_bo_wait(surface->bo, timeout_NS))
4191     {
4192         // Just loop while gem_bo_wait times-out.
4193     }
4194 
4195     MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
4196     return DdiMedia_StatusCheck(mediaCtx, surface, render_target);
4197 }
4198 
4199 #if VA_CHECK_VERSION(1, 9, 0)
DdiMedia_SyncSurface2(VADriverContextP ctx,VASurfaceID surface_id,uint64_t timeout_ns)4200 VAStatus DdiMedia_SyncSurface2 (
4201     VADriverContextP    ctx,
4202     VASurfaceID         surface_id,
4203     uint64_t            timeout_ns
4204 )
4205 {
4206     PERF_UTILITY_AUTO(__FUNCTION__, "ENCODE", "DDI");
4207 
4208     DDI_FUNCTION_ENTER();
4209     MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_START, &surface_id, sizeof(VAGenericID), nullptr, 0);
4210 
4211     DDI_CHK_NULL(ctx,    "nullptr ctx",    VA_STATUS_ERROR_INVALID_CONTEXT);
4212 
4213     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
4214     DDI_CHK_NULL(mediaCtx,               "nullptr mediaCtx",               VA_STATUS_ERROR_INVALID_CONTEXT);
4215     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
4216 
4217     DDI_CHK_LESS((uint32_t)surface_id, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid render_target", VA_STATUS_ERROR_INVALID_SURFACE);
4218 
4219     DDI_MEDIA_SURFACE  *surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface_id);
4220     DDI_CHK_NULL(surface,    "nullptr surface",      VA_STATUS_ERROR_INVALID_CONTEXT);
4221     if (surface->pCurrentFrameSemaphore)
4222     {
4223         DdiMediaUtil_WaitSemaphore(surface->pCurrentFrameSemaphore);
4224         DdiMediaUtil_PostSemaphore(surface->pCurrentFrameSemaphore);
4225     }
4226     MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_INFO, surface->bo? &surface->bo->handle:nullptr, sizeof(uint32_t), nullptr, 0);
4227 
4228     if (timeout_ns == VA_TIMEOUT_INFINITE)
4229     {
4230         // zero is an expected return value when not hit timeout
4231         auto ret = mos_bo_wait(surface->bo, DDI_BO_INFINITE_TIMEOUT);
4232         if (0 != ret)
4233         {
4234             DDI_NORMALMESSAGE("vaSyncSurface2: surface is still used by HW\n\r");
4235             return VA_STATUS_ERROR_TIMEDOUT;
4236         }
4237     }
4238     else
4239     {
4240         int64_t timeoutBoWait1 = 0;
4241         int64_t timeoutBoWait2 = 0;
4242         if (timeout_ns >= DDI_BO_MAX_TIMEOUT)
4243         {
4244             timeoutBoWait1 = DDI_BO_MAX_TIMEOUT - 1;
4245             timeoutBoWait2 = timeout_ns - DDI_BO_MAX_TIMEOUT + 1;
4246         }
4247         else
4248         {
4249             timeoutBoWait1 = (int64_t)timeout_ns;
4250         }
4251 
4252         // zero is an expected return value when not hit timeout
4253         auto ret = mos_bo_wait(surface->bo, timeoutBoWait1);
4254         if (0 != ret)
4255         {
4256             if (timeoutBoWait2)
4257             {
4258                 ret = mos_bo_wait(surface->bo, timeoutBoWait2);
4259             }
4260             if (0 != ret)
4261             {
4262                 DDI_NORMALMESSAGE("vaSyncSurface2: surface is still used by HW\n\r");
4263                 return VA_STATUS_ERROR_TIMEDOUT;
4264             }
4265         }
4266     }
4267     MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
4268     return DdiMedia_StatusCheck(mediaCtx, surface, surface_id);
4269 }
4270 
DdiMedia_SyncBuffer(VADriverContextP ctx,VABufferID buf_id,uint64_t timeout_ns)4271 VAStatus DdiMedia_SyncBuffer (
4272     VADriverContextP    ctx,
4273     VABufferID          buf_id,
4274     uint64_t            timeout_ns
4275 )
4276 {
4277     PERF_UTILITY_AUTO(__FUNCTION__, "ENCODE", "DDI");
4278 
4279     DDI_FUNCTION_ENTER();
4280     MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_START, &buf_id, sizeof(buf_id), nullptr, 0);
4281 
4282     DDI_CHK_NULL(ctx,    "nullptr ctx",    VA_STATUS_ERROR_INVALID_CONTEXT);
4283 
4284     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
4285     DDI_CHK_NULL(mediaCtx,               "nullptr mediaCtx",               VA_STATUS_ERROR_INVALID_CONTEXT);
4286     DDI_CHK_NULL(mediaCtx->pBufferHeap,  "nullptr mediaCtx->pBufferHeap",  VA_STATUS_ERROR_INVALID_CONTEXT);
4287 
4288     DDI_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid buffer", VA_STATUS_ERROR_INVALID_BUFFER);
4289 
4290     DDI_MEDIA_BUFFER  *buffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id);
4291     DDI_CHK_NULL(buffer,    "nullptr buffer",      VA_STATUS_ERROR_INVALID_CONTEXT);
4292 
4293     MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_INFO, buffer->bo? &buffer->bo->handle:nullptr, sizeof(uint32_t), nullptr, 0);
4294     if (timeout_ns == VA_TIMEOUT_INFINITE)
4295     {
4296         // zero is a expected return value when not hit timeout
4297         auto ret = mos_bo_wait(buffer->bo, DDI_BO_INFINITE_TIMEOUT);
4298         if (0 != ret)
4299         {
4300             DDI_NORMALMESSAGE("vaSyncBuffer: buffer is still used by HW\n\r");
4301             return VA_STATUS_ERROR_TIMEDOUT;
4302         }
4303     }
4304     else
4305     {
4306         int64_t timeoutBoWait1 = 0;
4307         int64_t timeoutBoWait2 = 0;
4308         if (timeout_ns >= DDI_BO_MAX_TIMEOUT)
4309         {
4310             timeoutBoWait1 = DDI_BO_MAX_TIMEOUT - 1;
4311             timeoutBoWait2 = timeout_ns - DDI_BO_MAX_TIMEOUT + 1;
4312         }
4313         else
4314         {
4315             timeoutBoWait1 = (int64_t)timeout_ns;
4316         }
4317 
4318         // zero is a expected return value when not hit timeout
4319         auto ret = mos_bo_wait(buffer->bo, timeoutBoWait1);
4320         if (0 != ret)
4321         {
4322             if (timeoutBoWait2)
4323             {
4324                 ret = mos_bo_wait(buffer->bo, timeoutBoWait2);
4325             }
4326             if (0 != ret)
4327             {
4328                 DDI_NORMALMESSAGE("vaSyncBuffer: buffer is still used by HW\n\r");
4329                 return VA_STATUS_ERROR_TIMEDOUT;
4330             }
4331         }
4332     }
4333     MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
4334     return VA_STATUS_SUCCESS;
4335 }
4336 #endif
4337 
DdiMedia_QuerySurfaceStatus(VADriverContextP ctx,VASurfaceID render_target,VASurfaceStatus * status)4338 VAStatus DdiMedia_QuerySurfaceStatus (
4339     VADriverContextP    ctx,
4340     VASurfaceID         render_target,
4341     VASurfaceStatus    *status
4342 )
4343 {
4344     DDI_FUNCTION_ENTER();
4345 
4346     DDI_CHK_NULL(ctx,    "nullptr ctx",    VA_STATUS_ERROR_INVALID_CONTEXT);
4347     DDI_CHK_NULL(status, "nullptr status", VA_STATUS_ERROR_INVALID_PARAMETER);
4348 
4349     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
4350     DDI_CHK_NULL(mediaCtx,                  "nullptr mediaCtx",               VA_STATUS_ERROR_INVALID_CONTEXT);
4351     DDI_CHK_NULL(mediaCtx->pSurfaceHeap,    "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
4352 
4353     DDI_CHK_LESS((uint32_t)render_target, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid render_target", VA_STATUS_ERROR_INVALID_SURFACE);
4354     DDI_MEDIA_SURFACE *surface   = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, render_target);
4355     DDI_CHK_NULL(surface,    "nullptr surface",    VA_STATUS_ERROR_INVALID_SURFACE);
4356 
4357     if (surface->pCurrentFrameSemaphore)
4358     {
4359         if(DdiMediaUtil_TryWaitSemaphore(surface->pCurrentFrameSemaphore) == 0)
4360         {
4361             DdiMediaUtil_PostSemaphore(surface->pCurrentFrameSemaphore);
4362         }
4363         else
4364         {
4365             // Return busy state if the surface is not submitted
4366             *status = VASurfaceRendering;
4367             return VA_STATUS_SUCCESS;
4368         }
4369     }
4370 
4371     // Query the busy state of bo.
4372     // check the bo here?
4373     if(mos_bo_busy(surface->bo))
4374     {
4375         // busy
4376         *status = VASurfaceRendering;
4377     }
4378     else
4379     {
4380         // idle
4381         *status = VASurfaceReady;
4382     }
4383 
4384     return VA_STATUS_SUCCESS;
4385 }
4386 
DdiMedia_QuerySurfaceError(VADriverContextP ctx,VASurfaceID render_target,VAStatus error_status,void ** error_info)4387 VAStatus DdiMedia_QuerySurfaceError(
4388     VADriverContextP ctx,
4389     VASurfaceID      render_target,
4390     VAStatus         error_status,
4391     void             **error_info /*out*/
4392 )
4393 {
4394     DDI_UNUSED(error_status);
4395 
4396     DDI_FUNCTION_ENTER();
4397 
4398     DDI_CHK_NULL( ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT );
4399 
4400     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
4401     DDI_CHK_NULL( mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
4402 
4403     DDI_MEDIA_SURFACE *surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, render_target);
4404     DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
4405 
4406     PDDI_DECODE_CONTEXT decCtx = (PDDI_DECODE_CONTEXT)surface->pDecCtx;
4407     DDI_CHK_NULL( decCtx, "nullptr surface->pDecCtx", VA_STATUS_ERROR_INVALID_CONTEXT );
4408 
4409     VASurfaceDecodeMBErrors *surfaceErrors   = decCtx->vaSurfDecErrOutput;
4410     DDI_CHK_NULL(surfaceErrors , "nullptr surfaceErrors", VA_STATUS_ERROR_INVALID_CONTEXT );
4411 
4412     VAStatus vaStatus = VA_STATUS_SUCCESS;
4413 
4414     DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
4415     if (surface->curStatusReportQueryState == DDI_MEDIA_STATUS_REPORT_QUERY_STATE_COMPLETED)
4416     {
4417         if (error_status != -1 && surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_DECODER)
4418         {
4419             if (surface->curStatusReport.decode.status == CODECHAL_STATUS_ERROR ||
4420                 surface->curStatusReport.decode.status == CODECHAL_STATUS_RESET)
4421             {
4422                 surfaceErrors[1].status            = -1;
4423                 surfaceErrors[0].status            = 1;
4424                 surfaceErrors[0].start_mb          = 0;
4425                 surfaceErrors[0].end_mb            = 0;
4426                 surfaceErrors[0].num_mb            = surface->curStatusReport.decode.errMbNum;
4427 #if VA_CHECK_VERSION(1, 20, 0)
4428                 surfaceErrors[0].decode_error_type = (surface->curStatusReport.decode.status == CODECHAL_STATUS_RESET) ? VADecodeReset : VADecodeMBError;
4429 #else
4430                 surfaceErrors[0].decode_error_type = VADecodeMBError;
4431 #endif
4432                 *error_info = surfaceErrors;
4433                 DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
4434                 return VA_STATUS_SUCCESS;
4435             }
4436 #if VA_CHECK_VERSION(1, 20, 0)
4437             else if (surface->curStatusReport.decode.status == CODECHAL_STATUS_INCOMPLETE  ||
4438                      surface->curStatusReport.decode.status == CODECHAL_STATUS_UNAVAILABLE)
4439             {
4440                 MOS_ZeroMemory(&surfaceErrors[0], sizeof(VASurfaceDecodeMBErrors));
4441                 surfaceErrors[1].status            = -1;
4442                 surfaceErrors[0].status            = 1;
4443                 surfaceErrors[0].decode_error_type = VADecodeReset;
4444                 *error_info                        = surfaceErrors;
4445                 DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
4446                 return VA_STATUS_SUCCESS;
4447             }
4448 #endif
4449         }
4450 
4451         if (error_status == -1 && surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_DECODER)
4452             //&& surface->curStatusReport.decode.status == CODECHAL_STATUS_SUCCESSFUL)  // get the crc value whatever the status is
4453         {
4454             CodechalDecode *decoder = dynamic_cast<CodechalDecode *>(decCtx->pCodecHal);
4455 
4456             if (nullptr == decoder)
4457             {
4458                 DDI_ASSERTMESSAGE("nullptr codechal decoder");
4459                 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
4460             }
4461             else
4462             {
4463                 if (decoder->GetStandard() != CODECHAL_AVC)
4464                 {
4465                     vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
4466                 }
4467                 else
4468                 {
4469                     *error_info = (void *)&surface->curStatusReport.decode.crcValue;
4470                 }
4471             }
4472 
4473             DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
4474             return vaStatus;
4475         }
4476 
4477         if (surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_VP &&
4478             surface->curStatusReport.vpp.status == CODECHAL_STATUS_ERROR)
4479         {
4480             DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
4481             return VA_STATUS_SUCCESS;
4482         }
4483     }
4484 
4485     surfaceErrors[0].status = -1;
4486     DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
4487     return VA_STATUS_SUCCESS;
4488 }
4489 
DdiMedia_QuerySurfaceAttributes(VADriverContextP ctx,VAConfigID config_id,VASurfaceAttrib * attrib_list,uint32_t * num_attribs)4490 VAStatus DdiMedia_QuerySurfaceAttributes(
4491     VADriverContextP ctx,
4492     VAConfigID config_id,
4493     VASurfaceAttrib *attrib_list,
4494     uint32_t *num_attribs
4495 )
4496 {
4497     DDI_FUNCTION_ENTER();
4498 
4499     DDI_CHK_NULL(ctx,         "nullptr ctx",         VA_STATUS_ERROR_INVALID_CONTEXT);
4500     DDI_CHK_NULL(num_attribs, "nullptr num_attribs", VA_STATUS_ERROR_INVALID_PARAMETER);
4501 
4502     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
4503     DDI_CHK_NULL(mediaCtx,   "nullptr mediaCtx",   VA_STATUS_ERROR_INVALID_CONTEXT);
4504     DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
4505 
4506     return mediaCtx->m_caps->QuerySurfaceAttributes(config_id,
4507             attrib_list, num_attribs);
4508 }
4509 
DdiMedia_PutSurface(VADriverContextP ctx,VASurfaceID surface,void * draw,int16_t srcx,int16_t srcy,uint16_t srcw,uint16_t srch,int16_t destx,int16_t desty,uint16_t destw,uint16_t desth,VARectangle * cliprects,uint32_t number_cliprects,uint32_t flags)4510 VAStatus DdiMedia_PutSurface(
4511     VADriverContextP ctx,
4512     VASurfaceID      surface,
4513     void*            draw,
4514     int16_t          srcx,
4515     int16_t          srcy,
4516     uint16_t         srcw,
4517     uint16_t         srch,
4518     int16_t          destx,
4519     int16_t          desty,
4520     uint16_t         destw,
4521     uint16_t         desth,
4522     VARectangle     *cliprects,        /* client supplied clip list */
4523     uint32_t         number_cliprects, /* number of clip rects in the clip list */
4524     uint32_t         flags             /* de-interlacing flags */
4525 )
4526 {
4527     DDI_FUNCTION_ENTER();
4528 
4529     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_PARAMETER);
4530     if(number_cliprects > 0)
4531     {
4532         DDI_CHK_NULL(cliprects, "nullptr cliprects", VA_STATUS_ERROR_INVALID_PARAMETER);
4533     }
4534 
4535     void               *vpCtx        = nullptr;
4536     PDDI_MEDIA_CONTEXT mediaDrvCtx   = DdiMedia_GetMediaContext(ctx);
4537 
4538     DDI_CHK_NULL(mediaDrvCtx,               "nullptr mediaDrvCtx",               VA_STATUS_ERROR_INVALID_CONTEXT);
4539     DDI_CHK_NULL(mediaDrvCtx->pSurfaceHeap, "nullptr mediaDrvCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
4540 
4541     DDI_CHK_LESS((uint32_t)surface, mediaDrvCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface", VA_STATUS_ERROR_INVALID_SURFACE);
4542 
4543     if (nullptr != mediaDrvCtx->pVpCtxHeap->pHeapBase)
4544     {
4545         uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
4546         vpCtx = DdiMedia_GetContextFromContextID(ctx, (VAContextID)(0 + DDI_MEDIA_VACONTEXTID_OFFSET_VP), &ctxType);
4547     }
4548 
4549 #if defined(ANDROID) || !defined(X11_FOUND)
4550        return VA_STATUS_ERROR_UNIMPLEMENTED;
4551 #else
4552     if(nullptr == vpCtx)
4553     {
4554         VAContextID context = VA_INVALID_ID;
4555         VAStatus vaStatus = DdiVp_CreateContext(ctx, 0, 0, 0, 0, 0, 0, &context);
4556         DDI_CHK_RET(vaStatus, "Create VP Context failed");
4557     }
4558     return DdiCodec_PutSurfaceLinuxHW(ctx, surface, draw, srcx, srcy, srcw, srch, destx, desty, destw, desth, cliprects, number_cliprects, flags);
4559 #endif
4560 
4561 }
4562 
DdiMedia_QueryImageFormats(VADriverContextP ctx,VAImageFormat * format_list,int32_t * num_formats)4563 VAStatus DdiMedia_QueryImageFormats (
4564     VADriverContextP    ctx,
4565     VAImageFormat      *format_list,
4566     int32_t            *num_formats
4567 )
4568 {
4569     DDI_FUNCTION_ENTER();
4570 
4571     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
4572     DDI_CHK_NULL(mediaCtx,   "nullptr mediaCtx.",   VA_STATUS_ERROR_INVALID_PARAMETER);
4573     DDI_CHK_NULL(mediaCtx->m_caps,   "nullptr pointer.",   VA_STATUS_ERROR_INVALID_PARAMETER);
4574     return mediaCtx->m_caps->QueryImageFormats(format_list, num_formats);
4575 }
4576 
DdiMedia_CreateImage(VADriverContextP ctx,VAImageFormat * format,int32_t width,int32_t height,VAImage * image)4577 VAStatus DdiMedia_CreateImage(
4578     VADriverContextP ctx,
4579     VAImageFormat   *format,
4580     int32_t          width,
4581     int32_t          height,
4582     VAImage         *image     /* out */
4583 )
4584 {
4585     DDI_FUNCTION_ENTER();
4586 
4587     DDI_CHK_NULL(ctx,         "Invalid context!",    VA_STATUS_ERROR_INVALID_CONTEXT);
4588     DDI_CHK_NULL(format,      "Invalid format!",     VA_STATUS_ERROR_INVALID_PARAMETER);
4589     DDI_CHK_NULL(image,       "Invalid image!",      VA_STATUS_ERROR_INVALID_PARAMETER);
4590     DDI_CHK_LARGER(width,  0, "Invalid width!",      VA_STATUS_ERROR_INVALID_PARAMETER);
4591     DDI_CHK_LARGER(height, 0, "Invalid height!",     VA_STATUS_ERROR_INVALID_PARAMETER);
4592     int32_t event[] = {width, height, format->fourcc};
4593     MOS_TraceEventExt(EVENT_VA_IMAGE, EVENT_TYPE_START, event, sizeof(event), nullptr, 0);
4594 
4595     PDDI_MEDIA_CONTEXT mediaCtx        = DdiMedia_GetMediaContext(ctx);
4596     DDI_CHK_NULL(mediaCtx,   "nullptr mediaCtx.",   VA_STATUS_ERROR_INVALID_PARAMETER);
4597     DDI_CHK_NULL(mediaCtx->pGmmClientContext, "nullptr mediaCtx->pGmmClientContext.", VA_STATUS_ERROR_INVALID_PARAMETER);
4598 
4599     VAImage *vaimg           = (VAImage*)MOS_AllocAndZeroMemory(sizeof(VAImage));
4600     DDI_CHK_NULL(vaimg,  "Insufficient to allocate an VAImage.",  VA_STATUS_ERROR_ALLOCATION_FAILED);
4601 
4602     GMM_RESCREATE_PARAMS        gmmParams;
4603     GMM_RESOURCE_INFO          *gmmResourceInfo;
4604     MOS_ZeroMemory(&gmmParams, sizeof(gmmParams));
4605 
4606     gmmParams.BaseWidth         = width;
4607     gmmParams.BaseHeight        = height;
4608     gmmParams.ArraySize         = 1;
4609     gmmParams.Type              = RESOURCE_2D;
4610     gmmParams.Flags.Gpu.Video   = true;
4611     gmmParams.Format            = mediaCtx->m_caps->ConvertFourccToGmmFmt(format->fourcc);
4612     gmmParams.Flags.Info.Linear = 1;
4613 
4614     if (gmmParams.Format == GMM_FORMAT_INVALID)
4615     {
4616         MOS_FreeMemory(vaimg);
4617         return VA_STATUS_ERROR_UNIMPLEMENTED;
4618     }
4619     gmmResourceInfo = mediaCtx->pGmmClientContext->CreateResInfoObject(&gmmParams);
4620     if(nullptr == gmmResourceInfo)
4621     {
4622         DDI_ASSERTMESSAGE("Gmm Create Resource Failed.");
4623         MOS_FreeMemory(vaimg);
4624         return VA_STATUS_ERROR_ALLOCATION_FAILED;
4625     }
4626 
4627     // Get offset from GMM
4628     GMM_REQ_OFFSET_INFO reqInfo = {0};
4629     reqInfo.Plane               = GMM_PLANE_U;
4630     reqInfo.ReqRender           = 1;
4631     gmmResourceInfo->GetOffset(reqInfo);
4632     uint32_t offsetU            = reqInfo.Render.Offset;
4633     MOS_ZeroMemory(&reqInfo, sizeof(GMM_REQ_OFFSET_INFO));
4634     reqInfo.Plane               = GMM_PLANE_V;
4635     reqInfo.ReqRender           = 1;
4636     gmmResourceInfo->GetOffset(reqInfo);
4637     uint32_t offsetV            = reqInfo.Render.Offset;
4638     uint32_t size               = (uint32_t)gmmResourceInfo->GetSizeSurface();
4639     uint32_t pitch              = (uint32_t)gmmResourceInfo->GetRenderPitch();
4640     vaimg->format               = *format;
4641     vaimg->format.byte_order    = VA_LSB_FIRST;
4642     vaimg->width                = width;
4643     vaimg->height               = height;
4644     vaimg->data_size            = size;
4645 
4646     mediaCtx->pGmmClientContext->DestroyResInfoObject(gmmResourceInfo);
4647 
4648      switch(format->fourcc)
4649     {
4650         case VA_FOURCC_RGBA:
4651         case VA_FOURCC_BGRA:
4652         case VA_FOURCC_ARGB:
4653         case VA_FOURCC_ABGR:
4654         case VA_FOURCC_BGRX:
4655         case VA_FOURCC_RGBX:
4656         case VA_FOURCC_XRGB:
4657         case VA_FOURCC_XBGR:
4658         case VA_FOURCC_A2R10G10B10:
4659         case VA_FOURCC_A2B10G10R10:
4660         case VA_FOURCC_X2R10G10B10:
4661         case VA_FOURCC_X2B10G10R10:
4662         case VA_FOURCC_R8G8B8:
4663         case VA_FOURCC_RGB565:
4664         case VA_FOURCC_UYVY:
4665         case VA_FOURCC_YUY2:
4666         case VA_FOURCC_VYUY:
4667         case VA_FOURCC_YVYU:
4668         case VA_FOURCC_AYUV:
4669 #if VA_CHECK_VERSION(1, 13, 0)
4670         case VA_FOURCC_XYUV:
4671 #endif
4672         case VA_FOURCC_Y210:
4673 #if VA_CHECK_VERSION(1, 9, 0)
4674         case VA_FOURCC_Y212:
4675 #endif
4676         case VA_FOURCC_Y216:
4677         case VA_FOURCC_Y410:
4678 #if VA_CHECK_VERSION(1, 9, 0)
4679         case VA_FOURCC_Y412:
4680 #endif
4681         case VA_FOURCC_Y416:
4682         case VA_FOURCC_Y800:
4683             vaimg->num_planes = 1;
4684             vaimg->pitches[0] = pitch;
4685             vaimg->offsets[0] = 0;
4686             break;
4687         case VA_FOURCC_NV12:
4688         case VA_FOURCC_NV21:
4689         case VA_FOURCC_P010:
4690         case VA_FOURCC_P012:
4691         case VA_FOURCC_P016:
4692             vaimg->num_planes = 2;
4693             vaimg->pitches[0] = pitch;
4694             vaimg->pitches[1] = pitch;
4695             vaimg->offsets[0] = 0;
4696             vaimg->offsets[1] = offsetU;
4697             if (height % 2 == 1)
4698             {
4699                 vaimg->data_size += pitch;
4700             }
4701             break;
4702         case VA_FOURCC_YV12:
4703             vaimg->num_planes = 3;
4704             vaimg->pitches[0] = pitch;
4705             vaimg->pitches[1] = pitch / 2;
4706             vaimg->pitches[2] = pitch / 2;
4707             vaimg->offsets[0] = 0;
4708             vaimg->offsets[1] = offsetV;
4709             vaimg->offsets[2] = offsetU;
4710             break;
4711         case VA_FOURCC_I420:
4712             vaimg->num_planes = 3;
4713             vaimg->pitches[0] = pitch;
4714             vaimg->pitches[1] = pitch / 2;
4715             vaimg->pitches[2] = pitch / 2;
4716             vaimg->offsets[0] = 0;
4717             vaimg->offsets[1] = offsetU;
4718             vaimg->offsets[2] = offsetV;
4719             break;
4720         case VA_FOURCC_IMC3:
4721         case VA_FOURCC_411P:
4722         case VA_FOURCC_422V:
4723         case VA_FOURCC_422H:
4724         case VA_FOURCC_444P:
4725         case VA_FOURCC_RGBP:
4726         case VA_FOURCC_BGRP:
4727             vaimg->num_planes = 3;
4728             vaimg->pitches[0] = pitch;
4729             vaimg->pitches[1] = pitch;
4730             vaimg->pitches[2] = pitch;
4731             vaimg->offsets[0] = 0;
4732             vaimg->offsets[1] = offsetU;
4733             vaimg->offsets[2] = offsetV;
4734             break;
4735         default:
4736             MOS_FreeMemory(vaimg);
4737             return VA_STATUS_ERROR_UNIMPLEMENTED;
4738     }
4739 
4740     DDI_MEDIA_BUFFER *buf  = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
4741     if (nullptr == buf)
4742     {
4743         MOS_FreeMemory(vaimg);
4744         return VA_STATUS_ERROR_ALLOCATION_FAILED;
4745     }
4746     buf->uiNumElements     = 1;
4747     buf->iSize             = vaimg->data_size;
4748     buf->uiType            = VAImageBufferType;
4749     buf->format            = Media_Format_CPU;//DdiCodec_OsFormatToMediaFormat(vaimg->format.fourcc); //Media_Format_Buffer;
4750     buf->uiOffset          = 0;
4751     buf->pMediaCtx         = mediaCtx;
4752 
4753     //Put Image in untiled buffer for better CPU access?
4754     VAStatus status= DdiMediaUtil_CreateBuffer(buf,  mediaCtx->pDrmBufMgr);
4755     if((status != VA_STATUS_SUCCESS))
4756     {
4757         MOS_FreeMemory(vaimg);
4758         MOS_FreeMemory(buf);
4759         return status;
4760     }
4761     buf->TileType     = TILING_NONE;
4762 
4763     DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
4764     PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufferHeapElement  = DdiMediaUtil_AllocPMediaBufferFromHeap(mediaCtx->pBufferHeap);
4765 
4766     if (nullptr == bufferHeapElement)
4767     {
4768         DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
4769         MOS_FreeMemory(vaimg);
4770         DdiMediaUtil_FreeBuffer(buf);
4771         MOS_FreeMemory(buf);
4772         return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4773     }
4774 
4775     bufferHeapElement->pBuffer   = buf;
4776     bufferHeapElement->pCtx      = nullptr;
4777     bufferHeapElement->uiCtxType = DDI_MEDIA_CONTEXT_TYPE_MEDIA;
4778 
4779     vaimg->buf                   = bufferHeapElement->uiVaBufferID;
4780     mediaCtx->uiNumBufs++;
4781     DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
4782 
4783     DdiMediaUtil_LockMutex(&mediaCtx->ImageMutex);
4784     PDDI_MEDIA_IMAGE_HEAP_ELEMENT imageHeapElement = DdiMediaUtil_AllocPVAImageFromHeap(mediaCtx->pImageHeap);
4785     if (nullptr == imageHeapElement)
4786     {
4787         DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex);
4788         MOS_FreeMemory(vaimg);
4789         return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4790     }
4791     imageHeapElement->pImage     = vaimg;
4792     mediaCtx->uiNumImages++;
4793     vaimg->image_id              = imageHeapElement->uiVaImageID;
4794     DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex);
4795 
4796    *image = *vaimg;
4797     MOS_TraceEventExt(EVENT_VA_IMAGE, EVENT_TYPE_END, &vaimg->image_id, sizeof(VAGenericID), nullptr, 0);
4798     return VA_STATUS_SUCCESS;
4799 }
4800 
4801 //!
4802 //! \brief  Derive image
4803 //!
4804 //! \param  [in] ctx
4805 //!         Pointer to VA driver context
4806 //! \param  [in] surface
4807 //!         VA surface ID
4808 //! \param  [in] image
4809 //!         VA image
4810 //!
4811 //! \return VAStatus
4812 //!     VA_STATUS_SUCCESS if success, else fail reason
4813 //!
DdiMedia_DeriveImage(VADriverContextP ctx,VASurfaceID surface,VAImage * image)4814 VAStatus DdiMedia_DeriveImage (
4815     VADriverContextP  ctx,
4816     VASurfaceID       surface,
4817     VAImage           *image
4818 )
4819 {
4820     DDI_FUNCTION_ENTER();
4821     MOS_TraceEventExt(EVENT_VA_DERIVE, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
4822 
4823     DDI_CHK_NULL(ctx,   "nullptr ctx",   VA_STATUS_ERROR_INVALID_CONTEXT);
4824     DDI_CHK_NULL(image, "nullptr image", VA_STATUS_ERROR_INVALID_PARAMETER);
4825 
4826     PDDI_MEDIA_CONTEXT mediaCtx     = DdiMedia_GetMediaContext(ctx);
4827     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
4828 
4829     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
4830     DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface", VA_STATUS_ERROR_INVALID_SURFACE);
4831 
4832     DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface);
4833     DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface", VA_STATUS_ERROR_INVALID_SURFACE);
4834 
4835     VAImage *vaimg                  = (VAImage*)MOS_AllocAndZeroMemory(sizeof(VAImage));
4836     DDI_CHK_NULL(vaimg, "nullptr vaimg", VA_STATUS_ERROR_ALLOCATION_FAILED);
4837 
4838     if (mediaSurface->pCurrentFrameSemaphore)
4839     {
4840         DdiMediaUtil_WaitSemaphore(mediaSurface->pCurrentFrameSemaphore);
4841         DdiMediaUtil_PostSemaphore(mediaSurface->pCurrentFrameSemaphore);
4842     }
4843     DdiMediaUtil_LockMutex(&mediaCtx->ImageMutex);
4844     PDDI_MEDIA_IMAGE_HEAP_ELEMENT imageHeapElement = DdiMediaUtil_AllocPVAImageFromHeap(mediaCtx->pImageHeap);
4845     if (nullptr == imageHeapElement)
4846     {
4847         DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex);
4848         MOS_FreeMemory(vaimg);
4849         return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4850     }
4851     imageHeapElement->pImage        = vaimg;
4852     mediaCtx->uiNumImages++;
4853     vaimg->image_id                 = imageHeapElement->uiVaImageID;
4854     DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex);
4855 
4856     vaimg->format.fourcc            = DdiMedia_MediaFormatToOsFormat(mediaSurface->format);
4857     vaimg->width                    = mediaSurface->iWidth;
4858     vaimg->height                   = mediaSurface->iRealHeight;
4859     vaimg->format.byte_order        = VA_LSB_FIRST;
4860 
4861     GMM_RESOURCE_INFO          *gmmResourceInfo = mediaSurface->pGmmResourceInfo;
4862     GMM_REQ_OFFSET_INFO reqInfo     = {0};
4863     reqInfo.Plane                   = GMM_PLANE_U;
4864     reqInfo.ReqRender               = 1;
4865     gmmResourceInfo->GetOffset(reqInfo);
4866     uint32_t offsetU                = reqInfo.Render.Offset;
4867     MOS_ZeroMemory(&reqInfo, sizeof(GMM_REQ_OFFSET_INFO));
4868     reqInfo.Plane                   = GMM_PLANE_V;
4869     reqInfo.ReqRender               = 1;
4870     gmmResourceInfo->GetOffset(reqInfo);
4871     uint32_t offsetV                = reqInfo.Render.Offset;
4872     vaimg->data_size                = (uint32_t)gmmResourceInfo->GetSizeSurface();
4873 
4874     switch( mediaSurface->format )
4875     {
4876     case Media_Format_YV12:
4877     case Media_Format_I420:
4878     case Media_Format_IYUV:
4879         vaimg->format.bits_per_pixel    = 12;
4880         vaimg->num_planes               = 3;
4881         vaimg->pitches[0]               = mediaSurface->iPitch;
4882         vaimg->pitches[1]               =
4883         vaimg->pitches[2]               = mediaSurface->iPitch / 2;
4884         vaimg->offsets[0]               = 0;
4885         vaimg->offsets[1]               = mediaSurface->iHeight * mediaSurface->iPitch;
4886         vaimg->offsets[2]               = vaimg->offsets[1] + vaimg->pitches[1] * MOS_ALIGN_CEIL(mediaSurface->iHeight, 2) / 2;
4887         break;
4888     case Media_Format_A8B8G8R8:
4889     case Media_Format_R8G8B8A8:
4890     case Media_Format_A8R8G8B8:
4891         vaimg->format.bits_per_pixel    = 32;
4892         vaimg->format.alpha_mask        = RGB_8BIT_ALPHAMASK;
4893         vaimg->num_planes               = 1;
4894         vaimg->pitches[0]               = mediaSurface->iPitch;
4895         vaimg->offsets[0]               = 0;
4896         break;
4897     case Media_Format_X8R8G8B8:
4898     case Media_Format_X8B8G8R8:
4899         vaimg->format.bits_per_pixel    = 32;
4900         vaimg->num_planes               = 1;
4901         vaimg->pitches[0]               = mediaSurface->iPitch;
4902         vaimg->offsets[0]               = 0;
4903         break;
4904     case Media_Format_R10G10B10A2:
4905     case Media_Format_B10G10R10A2:
4906         vaimg->format.bits_per_pixel    = 32;
4907         vaimg->format.alpha_mask        = RGB_10BIT_ALPHAMASK;
4908         vaimg->num_planes               = 1;
4909         vaimg->pitches[0]               = mediaSurface->iPitch;
4910         vaimg->offsets[0]               = 0;
4911         break;
4912     case Media_Format_R10G10B10X2:
4913     case Media_Format_B10G10R10X2:
4914         vaimg->format.bits_per_pixel    = 32;
4915         vaimg->num_planes               = 1;
4916         vaimg->pitches[0]               = mediaSurface->iPitch;
4917         vaimg->offsets[0]               = 0;
4918         break;
4919     case Media_Format_R5G6B5:
4920         vaimg->format.bits_per_pixel    = 16;
4921         vaimg->data_size                = mediaSurface->iPitch * mediaSurface->iHeight;
4922         vaimg->num_planes               = 1;
4923         vaimg->pitches[0]               = mediaSurface->iPitch;
4924         vaimg->offsets[0]               = 0;
4925         break;
4926     case Media_Format_R8G8B8:
4927         vaimg->format.bits_per_pixel    = 24;
4928         vaimg->num_planes               = 1;
4929         vaimg->pitches[0]               = mediaSurface->iPitch;
4930         vaimg->offsets[0]               = 0;
4931         break;
4932     case Media_Format_YUY2:
4933     case Media_Format_UYVY:
4934         vaimg->format.bits_per_pixel    = 16;
4935         vaimg->data_size                = mediaSurface->iPitch * mediaSurface->iHeight;
4936         vaimg->num_planes               = 1;
4937         vaimg->pitches[0]               = mediaSurface->iPitch;
4938         vaimg->offsets[0]               = 0;
4939         break;
4940     case Media_Format_400P:
4941         vaimg->format.bits_per_pixel    = 8;
4942         vaimg->num_planes               = 1;
4943         vaimg->pitches[0]               = mediaSurface->iPitch;
4944         vaimg->offsets[0]               = 0;
4945         break;
4946     case Media_Format_444P:
4947     case Media_Format_RGBP:
4948     case Media_Format_BGRP:
4949         vaimg->format.bits_per_pixel    = 24;
4950         vaimg->num_planes               = 3;
4951         vaimg->pitches[0]               =
4952         vaimg->pitches[1]               =
4953         vaimg->pitches[2]               = mediaSurface->iPitch;
4954         vaimg->offsets[0]               = 0;
4955         vaimg->offsets[1]               = mediaSurface->iHeight * mediaSurface->iPitch;
4956         vaimg->offsets[2]               = mediaSurface->iHeight * mediaSurface->iPitch * 2;
4957         break;
4958     case Media_Format_IMC3:
4959         vaimg->format.bits_per_pixel    = 12;
4960         vaimg->num_planes               = 3;
4961         vaimg->pitches[0]               =
4962         vaimg->pitches[1]               =
4963         vaimg->pitches[2]               = mediaSurface->iPitch;
4964         vaimg->offsets[0]               = 0;
4965         vaimg->offsets[1]               = mediaSurface->iHeight * mediaSurface->iPitch;
4966         vaimg->offsets[2]               = mediaSurface->iHeight * mediaSurface->iPitch * 3 / 2;
4967         break;
4968     case Media_Format_411P:
4969         vaimg->format.bits_per_pixel    = 12;
4970         vaimg->num_planes               = 3;
4971         vaimg->pitches[0]               =
4972         vaimg->pitches[1]               =
4973         vaimg->pitches[2]               = mediaSurface->iPitch;
4974         vaimg->offsets[0]               = 0;
4975         vaimg->offsets[1]               = mediaSurface->iHeight * mediaSurface->iPitch;
4976         vaimg->offsets[2]               = mediaSurface->iHeight * mediaSurface->iPitch * 2;
4977         break;
4978     case Media_Format_422V:
4979         vaimg->format.bits_per_pixel    = 16;
4980         vaimg->num_planes               = 3;
4981         vaimg->pitches[0]               =
4982         vaimg->pitches[1]               =
4983         vaimg->pitches[2]               = mediaSurface->iPitch;
4984         vaimg->offsets[0]               = 0;
4985         vaimg->offsets[1]               = mediaSurface->iHeight * mediaSurface->iPitch;
4986         vaimg->offsets[2]               = mediaSurface->iHeight * mediaSurface->iPitch * 3 / 2;
4987         break;
4988     case Media_Format_422H:
4989         vaimg->format.bits_per_pixel    = 16;
4990         vaimg->num_planes               = 3;
4991         vaimg->pitches[0]               =
4992         vaimg->pitches[1]               =
4993         vaimg->pitches[2]               = mediaSurface->iPitch;
4994         vaimg->offsets[0]               = 0;
4995         vaimg->offsets[1]               = mediaSurface->iHeight * mediaSurface->iPitch;
4996         vaimg->offsets[2]               = mediaSurface->iHeight * mediaSurface->iPitch * 2;
4997         break;
4998     case Media_Format_P010:
4999     case Media_Format_P012:
5000     case Media_Format_P016:
5001         vaimg->format.bits_per_pixel    = 24;
5002         vaimg->num_planes               = 2;
5003         vaimg->pitches[0]               = mediaSurface->iPitch;
5004         vaimg->pitches[1]               =
5005         vaimg->pitches[2]               = mediaSurface->iPitch;
5006         vaimg->offsets[0]               = 0;
5007         vaimg->offsets[1]               = mediaSurface->iHeight * mediaSurface->iPitch;
5008         vaimg->offsets[2]               = vaimg->offsets[1] + 2;
5009         break;
5010     case Media_Format_Y410:
5011     case Media_Format_AYUV:
5012 #if VA_CHECK_VERSION(1, 13, 0)
5013     case Media_Format_XYUV:
5014 #endif
5015     case Media_Format_Y210:
5016 #if VA_CHECK_VERSION(1, 9, 0)
5017     case Media_Format_Y212:
5018 #endif
5019     case Media_Format_Y216:
5020         vaimg->format.bits_per_pixel    = 32;
5021         vaimg->data_size                = mediaSurface->iPitch * mediaSurface->iHeight;
5022         vaimg->num_planes               = 1;
5023         vaimg->pitches[0]               = mediaSurface->iPitch;
5024         vaimg->offsets[0]               = 0;
5025         break;
5026 #if VA_CHECK_VERSION(1, 9, 0)
5027     case Media_Format_Y412:
5028 #endif
5029     case Media_Format_Y416:
5030         vaimg->format.bits_per_pixel    = 64; // packed format [alpha, Y, U, V], 16 bits per channel
5031         vaimg->num_planes               = 1;
5032         vaimg->pitches[0]               = mediaSurface->iPitch;
5033         vaimg->offsets[0]               = 0;
5034         break;
5035      default:
5036         vaimg->format.bits_per_pixel    = 12;
5037         vaimg->num_planes               = 2;
5038         vaimg->pitches[0]               = mediaSurface->iPitch;
5039         vaimg->pitches[1]               =
5040         vaimg->pitches[2]               = mediaSurface->iPitch;
5041         vaimg->offsets[0]               = 0;
5042         if(MEDIA_IS_WA(&mediaCtx->WaTable, WaDisableGmmLibOffsetInDeriveImage))
5043         {
5044             vaimg->offsets[1]           = mediaSurface->iHeight * mediaSurface->iPitch;
5045             vaimg->offsets[2]           = vaimg->offsets[1] + 1;
5046         }
5047         else
5048         {
5049             vaimg->offsets[1]           = offsetU;
5050             vaimg->offsets[2]           = offsetV;
5051         }
5052         break;
5053     }
5054 
5055     if ((mediaSurface->pSurfDesc != nullptr) && (mediaSurface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR))
5056     {
5057         vaimg->num_planes               = mediaSurface->pSurfDesc->uiPlanes;
5058         for (uint32_t i = 0; i < vaimg->num_planes; i++)
5059         {
5060             vaimg->pitches[i]           = mediaSurface->pSurfDesc->uiPitches[i];
5061             vaimg->offsets[i]           = mediaSurface->pSurfDesc->uiOffsets[i];
5062         }
5063     }
5064 
5065     mediaCtx->m_caps->PopulateColorMaskInfo(&vaimg->format);
5066 
5067     DDI_MEDIA_BUFFER *buf               = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
5068     if (buf == nullptr)
5069     {
5070         MOS_FreeMemory(vaimg);
5071         MOS_FreeMemory(buf);
5072         return VA_STATUS_ERROR_ALLOCATION_FAILED;
5073     }
5074     buf->uiNumElements = 1;
5075     buf->iSize         = vaimg->data_size;
5076     buf->uiType        = VAImageBufferType;
5077     buf->format        = mediaSurface->format;
5078     buf->uiOffset      = 0;
5079 
5080     buf->bo            = mediaSurface->bo;
5081     buf->format        = mediaSurface->format;
5082     buf->TileType      = mediaSurface->TileType;
5083     buf->pSurface      = mediaSurface;
5084     mos_bo_reference(mediaSurface->bo);
5085 
5086     DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
5087     PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufferHeapElement = DdiMediaUtil_AllocPMediaBufferFromHeap(mediaCtx->pBufferHeap);
5088 
5089     if (nullptr == bufferHeapElement)
5090     {
5091         DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
5092         MOS_FreeMemory(vaimg);
5093         MOS_FreeMemory(buf);
5094         return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5095     }
5096     bufferHeapElement->pBuffer    = buf;
5097     bufferHeapElement->pCtx       = nullptr;
5098     bufferHeapElement->uiCtxType  = DDI_MEDIA_CONTEXT_TYPE_MEDIA;
5099 
5100     vaimg->buf             = bufferHeapElement->uiVaBufferID;
5101     mediaCtx->uiNumBufs++;
5102     DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
5103 
5104     *image = *vaimg;
5105 
5106     MOS_TraceEventExt(EVENT_VA_DERIVE, EVENT_TYPE_END, &surface, sizeof(surface), &vaimg->image_id, sizeof(VAGenericID));
5107     return VA_STATUS_SUCCESS;
5108 }
5109 
5110 //!
5111 //! \brief  Free allocated surfaceheap elements
5112 //!
5113 //! \param  [in] ctx
5114 //!         Pointer to VA driver context
5115 //! \param  [in] image
5116 //!         VA image ID
5117 //!
5118 //! \return VAStatus
5119 //!     VA_STATUS_SUCCESS if success, else fail reason
5120 //!
DdiMedia_DestroyImage(VADriverContextP ctx,VAImageID image)5121 VAStatus DdiMedia_DestroyImage (
5122     VADriverContextP ctx,
5123     VAImageID        image)
5124 {
5125     DDI_FUNCTION_ENTER();
5126     MOS_TraceEventExt(EVENT_VA_FREE_IMAGE, EVENT_TYPE_START, &image, sizeof(image), nullptr, 0);
5127 
5128     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
5129     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
5130 
5131     DDI_CHK_NULL(mediaCtx,             "nullptr Media",                        VA_STATUS_ERROR_INVALID_CONTEXT);
5132     DDI_CHK_NULL(mediaCtx->pImageHeap, "nullptr mediaCtx->pImageHeap",        VA_STATUS_ERROR_INVALID_CONTEXT);
5133     DDI_CHK_LESS((uint32_t)image, mediaCtx->pImageHeap->uiAllocatedHeapElements, "Invalid image", VA_STATUS_ERROR_INVALID_IMAGE);
5134 
5135     VAImage *vaImage = DdiMedia_GetVAImageFromVAImageID(mediaCtx, image);
5136     if (vaImage == nullptr)
5137     {
5138         return VA_STATUS_ERROR_INVALID_PARAMETER;
5139     }
5140     DdiMedia_DestroyBuffer(ctx, vaImage->buf);
5141     MOS_FreeMemory(vaImage);
5142 
5143     DdiMedia_DestroyImageFromVAImageID(mediaCtx, image);
5144 
5145     MOS_TraceEventExt(EVENT_VA_FREE_IMAGE, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
5146     return VA_STATUS_SUCCESS;
5147 }
5148 
5149 //!
5150 //! \brief  Set image palette
5151 //!
5152 //! \param  [in] ctx
5153 //!         Pointer to VA driver context
5154 //! \param  [in] image
5155 //!         VA image ID
5156 //! \param  [in] palette
5157 //!         Palette
5158 //!
5159 //! \return VAStatus
5160 //!     VA_STATUS_ERROR_UNIMPLEMENTED if call success, else fail reason
5161 //!
DdiMedia_SetImagePalette(VADriverContextP ctx,VAImageID image,unsigned char * palette)5162 VAStatus DdiMedia_SetImagePalette(
5163     VADriverContextP ctx,
5164     VAImageID        image,
5165     unsigned char    *palette
5166 )
5167 {
5168     DDI_UNUSED(ctx);
5169     DDI_UNUSED(image);
5170     DDI_UNUSED(palette);
5171     DDI_FUNCTION_ENTER();
5172 
5173     return VA_STATUS_ERROR_UNIMPLEMENTED;
5174 }
5175 
SwizzleSurface(PDDI_MEDIA_CONTEXT mediaCtx,PGMM_RESOURCE_INFO pGmmResInfo,void * pLockedAddr,uint32_t TileType,uint8_t * pResourceBase,bool bUpload)5176 VAStatus SwizzleSurface(PDDI_MEDIA_CONTEXT mediaCtx, PGMM_RESOURCE_INFO pGmmResInfo, void *pLockedAddr, uint32_t TileType, uint8_t* pResourceBase, bool bUpload)
5177 {
5178     uint32_t            uiSize, uiPitch;
5179     GMM_RES_COPY_BLT    gmmResCopyBlt;
5180     uint32_t               uiPicHeight;
5181     uint32_t               ulSwizzledSize;
5182     VAStatus            vaStatus = VA_STATUS_SUCCESS;
5183 
5184     DDI_CHK_NULL(pGmmResInfo, "pGmmResInfo is NULL", VA_STATUS_ERROR_OPERATION_FAILED);
5185     DDI_CHK_NULL(pLockedAddr, "pLockedAddr is NULL", VA_STATUS_ERROR_OPERATION_FAILED);
5186     DDI_CHK_NULL(pResourceBase, "pResourceBase is NULL", VA_STATUS_ERROR_ALLOCATION_FAILED);
5187 
5188     memset(&gmmResCopyBlt, 0x0, sizeof(GMM_RES_COPY_BLT));
5189     uiPicHeight = pGmmResInfo->GetBaseHeight();
5190     uiSize = pGmmResInfo->GetSizeMainSurface();
5191     uiPitch = pGmmResInfo->GetRenderPitch();
5192     gmmResCopyBlt.Gpu.pData = pLockedAddr;
5193     gmmResCopyBlt.Sys.pData = pResourceBase;
5194     gmmResCopyBlt.Sys.RowPitch = uiPitch;
5195     gmmResCopyBlt.Sys.BufferSize = uiSize;
5196     gmmResCopyBlt.Sys.SlicePitch = uiSize;
5197     gmmResCopyBlt.Blt.Slices = 1;
5198     gmmResCopyBlt.Blt.Upload = bUpload;
5199 
5200     if(mediaCtx->pGmmClientContext->IsPlanar(pGmmResInfo->GetResourceFormat()) == true)
5201     {
5202         gmmResCopyBlt.Blt.Width = pGmmResInfo->GetBaseWidth();
5203         gmmResCopyBlt.Blt.Height = uiSize/uiPitch;
5204     }
5205 
5206     pGmmResInfo->CpuBlt(&gmmResCopyBlt);
5207 
5208     return vaStatus;
5209 }
5210 
5211 //!
5212 //! \brief  Copy plane from src to dst row by row when src and dst strides are different
5213 //!
5214 //! \param  [in] dst
5215 //!         Destination plane
5216 //! \param  [in] dstPitch
5217 //!         Destination plane pitch
5218 //! \param  [in] src
5219 //!         Source plane
5220 //! \param  [in] srcPitch
5221 //!         Source plane pitch
5222 //! \param  [in] height
5223 //!         Plane hight
5224 //!
DdiMedia_CopyPlane(uint8_t * dst,uint32_t dstPitch,uint8_t * src,uint32_t srcPitch,uint32_t height)5225 static void DdiMedia_CopyPlane(
5226     uint8_t *dst,
5227     uint32_t dstPitch,
5228     uint8_t *src,
5229     uint32_t srcPitch,
5230     uint32_t height)
5231 {
5232     uint32_t rowSize = std::min(dstPitch, srcPitch);
5233     for (int y = 0; y < height; y += 1)
5234     {
5235         memcpy(dst, src, rowSize);
5236         dst += dstPitch;
5237         src += srcPitch;
5238     }
5239 }
5240 
5241 //!
5242 //! \brief  Copy data from surface to image
5243 //!
5244 //! \param  [in] ctx
5245 //!         Input driver context
5246 //! \param  [in] surface
5247 //!         Pointer to surface
5248 //! \param  [in] image
5249 //!         Pointer to image
5250 //!
5251 //! \return VAStatus
5252 //!     VA_STATUS_SUCCESS if success, else fail reason
5253 //!
DdiMedia_CopySurfaceToImage(VADriverContextP ctx,DDI_MEDIA_SURFACE * surface,VAImage * image)5254 static VAStatus DdiMedia_CopySurfaceToImage(
5255     VADriverContextP  ctx,
5256     DDI_MEDIA_SURFACE *surface,
5257     VAImage           *image)
5258 {
5259     DDI_FUNCTION_ENTER();
5260 
5261     DDI_CHK_NULL(ctx,       "nullptr ctx.",         VA_STATUS_ERROR_INVALID_CONTEXT);
5262     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
5263     DDI_CHK_NULL(mediaCtx,  "nullptr mediaCtx.",    VA_STATUS_ERROR_INVALID_CONTEXT);
5264     DDI_CHK_NULL(surface,  "nullptr meida surface.", VA_STATUS_ERROR_INVALID_BUFFER);
5265     uint32_t flag = MOS_LOCKFLAG_READONLY;
5266     VAStatus vaStatus = VA_STATUS_SUCCESS;
5267 
5268     //Lock Surface
5269     if ((Media_Format_CPU != surface->format))
5270     {
5271         vaStatus = DdiMedia_MediaMemoryDecompress(mediaCtx, surface);
5272 
5273         if (vaStatus != VA_STATUS_SUCCESS)
5274         {
5275             DDI_NORMALMESSAGE("surface Decompression fail, continue next steps.");
5276         }
5277     }
5278 
5279     void* surfData = DdiMediaUtil_LockSurface(surface, flag);
5280 
5281     if (surfData == nullptr)
5282     {
5283         DDI_ASSERTMESSAGE("nullptr surfData.");
5284         return vaStatus;
5285     }
5286 
5287     void *imageData = nullptr;
5288     vaStatus = DdiMedia_MapBuffer(ctx, image->buf, &imageData);
5289     if (vaStatus != VA_STATUS_SUCCESS)
5290     {
5291         DDI_ASSERTMESSAGE("Failed to map buffer.");
5292         DdiMediaUtil_UnlockSurface(surface);
5293         return vaStatus;
5294     }
5295 
5296     uint8_t *ySrc = (uint8_t*)surfData;
5297     uint8_t *yDst = (uint8_t*)imageData;
5298 
5299     DdiMedia_CopyPlane(yDst, image->pitches[0], ySrc, surface->iPitch, image->height);
5300     if (image->num_planes > 1)
5301     {
5302         uint8_t *uSrc = ySrc + surface->iPitch * surface->iHeight;
5303         uint8_t *uDst = yDst + image->offsets[1];
5304         uint32_t chromaPitch       = 0;
5305         uint32_t chromaHeight      = 0;
5306         uint32_t imageChromaPitch  = 0;
5307         uint32_t imageChromaHeight = 0;
5308         DdiMedia_GetChromaPitchHeight(DdiMedia_MediaFormatToOsFormat(surface->format), surface->iPitch, surface->iHeight, &chromaPitch, &chromaHeight);
5309         DdiMedia_GetChromaPitchHeight(image->format.fourcc, image->pitches[0], image->height, &imageChromaPitch, &imageChromaHeight);
5310         DdiMedia_CopyPlane(uDst, image->pitches[1], uSrc, chromaPitch, imageChromaHeight);
5311 
5312         if(image->num_planes > 2)
5313         {
5314             uint8_t *vSrc = uSrc + chromaPitch * chromaHeight;
5315             uint8_t *vDst = yDst + image->offsets[2];
5316             DdiMedia_CopyPlane(vDst, image->pitches[2], vSrc, chromaPitch, imageChromaHeight);
5317         }
5318     }
5319 
5320     vaStatus = DdiMedia_UnmapBuffer(ctx, image->buf);
5321     if (vaStatus != VA_STATUS_SUCCESS)
5322     {
5323         DDI_ASSERTMESSAGE("Failed to unmap buffer.");
5324         DdiMediaUtil_UnlockSurface(surface);
5325         return vaStatus;
5326     }
5327 
5328     DdiMediaUtil_UnlockSurface(surface);
5329 
5330     return vaStatus;
5331 }
5332 
5333 //!
5334 //! \brief  Retrive surface data into a VAImage
5335 //! \details    Image must be in a format supported by the implementation
5336 //!
5337 //! \param  [in] ctx
5338 //!         Input driver context
5339 //! \param  [in] surface
5340 //!         Input surface ID of source
5341 //! \param  [in] x
5342 //!         X offset of the wanted region
5343 //! \param  [in] y
5344 //!         Y offset of the wanted region
5345 //! \param  [in] width
5346 //!         Width of the wanted region
5347 //! \param  [in] height
5348 //!         Height of the wanted region
5349 //! \param  [in] image
5350 //!     The image ID of the source image
5351 //!
5352 //! \return VAStatus
5353 //!     VA_STATUS_SUCCESS if success, else fail reason
5354 //!
DdiMedia_GetImage(VADriverContextP ctx,VASurfaceID surface,int32_t x,int32_t y,uint32_t width,uint32_t height,VAImageID image)5355 VAStatus DdiMedia_GetImage(
5356     VADriverContextP ctx,
5357     VASurfaceID      surface,
5358     int32_t          x,     /* coordinates of the upper left source pixel */
5359     int32_t          y,
5360     uint32_t         width, /* width and height of the region */
5361     uint32_t         height,
5362     VAImageID        image
5363 )
5364 {
5365     DDI_FUNCTION_ENTER();
5366     uint32_t event[] = {surface, x, y, width, height, image};
5367     MOS_TraceEventExt(EVENT_VA_GET, EVENT_TYPE_START, &event, sizeof(event), nullptr, 0);
5368 
5369     DDI_CHK_NULL(ctx,       "nullptr ctx.",         VA_STATUS_ERROR_INVALID_CONTEXT);
5370 
5371     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
5372     DDI_CHK_NULL(mediaCtx,  "nullptr mediaCtx.",    VA_STATUS_ERROR_INVALID_CONTEXT);
5373 
5374     DDI_CHK_NULL(mediaCtx->pSurfaceHeap,    "nullptr mediaCtx->pSurfaceHeap.",   VA_STATUS_ERROR_INVALID_CONTEXT);
5375     DDI_CHK_NULL(mediaCtx->pImageHeap,      "nullptr mediaCtx->pImageHeap.",     VA_STATUS_ERROR_INVALID_CONTEXT);
5376     DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface.", VA_STATUS_ERROR_INVALID_SURFACE);
5377     DDI_CHK_LESS((uint32_t)image,   mediaCtx->pImageHeap->uiAllocatedHeapElements,   "Invalid image.",   VA_STATUS_ERROR_INVALID_IMAGE);
5378 
5379     VAImage *vaimg = DdiMedia_GetVAImageFromVAImageID(mediaCtx, image);
5380     DDI_CHK_NULL(vaimg,     "nullptr vaimg.",       VA_STATUS_ERROR_INVALID_IMAGE);
5381 
5382     DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, vaimg->buf);
5383     DDI_CHK_NULL(buf,       "nullptr buf.",         VA_STATUS_ERROR_INVALID_BUFFER);
5384 
5385     DDI_MEDIA_SURFACE *inputSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface);
5386     DDI_CHK_NULL(inputSurface,     "nullptr inputSurface.",      VA_STATUS_ERROR_INVALID_SURFACE);
5387     DDI_CHK_NULL(inputSurface->bo, "nullptr inputSurface->bo.",  VA_STATUS_ERROR_INVALID_SURFACE);
5388 
5389     VAStatus vaStatus = VA_STATUS_SUCCESS;
5390 #ifndef _FULL_OPEN_SOURCE
5391     VASurfaceID target_surface = VA_INVALID_SURFACE;
5392     VASurfaceID output_surface = surface;
5393 
5394     if (inputSurface->format != DdiMedia_OsFormatToMediaFormat(vaimg->format.fourcc, vaimg->format.alpha_mask) ||
5395         (width != vaimg->width || height != vaimg->height) &&
5396         (vaimg->format.fourcc != VA_FOURCC_444P &&
5397         vaimg->format.fourcc != VA_FOURCC_422V &&
5398         vaimg->format.fourcc != VA_FOURCC_422H))
5399     {
5400         VAContextID context = VA_INVALID_ID;
5401         //Create VP Context.
5402         vaStatus = DdiVp_CreateContext(ctx, 0, 0, 0, 0, 0, 0, &context);
5403         DDI_CHK_RET(vaStatus, "Create VP Context failed.");
5404 
5405         //Create target surface for VP pipeline.
5406         DDI_MEDIA_FORMAT mediaFmt = DdiMedia_OsFormatToMediaFormat(vaimg->format.fourcc, vaimg->format.fourcc);
5407         if (mediaFmt == Media_Format_Count)
5408         {
5409             DDI_ASSERTMESSAGE("Unsupported surface type.");
5410             DdiVp_DestroyContext(ctx, context);
5411             return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
5412         }
5413         PDDI_MEDIA_SURFACE_DESCRIPTOR surfDesc = (PDDI_MEDIA_SURFACE_DESCRIPTOR)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_SURFACE_DESCRIPTOR));
5414         if (!surfDesc) {
5415             DDI_ASSERTMESSAGE("nullptr surfDesc.");
5416             DdiVp_DestroyContext(ctx, context);
5417             return VA_STATUS_ERROR_ALLOCATION_FAILED;
5418         }
5419         surfDesc->uiVaMemType = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
5420         int memType = MOS_MEMPOOL_VIDEOMEMORY;
5421         if (MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrLocalMemory))
5422         {
5423             memType = MOS_MEMPOOL_SYSTEMMEMORY;
5424         }
5425         target_surface = (VASurfaceID)DdiMedia_CreateRenderTarget(mediaCtx, mediaFmt, vaimg->width, vaimg->height, surfDesc, VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC, memType);
5426         if (VA_INVALID_SURFACE == target_surface)
5427         {
5428             DDI_ASSERTMESSAGE("Create temp surface failed.");
5429             DdiVp_DestroyContext(ctx, context);
5430             return VA_STATUS_ERROR_ALLOCATION_FAILED;
5431         }
5432 
5433         VARectangle srcRect, dstRect;
5434         srcRect.x      = x;
5435         srcRect.y      = y;
5436         srcRect.width  = width;
5437         srcRect.height = height;
5438         dstRect.x      = 0;
5439         dstRect.y      = 0;
5440         dstRect.width  = vaimg->width;
5441         dstRect.height = vaimg->height;
5442 
5443         //Execute VP pipeline.
5444         vaStatus = DdiVp_VideoProcessPipeline(ctx, context, surface, &srcRect, target_surface, &dstRect);
5445         if (vaStatus != VA_STATUS_SUCCESS)
5446         {
5447             DDI_ASSERTMESSAGE("VP Pipeline failed.");
5448             DdiMedia_DestroySurfaces(ctx, &target_surface, 1);
5449             DdiVp_DestroyContext(ctx, context);
5450             return vaStatus;
5451         }
5452         vaStatus = DdiMedia_SyncSurface(ctx, target_surface);
5453         if (vaStatus != VA_STATUS_SUCCESS)
5454         {
5455             DDI_ASSERTMESSAGE("VP Sync surface failed.");
5456         }
5457         vaStatus = DdiVp_DestroyContext(ctx, context);
5458         if (vaStatus != VA_STATUS_SUCCESS)
5459         {
5460             DDI_ASSERTMESSAGE("VP Destroy Context failed.");
5461         }
5462         output_surface = target_surface;
5463     }
5464 
5465     //Get Media Surface from output surface ID
5466     DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, output_surface);
5467     DDI_CHK_NULL(mediaSurface,     "nullptr mediaSurface.",      VA_STATUS_ERROR_INVALID_SURFACE);
5468     DDI_CHK_NULL(mediaSurface->bo, "nullptr mediaSurface->bo.",  VA_STATUS_ERROR_INVALID_SURFACE);
5469 
5470     vaStatus = DdiMedia_CopySurfaceToImage(ctx, mediaSurface, vaimg);
5471 
5472     if (vaStatus != MOS_STATUS_SUCCESS)
5473     {
5474         DDI_ASSERTMESSAGE("Failed to copy surface to image buffer data!");
5475         if(target_surface != VA_INVALID_SURFACE)
5476         {
5477             DdiMedia_DestroySurfaces(ctx, &target_surface, 1);
5478         }
5479         return vaStatus;
5480     }
5481 
5482     //Destroy temp surface if created
5483     if(target_surface != VA_INVALID_SURFACE)
5484     {
5485         DdiMedia_DestroySurfaces(ctx, &target_surface, 1);
5486     }
5487 #else
5488     vaStatus = DdiMedia_CopySurfaceToImage(ctx, inputSurface, vaimg);
5489     DDI_CHK_RET(vaStatus, "Copy surface to image failed.");
5490 #endif
5491     MOS_TraceEventExt(EVENT_VA_GET, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
5492     return VA_STATUS_SUCCESS;
5493 }
5494 
5495 //!
5496 //! \brief  Copy data from a VAImage to a surface
5497 //! \details    Image must be in a format supported by the implementation
5498 //!
5499 //! \param  [in] ctx
5500 //!         Input driver context
5501 //! \param  [in] surface
5502 //!         Surface ID of destination
5503 //! \param  [in] image
5504 //!         The image ID of the destination image
5505 //! \param  [in] src_x
5506 //!         Source x offset of the image region
5507 //! \param  [in] src_y
5508 //!         Source y offset of the image region
5509 //! \param  [in] src_width
5510 //!         Source width offset of the image region
5511 //! \param  [in] src_height
5512 //!         Source height offset of the image region
5513 //! \param  [in] dest_x
5514 //!         Destination x offset of the surface region
5515 //! \param  [in] dest_y
5516 //!         Destination y offset of the surface region
5517 //! \param  [in] dest_width
5518 //!         Destination width offset of the surface region
5519 //! \param  [in] dest_height
5520 //!         Destination height offset of the surface region
5521 //!
5522 //! \return VAStatus
5523 //!     VA_STATUS_SUCCESS if success, else fail reason
5524 //!
DdiMedia_PutImage(VADriverContextP ctx,VASurfaceID surface,VAImageID image,int32_t src_x,int32_t src_y,uint32_t src_width,uint32_t src_height,int32_t dest_x,int32_t dest_y,uint32_t dest_width,uint32_t dest_height)5525 VAStatus DdiMedia_PutImage(
5526     VADriverContextP ctx,
5527     VASurfaceID      surface,
5528     VAImageID        image,
5529     int32_t          src_x,
5530     int32_t          src_y,
5531     uint32_t         src_width,
5532     uint32_t         src_height,
5533     int32_t          dest_x,
5534     int32_t          dest_y,
5535     uint32_t         dest_width,
5536     uint32_t         dest_height
5537 )
5538 {
5539     DDI_FUNCTION_ENTER();
5540     uint32_t event[] = {surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height};
5541     MOS_TraceEventExt(EVENT_VA_PUT, EVENT_TYPE_START, &event, sizeof(event), nullptr, 0);
5542 
5543     DDI_CHK_NULL(ctx,                    "nullptr ctx.",                     VA_STATUS_ERROR_INVALID_CONTEXT);
5544 
5545     PDDI_MEDIA_CONTEXT mediaCtx     = DdiMedia_GetMediaContext(ctx);
5546     DDI_CHK_NULL(mediaCtx,               "nullptr mediaCtx.",                VA_STATUS_ERROR_INVALID_CONTEXT);
5547 
5548     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap.",   VA_STATUS_ERROR_INVALID_CONTEXT);
5549     DDI_CHK_NULL(mediaCtx->pImageHeap,   "nullptr mediaCtx->pImageHeap.",     VA_STATUS_ERROR_INVALID_CONTEXT);
5550     DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface.", VA_STATUS_ERROR_INVALID_SURFACE);
5551     DDI_CHK_LESS((uint32_t)image, mediaCtx->pImageHeap->uiAllocatedHeapElements,     "Invalid image.",   VA_STATUS_ERROR_INVALID_IMAGE);
5552 
5553     DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface);
5554     DDI_CHK_NULL(mediaSurface,     "nullptr mediaSurface.", VA_STATUS_ERROR_INVALID_SURFACE);
5555     DDI_CHK_NULL(mediaSurface->bo, "Invalid buffer.",       VA_STATUS_ERROR_INVALID_BUFFER);
5556 
5557     if (mediaSurface->pCurrentFrameSemaphore)
5558     {
5559         DdiMediaUtil_WaitSemaphore(mediaSurface->pCurrentFrameSemaphore);
5560         DdiMediaUtil_PostSemaphore(mediaSurface->pCurrentFrameSemaphore);
5561     }
5562 
5563     VAImage          *vaimg = DdiMedia_GetVAImageFromVAImageID(mediaCtx, image);
5564     DDI_CHK_NULL(vaimg,      "Invalid image.",      VA_STATUS_ERROR_INVALID_IMAGE);
5565 
5566     DDI_MEDIA_BUFFER *buf   = DdiMedia_GetBufferFromVABufferID(mediaCtx, vaimg->buf);
5567     DDI_CHK_NULL(buf,       "Invalid buffer.",      VA_STATUS_ERROR_INVALID_BUFFER);
5568 
5569     VAStatus vaStatus = VA_STATUS_SUCCESS;
5570     void *imageData   = nullptr;
5571 
5572     vaStatus = DdiMedia_MapBuffer(ctx, vaimg->buf, &imageData);
5573     DDI_CHK_RET(vaStatus, "MapBuffer failed.");
5574     DDI_CHK_NULL(imageData, "nullptr imageData.", VA_STATUS_ERROR_INVALID_IMAGE);
5575 
5576     // VP Pipeline will be called for CSC/Scaling if the surface format or data size is not consistent with image.
5577     if (mediaSurface->format != DdiMedia_OsFormatToMediaFormat(vaimg->format.fourcc, vaimg->format.alpha_mask) ||
5578         dest_width != src_width || dest_height != src_height ||
5579         src_x != 0 || dest_x != 0 || src_y != 0 || dest_y != 0)
5580     {
5581         VAContextID context     = VA_INVALID_ID;
5582 
5583         //Create VP Context.
5584         vaStatus = DdiVp_CreateContext(ctx, 0, 0, 0, 0, 0, 0, &context);
5585         DDI_CHK_RET(vaStatus, "Create VP Context failed");
5586 
5587         //Create temp surface for VP pipeline.
5588         DDI_MEDIA_FORMAT mediaFmt = DdiMedia_OsFormatToMediaFormat(vaimg->format.fourcc, vaimg->format.fourcc);
5589         if (mediaFmt == Media_Format_Count)
5590         {
5591             DDI_ASSERTMESSAGE("Unsupported surface type.");
5592             return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
5593         }
5594 
5595         int memType = MOS_MEMPOOL_VIDEOMEMORY;
5596         if (MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrLocalMemory))
5597         {
5598             memType = MOS_MEMPOOL_SYSTEMMEMORY;
5599         }
5600         VASurfaceID tempSurface = (VASurfaceID)DdiMedia_CreateRenderTarget(mediaCtx, mediaFmt, vaimg->width, vaimg->height, nullptr, VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ, memType);
5601         if (tempSurface == VA_INVALID_ID)
5602         {
5603             return VA_STATUS_ERROR_ALLOCATION_FAILED;
5604         }
5605 
5606         DDI_MEDIA_SURFACE *tempMediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, tempSurface);
5607         DDI_CHK_NULL(tempMediaSurface, "nullptr tempMediaSurface.", VA_STATUS_ERROR_INVALID_SURFACE);
5608 
5609         //Lock Surface
5610         void *tempSurfData = DdiMediaUtil_LockSurface(tempMediaSurface, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY));
5611         if (nullptr == tempSurfData)
5612         {
5613             DdiMedia_DestroySurfaces(ctx, &tempSurface, 1);
5614             return VA_STATUS_ERROR_SURFACE_BUSY;
5615         }
5616 
5617         //Copy data from image to temp surferce
5618         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5619         if (tempMediaSurface->data_size >= vaimg->data_size)
5620         {
5621             eStatus = MOS_SecureMemcpy(tempSurfData, tempMediaSurface->data_size, imageData, vaimg->data_size);
5622         }
5623         else
5624         {
5625             eStatus = MOS_SecureMemcpy(tempSurfData, tempMediaSurface->data_size, imageData, tempMediaSurface->data_size);
5626         }
5627         if (eStatus != MOS_STATUS_SUCCESS)
5628         {
5629             DDI_ASSERTMESSAGE("Failed to copy image to surface buffer.");
5630             DdiMediaUtil_UnlockSurface(tempMediaSurface);
5631             DdiMedia_DestroySurfaces(ctx, &tempSurface, 1);
5632             return VA_STATUS_ERROR_OPERATION_FAILED;
5633         }
5634 
5635         vaStatus = DdiMedia_UnmapBuffer(ctx, vaimg->buf);
5636         if (vaStatus != VA_STATUS_SUCCESS)
5637         {
5638             DDI_ASSERTMESSAGE("Failed to unmap buffer.");
5639             DdiMediaUtil_UnlockSurface(tempMediaSurface);
5640             DdiMedia_DestroySurfaces(ctx, &tempSurface, 1);
5641             return vaStatus;
5642         }
5643 
5644         DdiMediaUtil_UnlockSurface(tempMediaSurface);
5645 
5646         VARectangle srcRect, dstRect;
5647         srcRect.x      = src_x;
5648         srcRect.y      = src_y;
5649         srcRect.width  = src_width;
5650         srcRect.height = src_height;
5651         dstRect.x      = dest_x;
5652         dstRect.y      = dest_y;
5653         dstRect.width  = dest_width;
5654         dstRect.height = dest_height;
5655 
5656         //Execute VP pipeline.
5657         vaStatus = DdiVp_VideoProcessPipeline(ctx, context, tempSurface, &srcRect, surface, &dstRect);
5658         if (vaStatus != VA_STATUS_SUCCESS)
5659         {
5660             DDI_ASSERTMESSAGE("VP Pipeline failed.");
5661             DdiMedia_DestroySurfaces(ctx, &tempSurface, 1);
5662             return vaStatus;
5663         }
5664 
5665         vaStatus = DdiMedia_SyncSurface(ctx, tempSurface);
5666         DdiMedia_DestroySurfaces(ctx, &tempSurface, 1);
5667         vaStatus = DdiVp_DestroyContext(ctx, context);
5668     }
5669     else
5670     {
5671         //Lock Surface
5672         if ((nullptr != buf->pSurface) && (Media_Format_CPU != mediaSurface->format))
5673         {
5674             vaStatus = DdiMedia_MediaMemoryDecompress(mediaCtx, mediaSurface);
5675 
5676             if (vaStatus != VA_STATUS_SUCCESS)
5677             {
5678                 DDI_NORMALMESSAGE("surface Decompression fail, continue next steps.");
5679             }
5680         }
5681 
5682         void *surfData = DdiMediaUtil_LockSurface(mediaSurface, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY));
5683         if (nullptr == surfData)
5684         {
5685             DDI_ASSERTMESSAGE("Failed to lock surface.");
5686             return VA_STATUS_ERROR_SURFACE_BUSY;
5687         }
5688 
5689         if (src_width == dest_width && src_height == dest_height &&
5690             src_width == vaimg->width && src_height == vaimg->height &&
5691             src_width == mediaSurface->iWidth && src_height == mediaSurface->iHeight &&
5692             mediaSurface->data_size == vaimg->data_size)
5693         {
5694             //Copy data from image to surface
5695             MOS_STATUS eStatus = MOS_SecureMemcpy(surfData, vaimg->data_size, imageData, vaimg->data_size);
5696             DDI_CHK_CONDITION((eStatus != MOS_STATUS_SUCCESS), "Failed to copy image to surface buffer.", VA_STATUS_ERROR_OPERATION_FAILED);
5697         }
5698         else
5699         {
5700             uint8_t *ySrc = (uint8_t *)imageData + vaimg->offsets[0];
5701             uint8_t *yDst = (uint8_t *)surfData;
5702             DdiMedia_CopyPlane(yDst, mediaSurface->iPitch, ySrc, vaimg->pitches[0], src_height);
5703 
5704             if (vaimg->num_planes > 1)
5705             {
5706                 DDI_MEDIA_SURFACE uPlane = *mediaSurface;
5707 
5708                 uint32_t realChromaHeight      = 0;
5709                 uint32_t alignedChromaHeight   = 0;
5710                 uint32_t chromaPitch           = 0;
5711                 DdiMedia_GetChromaPitchHeight(DdiMedia_MediaFormatToOsFormat(uPlane.format), uPlane.iPitch, uPlane.iRealHeight, &chromaPitch, &realChromaHeight);
5712                 DdiMedia_GetChromaPitchHeight(DdiMedia_MediaFormatToOsFormat(uPlane.format), uPlane.iPitch, uPlane.iHeight, &chromaPitch, &alignedChromaHeight);
5713 
5714                 uint8_t *uSrc = (uint8_t *)imageData + vaimg->offsets[1];
5715                 uint8_t *uDst = yDst + mediaSurface->iPitch * mediaSurface->iHeight;
5716                 DdiMedia_CopyPlane(uDst, chromaPitch, uSrc, vaimg->pitches[1], realChromaHeight);
5717                 if (vaimg->num_planes > 2)
5718                 {
5719                     uint8_t *vSrc = (uint8_t *)imageData + vaimg->offsets[2];
5720                     uint8_t *vDst = uDst + chromaPitch * alignedChromaHeight;
5721                     DdiMedia_CopyPlane(vDst, chromaPitch, vSrc, vaimg->pitches[2], realChromaHeight);
5722                 }
5723             }
5724         }
5725 
5726         vaStatus = DdiMedia_UnmapBuffer(ctx, vaimg->buf);
5727         if (vaStatus != VA_STATUS_SUCCESS)
5728         {
5729             DDI_ASSERTMESSAGE("Failed to unmap buffer.");
5730             DdiMediaUtil_UnlockSurface(mediaSurface);
5731             return vaStatus;
5732         }
5733 
5734         DdiMediaUtil_UnlockSurface(mediaSurface);
5735     }
5736     MOS_TraceEventExt(EVENT_VA_PUT, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
5737     return VA_STATUS_SUCCESS;
5738 }
5739 
5740 //!
5741 //! \brief  Query subpicture formats
5742 //!
5743 //! \param  [in] ctx
5744 //!         Pointer to VA driver context
5745 //! \param  [in] format_list
5746 //!         VA image format
5747 //! \param  [in] flags
5748 //!         Flags
5749 //! \param  [in] num_formats
5750 //!         Number of formats
5751 //!
5752 //! \return VAStatus
5753 //!     VA_STATUS_SUCCESS if success, else fail reason
5754 //!
DdiMedia_QuerySubpictureFormats(VADriverContextP ctx,VAImageFormat * format_list,uint32_t * flags,uint32_t * num_formats)5755 VAStatus DdiMedia_QuerySubpictureFormats(
5756     VADriverContextP ctx,
5757     VAImageFormat   *format_list,
5758     uint32_t        *flags,
5759     uint32_t        *num_formats)
5760 {
5761     DDI_UNUSED(ctx);
5762     DDI_UNUSED(format_list);
5763     DDI_UNUSED(flags);
5764 
5765     DDI_FUNCTION_ENTER();
5766 
5767     DDI_CHK_NULL(num_formats, "nullptr num_formats", VA_STATUS_ERROR_INVALID_PARAMETER);
5768     *num_formats = 0;
5769 
5770     return VA_STATUS_SUCCESS;
5771 }
5772 
5773 //!
5774 //! \brief  Create subpicture
5775 //!
5776 //! \param  [in] ctx
5777 //!         Pointer to VA driver context
5778 //! \param  [in] image
5779 //!         VA image ID
5780 //! \param  [out] subpicture
5781 //!         VA subpicture ID
5782 //!
5783 //! \return VAStatus
5784 //!     VA_STATUS_ERROR_UNIMPLEMENTED
5785 //!
DdiMedia_CreateSubpicture(VADriverContextP ctx,VAImageID image,VASubpictureID * subpicture)5786 VAStatus DdiMedia_CreateSubpicture(
5787     VADriverContextP ctx,
5788     VAImageID        image,
5789     VASubpictureID  *subpicture   /* out */
5790 )
5791 {
5792     DDI_UNUSED(ctx);
5793     DDI_UNUSED(image);
5794     DDI_UNUSED(subpicture);
5795 
5796     DDI_FUNCTION_ENTER();
5797 
5798     return VA_STATUS_ERROR_UNIMPLEMENTED;
5799 }
5800 
5801 //!
5802 //! \brief  Destroy subpicture
5803 //!
5804 //! \param  [in] ctx
5805 //!         Pointer to VA driver context
5806 //! \param  [in] subpicture
5807 //!         VA subpicture ID
5808 //!
5809 //! \return VAStatus
5810 //!     VA_STATUS_ERROR_UNIMPLEMENTED
5811 //!
DdiMedia_DestroySubpicture(VADriverContextP ctx,VASubpictureID subpicture)5812 VAStatus DdiMedia_DestroySubpicture(
5813     VADriverContextP ctx,
5814     VASubpictureID   subpicture
5815 )
5816 {
5817     DDI_UNUSED(ctx);
5818     DDI_UNUSED(subpicture);
5819 
5820     DDI_FUNCTION_ENTER();
5821 
5822     return VA_STATUS_ERROR_UNIMPLEMENTED;
5823 }
5824 
5825 //!
5826 //! \brief  Set subpicture image
5827 //!
5828 //! \param  [in] ctx
5829 //!         Pointer to VA driver context
5830 //! \param  [in] subpicture
5831 //!         VA subpicture ID
5832 //! \param  [in] image
5833 //!         VA image ID
5834 //!
5835 //! \return VAStatus
5836 //!     VA_STATUS_ERROR_UNIMPLEMENTED
5837 //!
DdiMedia_SetSubpictureImage(VADriverContextP ctx,VASubpictureID subpicture,VAImageID image)5838 VAStatus DdiMedia_SetSubpictureImage(
5839     VADriverContextP ctx,
5840     VASubpictureID   subpicture,
5841     VAImageID        image
5842 )
5843 {
5844     DDI_UNUSED(ctx);
5845     DDI_UNUSED(subpicture);
5846     DDI_UNUSED(image);
5847 
5848     DDI_FUNCTION_ENTER();
5849 
5850     return VA_STATUS_ERROR_UNIMPLEMENTED;
5851 }
5852 
5853 //!
5854 //! \brief  Set subpicture chrome key
5855 //!
5856 //! \param  [in] ctx
5857 //!         Pointer to VA driver context
5858 //! \param  [in] subpicture
5859 //!         VA subpicture ID
5860 //! \param  [in] chromakey_min
5861 //!         Minimum chroma key
5862 //! \param  [in] chromakey_max
5863 //!         Maximum chroma key
5864 //! \param  [in] chromakey_mask
5865 //!         Chromakey mask
5866 //!
5867 //! \return VAStatus
5868 //!     VA_STATUS_ERROR_UNIMPLEMENTED
5869 //!
DdiMedia_SetSubpictureChromakey(VADriverContextP ctx,VASubpictureID subpicture,uint32_t chromakey_min,uint32_t chromakey_max,uint32_t chromakey_mask)5870 VAStatus DdiMedia_SetSubpictureChromakey(
5871     VADriverContextP ctx,
5872     VASubpictureID   subpicture,
5873     uint32_t         chromakey_min,
5874     uint32_t         chromakey_max,
5875     uint32_t         chromakey_mask
5876 )
5877 {
5878     DDI_UNUSED(ctx);
5879     DDI_UNUSED(subpicture);
5880     DDI_UNUSED(chromakey_min);
5881     DDI_UNUSED(chromakey_max);
5882     DDI_UNUSED(chromakey_mask);
5883 
5884     DDI_FUNCTION_ENTER();
5885 
5886     return VA_STATUS_ERROR_UNIMPLEMENTED;
5887 }
5888 
5889 //!
5890 //! \brief  set subpicture global alpha
5891 //!
5892 //! \param  [in] ctx
5893 //!         Pointer to VA driver context
5894 //! \param  [in] subpicture
5895 //!         VA subpicture ID
5896 //! \param  [in] global_alpha
5897 //!         Global alpha
5898 //!
5899 //! \return VAStatus
5900 //!     VA_STATUS_ERROR_UNIMPLEMENTED
DdiMedia_SetSubpictureGlobalAlpha(VADriverContextP ctx,VASubpictureID subpicture,float global_alpha)5901 VAStatus DdiMedia_SetSubpictureGlobalAlpha(
5902     VADriverContextP ctx,
5903     VASubpictureID   subpicture,
5904     float            global_alpha
5905 )
5906 {
5907     DDI_UNUSED(ctx);
5908     DDI_UNUSED(subpicture);
5909     DDI_UNUSED(global_alpha);
5910 
5911     DDI_FUNCTION_ENTER();
5912 
5913     return VA_STATUS_ERROR_UNIMPLEMENTED;
5914 }
5915 
5916 //!
5917 //! \brief  Associate subpicture
5918 //!
5919 //! \param  [in] ctx
5920 //!         Pointer to VA driver context
5921 //! \param  [in] subpicture
5922 //!         VA subpicture ID
5923 //! \param  [in] target_surfaces
5924 //!         VA surface ID
5925 //! \param  [in] num_surfaces
5926 //!         Number of surfaces
5927 //! \param  [in] src_x
5928 //!         Source x of the region
5929 //! \param  [in] src_y
5930 //!         Source y of the region
5931 //! \param  [in] src_width
5932 //!         Source width of the region
5933 //! \param  [in] src_height
5934 //!         Source height of the region
5935 //! \param  [in] dest_x
5936 //!         Destination x
5937 //! \param  [in] dest_y
5938 //!         Destination y
5939 //! \param  [in] dest_width
5940 //!         Destination width
5941 //! \param  [in] dest_height
5942 //!         Destination height
5943 //! \param  [in] flags
5944 //!         Flags
5945 //!
5946 //! \return VAStatus
5947 //!     VA_STATUS_ERROR_UNIMPLEMENTED
5948 //!
DdiMedia_AssociateSubpicture(VADriverContextP ctx,VASubpictureID subpicture,VASurfaceID * target_surfaces,int32_t num_surfaces,int16_t src_x,int16_t src_y,uint16_t src_width,uint16_t src_height,int16_t dest_x,int16_t dest_y,uint16_t dest_width,uint16_t dest_height,uint32_t flags)5949 VAStatus DdiMedia_AssociateSubpicture(
5950     VADriverContextP ctx,
5951     VASubpictureID   subpicture,
5952     VASurfaceID     *target_surfaces,
5953     int32_t          num_surfaces,
5954     int16_t          src_x,  /* upper left offset in subpicture */
5955     int16_t          src_y,
5956     uint16_t         src_width,
5957     uint16_t         src_height,
5958     int16_t          dest_x, /* upper left offset in surface */
5959     int16_t          dest_y,
5960     uint16_t         dest_width,
5961     uint16_t         dest_height,
5962     /*
5963      * whether to enable chroma-keying or global-alpha
5964      * see VA_SUBPICTURE_XXX values
5965      */
5966     uint32_t     flags
5967 )
5968 {
5969     DDI_UNUSED(ctx);
5970     DDI_UNUSED(subpicture);
5971     DDI_UNUSED(target_surfaces);
5972     DDI_UNUSED(num_surfaces);
5973     DDI_UNUSED(src_x);
5974     DDI_UNUSED(src_y);
5975     DDI_UNUSED(src_width);
5976     DDI_UNUSED(src_height);
5977     DDI_UNUSED(dest_x);
5978     DDI_UNUSED(dest_y);
5979     DDI_UNUSED(dest_width);
5980     DDI_UNUSED(dest_height);
5981     DDI_UNUSED(flags);
5982 
5983     DDI_FUNCTION_ENTER();
5984 
5985     return VA_STATUS_ERROR_UNIMPLEMENTED;
5986 }
5987 
5988 //!
5989 //! \brief  Deassociate subpicture
5990 //!
5991 //! \param  [in] ctx
5992 //!         Pointer to VA driver context
5993 //! \param  [in] subpicture
5994 //!         VA subpicture ID
5995 //! \param  [in] target_surfaces
5996 //!         VA surface ID
5997 //! \param  [in] num_surfaces
5998 //!         Number of surfaces
5999 //!
6000 //! \return VAStatus
6001 //!     VA_STATUS_ERROR_UNIMPLEMENTED
6002 //!
DdiMedia_DeassociateSubpicture(VADriverContextP ctx,VASubpictureID subpicture,VASurfaceID * target_surfaces,int32_t num_surfaces)6003 VAStatus DdiMedia_DeassociateSubpicture(
6004     VADriverContextP ctx,
6005     VASubpictureID   subpicture,
6006     VASurfaceID     *target_surfaces,
6007     int32_t          num_surfaces
6008 )
6009 {
6010     DDI_UNUSED(ctx);
6011     DDI_UNUSED(subpicture);
6012     DDI_UNUSED(target_surfaces);
6013     DDI_UNUSED(num_surfaces);
6014 
6015     DDI_FUNCTION_ENTER();
6016 
6017     return VA_STATUS_ERROR_UNIMPLEMENTED;
6018 }
6019 
6020 //!
6021 //! \brief  Query display attributes
6022 //!
6023 //! \param  [in] ctx
6024 //!         Pointer to VA driver context
6025 //! \param  [in] attr_list
6026 //!         VA display attribute
6027 //! \param  [in] num_attributes
6028 //!         Number of attributes
6029 //!
6030 //! \return VAStatus
6031 //!     VA_STATUS_SUCCESS if success, else fail reason
6032 //!
DdiMedia_QueryDisplayAttributes(VADriverContextP ctx,VADisplayAttribute * attr_list,int32_t * num_attributes)6033 VAStatus DdiMedia_QueryDisplayAttributes(
6034     VADriverContextP    ctx,
6035     VADisplayAttribute *attr_list,
6036     int32_t            *num_attributes)
6037 {
6038     DDI_FUNCTION_ENTER();
6039 
6040     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
6041     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
6042     DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
6043 
6044     DDI_CHK_NULL(attr_list, "nullptr attr_list", VA_STATUS_ERROR_INVALID_PARAMETER);
6045     DDI_CHK_NULL(num_attributes, "nullptr num_attributes", VA_STATUS_ERROR_INVALID_PARAMETER);
6046 
6047     return mediaCtx->m_caps->QueryDisplayAttributes(attr_list, num_attributes);
6048 }
6049 
6050 //!
6051 //! \brief  Get display attributes
6052 //! \details    This function returns the current attribute values in "attr_list".
6053 //!         Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
6054 //!         from vaQueryDisplayAttributes() can have their values retrieved.
6055 //!
6056 //! \param  [in] ctx
6057 //!         Pointer to VA driver context
6058 //! \param  [in] attr_list
6059 //!         VA display attribute
6060 //! \param  [in] num_attributes
6061 //!         Number of attributes
6062 //!
6063 //! \return VAStatus
6064 //!     VA_STATUS_ERROR_UNIMPLEMENTED
6065 //!
DdiMedia_GetDisplayAttributes(VADriverContextP ctx,VADisplayAttribute * attr_list,int32_t num_attributes)6066 VAStatus DdiMedia_GetDisplayAttributes(
6067     VADriverContextP    ctx,
6068     VADisplayAttribute *attr_list,
6069     int32_t             num_attributes)
6070 {
6071     DDI_FUNCTION_ENTER();
6072 
6073     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
6074     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
6075     DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
6076 
6077     DDI_CHK_NULL(attr_list, "nullptr attr_list", VA_STATUS_ERROR_INVALID_PARAMETER);
6078 
6079     return mediaCtx->m_caps->GetDisplayAttributes(attr_list, num_attributes);
6080 }
6081 
6082 //!
6083 //! \brief  Set display attributes
6084 //! \details    Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
6085 //!         from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or
6086 //!         the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
6087 //!
6088 //! \param  [in] ctx
6089 //!         Pointer to VA driver context
6090 //! \param  [in] attr_list
6091 //!         VA display attribute
6092 //! \param  [in] num_attributes
6093 //!         Number of attributes
6094 //!
6095 //! \return VAStatus
6096 //!     VA_STATUS_ERROR_UNIMPLEMENTED
6097 //!
DdiMedia_SetDisplayAttributes(VADriverContextP ctx,VADisplayAttribute * attr_list,int32_t num_attributes)6098 VAStatus DdiMedia_SetDisplayAttributes(
6099     VADriverContextP    ctx,
6100     VADisplayAttribute *attr_list,
6101     int32_t             num_attributes)
6102 {
6103     DDI_UNUSED(ctx);
6104     DDI_UNUSED(attr_list);
6105     DDI_UNUSED(num_attributes);
6106 
6107     DDI_FUNCTION_ENTER();
6108 
6109     return VA_STATUS_ERROR_UNIMPLEMENTED;
6110 }
6111 
6112 //!
6113 //! \brief  Query processing rate
6114 //!
6115 //! \param  [in] ctx
6116 //!         Pointer to VA driver context
6117 //! \param  [in] config_id
6118 //!         VA configuration ID
6119 //! \param  [in] proc_buf
6120 //!         VA processing rate parameter
6121 //! \param  [out] processing_rate
6122 //!         Processing rate
6123 //!
6124 //! \return VAStatus
6125 //!     VA_STATUS_SUCCESS if success, else fail reason
6126 //!
6127 VAStatus
DdiMedia_QueryProcessingRate(VADriverContextP ctx,VAConfigID config_id,VAProcessingRateParameter * proc_buf,uint32_t * processing_rate)6128 DdiMedia_QueryProcessingRate(
6129       VADriverContextP          ctx,
6130       VAConfigID                config_id,
6131       VAProcessingRateParameter *proc_buf,
6132       uint32_t                  *processing_rate /* output parameter */)
6133 {
6134     DDI_CHK_NULL(ctx,             "nullptr ctx",             VA_STATUS_ERROR_INVALID_CONTEXT);
6135     DDI_CHK_NULL(proc_buf,        "nullptr proc_buf",        VA_STATUS_ERROR_INVALID_PARAMETER);
6136     DDI_CHK_NULL(processing_rate, "nullptr processing_rate", VA_STATUS_ERROR_INVALID_PARAMETER);
6137 
6138     PDDI_MEDIA_CONTEXT mediaCtx   = DdiMedia_GetMediaContext(ctx);
6139     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
6140     DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
6141 
6142     return mediaCtx->m_caps->QueryProcessingRate(config_id,
6143             proc_buf, processing_rate);
6144 }
6145 
6146 //!
6147 //! \brief  media copy internal
6148 //!
6149 //! \param  [in] mosCtx
6150 //!         Pointer to mos context
6151 //! \param  [in] src
6152 //!         VA copy mos resource src.
6153 //! \param  [in] dst
6154 //!         VA copy mos resrouce dst.
6155 //! \param  [in] option
6156 //!         VA copy option, copy mode.
6157 //!
6158 //! \return VAStatus
6159 //!     VA_STATUS_SUCCESS if success, else fail reason
6160 //!
6161 VAStatus
DdiMedia_CopyInternal(PMOS_CONTEXT mosCtx,PMOS_RESOURCE src,PMOS_RESOURCE dst,uint32_t copy_mode)6162 DdiMedia_CopyInternal(
6163     PMOS_CONTEXT            mosCtx,
6164     PMOS_RESOURCE           src,
6165     PMOS_RESOURCE           dst,
6166     uint32_t                copy_mode
6167 )
6168 {
6169     VAStatus vaStatus = VA_STATUS_SUCCESS;
6170     MOS_STATUS mosStatus = MOS_STATUS_UNINITIALIZED;
6171     DDI_CHK_NULL(mosCtx, "nullptr mosCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
6172     DDI_CHK_NULL(src, "nullptr input osResource", VA_STATUS_ERROR_INVALID_SURFACE);
6173     DDI_CHK_NULL(dst, "nullptr output osResource", VA_STATUS_ERROR_INVALID_SURFACE);
6174 
6175     MediaCopyBaseState *mediaCopyState = static_cast<MediaCopyBaseState*>(*mosCtx->ppMediaCopyState);
6176 
6177     if (!mediaCopyState)
6178     {
6179         mediaCopyState = static_cast<MediaCopyBaseState*>(McpyDevice::CreateFactory(mosCtx));
6180         *mosCtx->ppMediaCopyState = mediaCopyState;
6181     }
6182 
6183     DDI_CHK_NULL(mediaCopyState, "Invalid mediaCopy State", VA_STATUS_ERROR_INVALID_PARAMETER);
6184 
6185     mosStatus = mediaCopyState->SurfaceCopy(src, dst, (MCPY_METHOD)copy_mode);
6186     if (mosStatus != MOS_STATUS_SUCCESS)
6187     {
6188         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
6189     }
6190 
6191     return vaStatus;
6192 }
6193 
6194 #if VA_CHECK_VERSION(1,10,0)
6195 //!
6196 //! \brief  media copy
6197 //!
6198 //! \param  [in] ctx
6199 //!         Pointer to VA driver context
6200 //! \param  [in] dst_obj
6201 //!         VA copy object dst.
6202 //! \param  [in] src_obj
6203 //!         VA copy object src.
6204 //! \param  [in] option
6205 //!         VA copy option, copy mode.
6206 //! \param  [in] sync_handle
6207 //!         VA copy sync handle
6208 //!
6209 //! \return VAStatus
6210 //!     VA_STATUS_SUCCESS if success, else fail reason
6211 //!
6212 VAStatus
DdiMedia_Copy(VADriverContextP ctx,VACopyObject * dst_obj,VACopyObject * src_obj,VACopyOption option)6213 DdiMedia_Copy(
6214     VADriverContextP    ctx,
6215     VACopyObject       *dst_obj,
6216     VACopyObject       *src_obj,
6217     VACopyOption       option
6218 )
6219 {
6220     VAStatus vaStatus = VA_STATUS_SUCCESS;
6221     MOS_CONTEXT        mosCtx   = {};
6222     MOS_RESOURCE src, dst;
6223     DdiCpInterface *pCpDdiInterface = nullptr;
6224     PDDI_MEDIA_SURFACE src_surface = nullptr;
6225     PDDI_MEDIA_SURFACE dst_surface = nullptr;
6226     PDDI_MEDIA_BUFFER src_buffer = nullptr;
6227     PDDI_MEDIA_BUFFER dst_buffer = nullptr;
6228 
6229     DDI_FUNCTION_ENTER();
6230 
6231     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
6232     PDDI_MEDIA_CONTEXT mediaCtx   = DdiMedia_GetMediaContext(ctx);
6233 
6234     DDI_CHK_NULL(mediaCtx,               "nullptr mediaCtx",               VA_STATUS_ERROR_INVALID_CONTEXT);
6235     DDI_CHK_NULL(mediaCtx->pBufferHeap,  "nullptr mediaCtx->pBufferHeap",  VA_STATUS_ERROR_INVALID_CONTEXT);
6236     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
6237     DDI_CHK_NULL(dst_obj, "nullptr copy dst", VA_STATUS_ERROR_INVALID_SURFACE);
6238     DDI_CHK_NULL(src_obj, "nullptr copy src", VA_STATUS_ERROR_INVALID_SURFACE);
6239 
6240     if (dst_obj->obj_type == VACopyObjectSurface)
6241     {
6242         DDI_CHK_LESS((uint32_t)dst_obj->object.surface_id, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "copy_dst", VA_STATUS_ERROR_INVALID_SURFACE);
6243         dst_surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, dst_obj->object.surface_id);
6244         DDI_CHK_NULL(dst_surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
6245         DDI_CHK_NULL(dst_surface->pGmmResourceInfo, "nullptr dst_surface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_PARAMETER);
6246 
6247         MOS_ZeroMemory(&dst, sizeof(dst));
6248         DdiMedia_MediaSurfaceToMosResource(dst_surface, &dst);
6249     }
6250     else if (dst_obj->obj_type == VACopyObjectBuffer)
6251     {
6252         DDI_CHK_LESS((uint32_t)dst_obj->object.buffer_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid copy dst buf_id", VA_STATUS_ERROR_INVALID_BUFFER);
6253         dst_buffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, dst_obj->object.buffer_id);
6254         DDI_CHK_NULL(dst_buffer, "nullptr buffer", VA_STATUS_ERROR_INVALID_BUFFER);
6255         DDI_CHK_NULL(dst_buffer->pGmmResourceInfo, "nullptr dst_buffer->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_PARAMETER);
6256 
6257         MOS_ZeroMemory(&dst, sizeof(dst));
6258         DdiMedia_MediaBufferToMosResource(dst_buffer, &dst);
6259     }
6260     else
6261     {
6262         DDI_ASSERTMESSAGE("DDI: unsupported src copy object in DdiMedia_copy.");
6263     }
6264 
6265     if (src_obj->obj_type == VACopyObjectSurface)
6266     {
6267         DDI_CHK_LESS((uint32_t)src_obj->object.surface_id, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "copy_src", VA_STATUS_ERROR_INVALID_SURFACE);
6268         src_surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, src_obj->object.surface_id);
6269         DDI_CHK_NULL(src_surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
6270         DDI_CHK_NULL(src_surface->pGmmResourceInfo, "nullptr src_surface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_PARAMETER);
6271 
6272         MOS_ZeroMemory(&src, sizeof(src));
6273         DdiMedia_MediaSurfaceToMosResource(src_surface, &src);
6274     }
6275     else if (src_obj->obj_type == VACopyObjectBuffer)
6276     {
6277         DDI_CHK_LESS((uint32_t)src_obj->object.buffer_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid copy dst buf_id", VA_STATUS_ERROR_INVALID_BUFFER);
6278         src_buffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, src_obj->object.buffer_id);
6279         DDI_CHK_NULL(src_buffer, "nullptr buffer", VA_STATUS_ERROR_INVALID_BUFFER);
6280         DDI_CHK_NULL(src_buffer->pGmmResourceInfo, "nullptr src_buffer->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_PARAMETER);
6281 
6282         MOS_ZeroMemory(&src, sizeof(src));
6283         DdiMedia_MediaBufferToMosResource(src_buffer, &src);
6284     }
6285     else
6286     {
6287         DDI_ASSERTMESSAGE("DDI: unsupported dst copy object in DdiMedia_copy.");
6288     }
6289 
6290     mosCtx.bufmgr          = mediaCtx->pDrmBufMgr;
6291     mosCtx.m_gpuContextMgr = mediaCtx->m_gpuContextMgr;
6292     mosCtx.m_cmdBufMgr     = mediaCtx->m_cmdBufMgr;
6293     mosCtx.fd              = mediaCtx->fd;
6294     mosCtx.iDeviceId       = mediaCtx->iDeviceId;
6295     mosCtx.m_skuTable      = mediaCtx->SkuTable;
6296     mosCtx.m_waTable       = mediaCtx->WaTable;
6297     mosCtx.m_gtSystemInfo  = *mediaCtx->pGtSystemInfo;
6298     mosCtx.m_platform      = mediaCtx->platform;
6299 
6300     mosCtx.ppMediaCopyState      = &mediaCtx->pMediaCopyState;
6301     mosCtx.m_gtSystemInfo        = *mediaCtx->pGtSystemInfo;
6302     mosCtx.m_auxTableMgr         = mediaCtx->m_auxTableMgr;
6303     mosCtx.pGmmClientContext     = mediaCtx->pGmmClientContext;
6304 
6305     mosCtx.m_osDeviceContext     = mediaCtx->m_osDeviceContext;
6306     mosCtx.m_apoMosEnabled       = mediaCtx->m_apoMosEnabled;
6307     mosCtx.pPerfData             = mediaCtx->perfData;
6308     mosCtx.m_userSettingPtr      = mediaCtx->m_userSettingPtr;
6309 
6310     pCpDdiInterface = Create_DdiCpInterface(mosCtx);
6311 
6312     if (nullptr == pCpDdiInterface)
6313     {
6314         return VA_STATUS_ERROR_ALLOCATION_FAILED;
6315     }
6316 
6317     vaStatus = DdiMedia_CopyInternal(&mosCtx, &src, &dst, option.bits.va_copy_mode);
6318 
6319     if ((option.bits.va_copy_sync == VA_EXEC_SYNC) && dst_surface)
6320     {
6321         uint32_t timeout_NS = 100000000;
6322         while (0 != mos_bo_wait(dst_surface->bo, timeout_NS))
6323         {
6324             // Just loop while gem_bo_wait times-out.
6325         }
6326     }
6327 
6328     if (pCpDdiInterface)
6329     {
6330         Delete_DdiCpInterface(pCpDdiInterface);
6331         pCpDdiInterface = NULL;
6332     }
6333 
6334     return vaStatus;
6335 }
6336 #endif
6337 
6338 //!
6339 //! \brief  Check for buffer info
6340 //!
6341 //! \param  [in] ctx
6342 //!         Pointer to VA driver context
6343 //! \param  [in] buf_id
6344 //!         VA buffer ID
6345 //! \param  [out] type
6346 //!         VA buffer type
6347 //! \param  [out] size
6348 //!         Size
6349 //! \param  [out] num_elements
6350 //!         Number of elements
6351 //!
6352 //! \return VAStatus
6353 //!     VA_STATUS_SUCCESS if success, else fail reason
6354 //!
DdiMedia_BufferInfo(VADriverContextP ctx,VABufferID buf_id,VABufferType * type,uint32_t * size,uint32_t * num_elements)6355 VAStatus DdiMedia_BufferInfo (
6356     VADriverContextP ctx,
6357     VABufferID       buf_id,
6358     VABufferType    *type,
6359     uint32_t        *size,
6360     uint32_t        *num_elements)
6361 {
6362     DDI_FUNCTION_ENTER();
6363 
6364     DDI_CHK_NULL(ctx,          "nullptr ctx",          VA_STATUS_ERROR_INVALID_CONTEXT);
6365     DDI_CHK_NULL(type,         "nullptr type",         VA_STATUS_ERROR_INVALID_PARAMETER);
6366     DDI_CHK_NULL(size,         "nullptr size",         VA_STATUS_ERROR_INVALID_PARAMETER);
6367     DDI_CHK_NULL(num_elements, "nullptr num_elements", VA_STATUS_ERROR_INVALID_PARAMETER);
6368 
6369     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
6370     if (nullptr == mediaCtx)
6371         return VA_STATUS_ERROR_INVALID_CONTEXT;
6372 
6373     DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
6374     DDI_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid buf_id", VA_STATUS_ERROR_INVALID_BUFFER);
6375 
6376     DDI_MEDIA_BUFFER *buf  = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id);
6377     if (nullptr == buf)
6378     {
6379         return VA_STATUS_ERROR_INVALID_BUFFER;
6380     }
6381 
6382     *type         = (VABufferType)buf->uiType;
6383     *size         = buf->iSize / buf->uiNumElements;
6384     *num_elements = buf->uiNumElements;
6385 
6386     return VA_STATUS_SUCCESS;
6387 }
6388 
6389 //!
6390 //! \brief  Lock surface
6391 //!
6392 //! \param  [in] ctx
6393 //!         Pointer to VA driver context
6394 //! \param  [in] surface
6395 //!         VA surface ID
6396 //! \param  [out] fourcc
6397 //!         FourCC
6398 //! \param  [out] luma_stride
6399 //!         Luma stride
6400 //! \param  [out] chroma_u_stride
6401 //!         Chroma U stride
6402 //! \param  [out] chroma_v_stride
6403 //!         Chroma V stride
6404 //! \param  [out] luma_offset
6405 //!         Luma offset
6406 //! \param  [out] chroma_u_offset
6407 //!         Chroma U offset
6408 //! \param  [out] chroma_v_offset
6409 //!         Chroma V offset
6410 //! \param  [out] buffer_name
6411 //!         Buffer name
6412 //! \param  [out] buffer
6413 //!         Buffer
6414 //!
6415 //! \return VAStatus
6416 //!     VA_STATUS_SUCCESS if success, else fail reason
6417 //!
DdiMedia_LockSurface(VADriverContextP ctx,VASurfaceID surface,uint32_t * fourcc,uint32_t * luma_stride,uint32_t * chroma_u_stride,uint32_t * chroma_v_stride,uint32_t * luma_offset,uint32_t * chroma_u_offset,uint32_t * chroma_v_offset,uint32_t * buffer_name,void ** buffer)6418 VAStatus DdiMedia_LockSurface (
6419     VADriverContextP ctx,
6420     VASurfaceID      surface,
6421     uint32_t        *fourcc,
6422     uint32_t        *luma_stride,
6423     uint32_t        *chroma_u_stride,
6424     uint32_t        *chroma_v_stride,
6425     uint32_t        *luma_offset,
6426     uint32_t        *chroma_u_offset,
6427     uint32_t        *chroma_v_offset,
6428     uint32_t        *buffer_name,
6429     void           **buffer )
6430 {
6431     DDI_FUNCTION_ENTER();
6432     MOS_TraceEventExt(EVENT_VA_LOCK, EVENT_TYPE_START, &surface, sizeof(surface), nullptr, 0);
6433 
6434     DDI_CHK_NULL(ctx,             "nullptr context",         VA_STATUS_ERROR_INVALID_CONTEXT);
6435     DDI_CHK_NULL(fourcc,          "nullptr fourcc",          VA_STATUS_ERROR_INVALID_PARAMETER);
6436     DDI_CHK_NULL(luma_stride,     "nullptr luma_stride",     VA_STATUS_ERROR_INVALID_PARAMETER);
6437     DDI_CHK_NULL(chroma_u_stride, "nullptr chroma_u_stride", VA_STATUS_ERROR_INVALID_PARAMETER);
6438     DDI_CHK_NULL(chroma_v_stride, "nullptr chroma_v_stride", VA_STATUS_ERROR_INVALID_PARAMETER);
6439     DDI_CHK_NULL(luma_offset,     "nullptr luma_offset",     VA_STATUS_ERROR_INVALID_PARAMETER);
6440     DDI_CHK_NULL(chroma_u_offset, "nullptr chroma_u_offset", VA_STATUS_ERROR_INVALID_PARAMETER);
6441     DDI_CHK_NULL(chroma_v_offset, "nullptr chroma_v_offset", VA_STATUS_ERROR_INVALID_PARAMETER);
6442     DDI_CHK_NULL(buffer_name,     "nullptr buffer_name",     VA_STATUS_ERROR_INVALID_PARAMETER);
6443     DDI_CHK_NULL(buffer,          "nullptr buffer",          VA_STATUS_ERROR_INVALID_PARAMETER);
6444 
6445     PDDI_MEDIA_CONTEXT mediaCtx          = DdiMedia_GetMediaContext(ctx);
6446     DDI_CHK_NULL(mediaCtx,               "nullptr Media",                   VA_STATUS_ERROR_INVALID_CONTEXT);
6447     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
6448     DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface", VA_STATUS_ERROR_INVALID_SURFACE);
6449 
6450     DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface);
6451 
6452 #ifdef _MMC_SUPPORTED
6453     // Decompress surface is needed
6454     DdiMedia_MediaMemoryDecompress(mediaCtx, mediaSurface);
6455 #endif
6456 
6457     if (nullptr == mediaSurface)
6458     {
6459         // Surface is absent.
6460         buffer = nullptr;
6461         return VA_STATUS_ERROR_INVALID_SURFACE;
6462     }
6463 
6464     if (mediaSurface->uiLockedImageID != VA_INVALID_ID)
6465     {
6466         // Surface is locked already.
6467         buffer = nullptr;
6468         return VA_STATUS_ERROR_INVALID_PARAMETER;
6469     }
6470 
6471     VAImage tmpImage;
6472     tmpImage.image_id = VA_INVALID_ID;
6473     VAStatus vaStatus = DdiMedia_DeriveImage(ctx,surface,&tmpImage);
6474     if (vaStatus != VA_STATUS_SUCCESS)
6475     {
6476         buffer = nullptr;
6477         return vaStatus;
6478     }
6479 
6480     mediaSurface->uiLockedImageID = tmpImage.image_id;
6481 
6482     vaStatus = DdiMedia_MapBuffer(ctx,tmpImage.buf,buffer);
6483     if (vaStatus != VA_STATUS_SUCCESS)
6484     {
6485         buffer = nullptr;
6486         return vaStatus;
6487     }
6488 
6489     mediaSurface->uiLockedBufID = tmpImage.buf;
6490 
6491     *fourcc                 = tmpImage.format.fourcc;
6492     *luma_offset            = tmpImage.offsets[0];
6493     *luma_stride            = tmpImage.pitches[0];
6494     *chroma_u_offset        = tmpImage.offsets[1];
6495     *chroma_u_stride        = tmpImage.pitches[1];
6496     *chroma_v_offset        = tmpImage.offsets[2];
6497     *chroma_v_stride        = tmpImage.pitches[2];
6498     *buffer_name            = tmpImage.buf;
6499 
6500     MOS_TraceEventExt(EVENT_VA_LOCK, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
6501     return VA_STATUS_SUCCESS;
6502 }
6503 
6504 //!
6505 //! \brief  Unlock surface
6506 //!
6507 //! \param  [in] ctx
6508 //!         Pointer to VA driver context
6509 //! \param  [in] surface
6510 //!         VA surface ID
6511 //!
6512 //! \return VAStatus
6513 //!     VA_STATUS_SUCCESS if success, else fail reason
6514 //!
DdiMedia_UnlockSurface(VADriverContextP ctx,VASurfaceID surface)6515 VAStatus DdiMedia_UnlockSurface (
6516     VADriverContextP   ctx,
6517     VASurfaceID        surface)
6518 {
6519     DDI_FUNCTION_ENTER();
6520     MOS_TraceEventExt(EVENT_VA_UNLOCK, EVENT_TYPE_START, &surface, sizeof(surface), nullptr, 0);
6521 
6522     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
6523 
6524     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
6525     DDI_CHK_NULL(mediaCtx,               "nullptr mediaCtx",                 VA_STATUS_ERROR_INVALID_CONTEXT);
6526     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap",   VA_STATUS_ERROR_INVALID_CONTEXT);
6527     DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface", VA_STATUS_ERROR_INVALID_SURFACE);
6528 
6529     DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface);
6530     DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface", VA_STATUS_ERROR_INVALID_SURFACE);
6531 
6532     if (mediaSurface->uiLockedImageID == VA_INVALID_ID)
6533     {
6534         return VA_STATUS_ERROR_INVALID_PARAMETER;
6535     }
6536 
6537     VABufferID bufID    = (VABufferID)(mediaSurface->uiLockedBufID);
6538     VAStatus   vaStatus = DdiMedia_UnmapBuffer(ctx, bufID);
6539     if (vaStatus != VA_STATUS_SUCCESS)
6540     {
6541         return vaStatus;
6542     }
6543     mediaSurface->uiLockedBufID = VA_INVALID_ID;
6544 
6545     VAImageID imageID  = (VAImageID)(mediaSurface->uiLockedImageID);
6546     vaStatus = DdiMedia_DestroyImage(ctx,imageID);
6547     if (vaStatus != VA_STATUS_SUCCESS)
6548     {
6549         return vaStatus;
6550     }
6551     mediaSurface->uiLockedImageID = VA_INVALID_ID;
6552 
6553     MOS_TraceEventExt(EVENT_VA_UNLOCK, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
6554     return VA_STATUS_SUCCESS;
6555 }
6556 
6557 //!
6558 //! \brief  Query video proc filters
6559 //!
6560 //! \param  [in] ctx
6561 //!         Pointer to VA driver context
6562 //! \param  [in] context
6563 //!         VA context ID
6564 //! \param  [in] filters
6565 //!         VA proc filter type
6566 //! \param  [in] num_filters
6567 //!         Number of filters
6568 //!
6569 //! \return VAStatus
6570 //!     VA_STATUS_SUCCESS if success, else fail reason
6571 //!
6572 VAStatus
DdiMedia_QueryVideoProcFilters(VADriverContextP ctx,VAContextID context,VAProcFilterType * filters,uint32_t * num_filters)6573 DdiMedia_QueryVideoProcFilters(
6574     VADriverContextP    ctx,
6575     VAContextID         context,
6576     VAProcFilterType   *filters,
6577     uint32_t           *num_filters)
6578 {
6579     DDI_UNUSED(ctx);
6580     DDI_UNUSED(context);
6581 
6582     DDI_FUNCTION_ENTER();
6583 
6584     DDI_CHK_NULL(filters,     "nullptr filters",     VA_STATUS_ERROR_INVALID_PARAMETER);
6585     DDI_CHK_NULL(num_filters, "nullptr num_filters", VA_STATUS_ERROR_INVALID_PARAMETER);
6586 
6587     uint32_t  max_num_filters = DDI_VP_MAX_NUM_FILTERS;
6588     // check if array size is less than VP_MAX_NUM_FILTERS
6589     if(*num_filters < max_num_filters)
6590     {
6591         DDI_NORMALMESSAGE("num_filters %d < max_num_filters %d. Probably caused by Libva version upgrade!", *num_filters, max_num_filters);
6592     }
6593 
6594     // Set the filters
6595     uint32_t i = 0;
6596     uint32_t num_supported_filters = 0;
6597     while(num_supported_filters < *num_filters && i < DDI_VP_MAX_NUM_FILTERS)
6598     {
6599         uint32_t num_filter_caps = 0;
6600         VAStatus vaStatus = DdiVp_QueryVideoProcFilterCaps(ctx, context, vp_supported_filters[i], nullptr, &num_filter_caps);
6601         if(vaStatus == VA_STATUS_SUCCESS && num_filter_caps != 0)
6602         {
6603             filters[num_supported_filters] = vp_supported_filters[i];
6604             num_supported_filters++;
6605         }
6606         i++;
6607     }
6608 
6609     // Tell the app how many valid filters are filled in the array
6610     *num_filters = num_supported_filters;
6611 
6612     return VA_STATUS_SUCCESS;
6613 }
6614 
6615 //!
6616 //! \brief  Query video processing filter capabilities.
6617 //!         The real implementation is in media_libva_vp.c, since it needs to use some definitions in vphal.h.
6618 //!
6619 //! \param  [in] ctx
6620 //!         Pointer to VA driver context
6621 //! \param  [in] context
6622 //!         VA context ID
6623 //! \param  [in] type
6624 //!         VA proc filter type
6625 //! \param  [inout] filter_caps
6626 //!         FIlter caps
6627 //! \param  [inout] num_filter_caps
6628 //!         Number of filter caps
6629 //!
6630 //! \return VAStatus
6631 //!     VA_STATUS_SUCCESS if success, else fail reason
6632 //!
6633 VAStatus
DdiMedia_QueryVideoProcFilterCaps(VADriverContextP ctx,VAContextID context,VAProcFilterType type,void * filter_caps,uint32_t * num_filter_caps)6634 DdiMedia_QueryVideoProcFilterCaps(
6635     VADriverContextP    ctx,
6636     VAContextID         context,
6637     VAProcFilterType    type,
6638     void               *filter_caps,
6639     uint32_t           *num_filter_caps
6640 )
6641 {
6642     DDI_FUNCTION_ENTER();
6643 
6644     return DdiVp_QueryVideoProcFilterCaps(ctx, context, type, filter_caps, num_filter_caps);
6645 }
6646 
6647 //!
6648 //! \brief  Query video proc pipeline caps
6649 //!
6650 //! \param  [in] ctx
6651 //!         Pointer to VA driver context
6652 //! \param  [in] context
6653 //!         VA context ID
6654 //! \param  [in] filters
6655 //!         VA buffer ID
6656 //! \param  [in] num_filters
6657 //!         Number of filters
6658 //! \param  [in] pipeline_caps
6659 //!         VA proc pipeline caps
6660 //!
6661 //! \return VAStatus
6662 //!     VA_STATUS_SUCCESS if success, else fail reason
6663 //!
6664 VAStatus
DdiMedia_QueryVideoProcPipelineCaps(VADriverContextP ctx,VAContextID context,VABufferID * filters,uint32_t num_filters,VAProcPipelineCaps * pipeline_caps)6665 DdiMedia_QueryVideoProcPipelineCaps(
6666     VADriverContextP    ctx,
6667     VAContextID         context,
6668     VABufferID         *filters,
6669     uint32_t            num_filters,
6670     VAProcPipelineCaps *pipeline_caps
6671 )
6672 {
6673     DDI_FUNCTION_ENTER();
6674 
6675     PDDI_MEDIA_CONTEXT mediaCtx   = DdiMedia_GetMediaContext(ctx);
6676 
6677     DDI_CHK_NULL(ctx,           "nullptr ctx",           VA_STATUS_ERROR_INVALID_CONTEXT);
6678     DDI_CHK_NULL(pipeline_caps, "nullptr pipeline_caps", VA_STATUS_ERROR_INVALID_PARAMETER);
6679     if (num_filters > 0)
6680         DDI_CHK_NULL(filters,   "nullptr filters",       VA_STATUS_ERROR_INVALID_PARAMETER);
6681 
6682     pipeline_caps->pipeline_flags             = VA_PROC_PIPELINE_FAST;
6683     pipeline_caps->filter_flags               = 0;
6684     pipeline_caps->rotation_flags             = (1 << VA_ROTATION_NONE) | (1 << VA_ROTATION_90) | (1 << VA_ROTATION_180) | (1 << VA_ROTATION_270);
6685     pipeline_caps->mirror_flags               = VA_MIRROR_HORIZONTAL  | VA_MIRROR_VERTICAL;
6686     pipeline_caps->blend_flags                = VA_BLEND_GLOBAL_ALPHA | VA_BLEND_PREMULTIPLIED_ALPHA | VA_BLEND_LUMA_KEY;
6687     pipeline_caps->num_forward_references     = DDI_CODEC_NUM_FWD_REF;
6688     pipeline_caps->num_backward_references    = DDI_CODEC_NUM_BK_REF;
6689     pipeline_caps->input_color_standards      = vp_input_color_std;
6690     pipeline_caps->num_input_color_standards  = DDI_VP_NUM_INPUT_COLOR_STD;
6691     pipeline_caps->output_color_standards     = vp_output_color_std;
6692     pipeline_caps->num_output_color_standards = DDI_VP_NUM_OUT_COLOR_STD;
6693 
6694     if ((context & DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_DECODER)
6695     {
6696         //Decode+SFC, go SFC path, the restriction here is the capability of SFC
6697         pipeline_caps->num_input_pixel_formats    = 1;
6698         pipeline_caps->input_pixel_format[0]      = VA_FOURCC_NV12;
6699         pipeline_caps->num_output_pixel_formats   = 1;
6700         pipeline_caps->output_pixel_format[0]     = VA_FOURCC_NV12;
6701         if((MEDIA_IS_SKU(&(mediaCtx->SkuTable), FtrHCP2SFCPipe)))
6702         {
6703             pipeline_caps->max_input_width            = DDI_DECODE_HCP_SFC_MAX_WIDTH;
6704             pipeline_caps->max_input_height           = DDI_DECODE_HCP_SFC_MAX_HEIGHT;
6705         }
6706         else
6707         {
6708             pipeline_caps->max_input_width            = DDI_DECODE_SFC_MAX_WIDTH;
6709             pipeline_caps->max_input_height           = DDI_DECODE_SFC_MAX_HEIGHT;
6710         }
6711         pipeline_caps->min_input_width            = DDI_DECODE_SFC_MIN_WIDTH;
6712         pipeline_caps->min_input_height           = DDI_DECODE_SFC_MIN_HEIGHT;
6713         pipeline_caps->max_output_width           = DDI_DECODE_SFC_MAX_WIDTH;
6714         pipeline_caps->max_output_height          = DDI_DECODE_SFC_MAX_HEIGHT;
6715         pipeline_caps->min_output_width           = DDI_DECODE_SFC_MIN_WIDTH;
6716         pipeline_caps->min_output_height          = DDI_DECODE_SFC_MIN_HEIGHT;
6717     }
6718     else if ((context & DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_VP)
6719     {
6720         if(mediaCtx->platform.eRenderCoreFamily <= IGFX_GEN8_CORE)
6721         {
6722             //Capability of Gen8- platform
6723             pipeline_caps->max_input_width            = VP_MAX_PIC_WIDTH_Gen8;
6724             pipeline_caps->max_input_height           = VP_MAX_PIC_HEIGHT_Gen8;
6725             pipeline_caps->max_output_width           = VP_MAX_PIC_WIDTH_Gen8;
6726             pipeline_caps->max_output_height          = VP_MAX_PIC_HEIGHT_Gen8;
6727         }else
6728         {
6729             //Capability of Gen9+ platform
6730             pipeline_caps->max_input_width            = VP_MAX_PIC_WIDTH;
6731             pipeline_caps->max_input_height           = VP_MAX_PIC_HEIGHT;
6732             pipeline_caps->max_output_width           = VP_MAX_PIC_WIDTH;
6733             pipeline_caps->max_output_height          = VP_MAX_PIC_HEIGHT;
6734         }
6735         pipeline_caps->min_input_width            = VP_MIN_PIC_WIDTH;
6736         pipeline_caps->min_input_height           = VP_MIN_PIC_HEIGHT;
6737         pipeline_caps->min_output_width           = VP_MIN_PIC_WIDTH;
6738         pipeline_caps->min_output_height          = VP_MIN_PIC_WIDTH;
6739     }
6740 
6741 
6742     for (int i = 0; i < num_filters; i++) {
6743         void *pData;
6744         DdiMedia_MapBuffer(ctx, filters[i], &pData);
6745         DDI_CHK_NULL(pData, "nullptr pData", VA_STATUS_ERROR_INVALID_PARAMETER);
6746         VAProcFilterParameterBufferBase* base_param = (VAProcFilterParameterBufferBase*) pData;
6747         if (base_param->type == VAProcFilterDeinterlacing)
6748         {
6749             VAProcFilterParameterBufferDeinterlacing *di_param = (VAProcFilterParameterBufferDeinterlacing *)base_param;
6750             if (di_param->algorithm == VAProcDeinterlacingMotionAdaptive ||
6751                 di_param->algorithm == VAProcDeinterlacingMotionCompensated)
6752             {
6753                 pipeline_caps->num_forward_references = 1;
6754             }
6755         }
6756     }
6757     return VA_STATUS_SUCCESS;
6758 }
6759 
6760 /**
6761  * \brief Get surface attributes for the supplied config.
6762  *
6763  * This function retrieves the surface attributes matching the supplied
6764  * config. The caller shall provide an \c attrib_list with all attributes
6765  * to be retrieved. Upon successful return, the attributes in \c attrib_list
6766  * are updated with the requested value. Unknown attributes or attributes
6767  * that are not supported for the given config will have their \c flags
6768  * field set to \c VA_SURFACE_ATTRIB_NOT_SUPPORTED.
6769  *
6770  * param[in] ctx               the VA display
6771  * param[in] config            the config identifying a codec or a video
6772  *     processing pipeline
6773  * param[out] attrib_list        the list of attributes on output, with at
6774  *     least \c type fields filled in, and possibly \c value fields whenever
6775  *     necessary.The updated list of attributes and flags on output
6776  * param[in] num_attribs       the number of attributes supplied in the
6777  *     \c attrib_list array
6778  */
DdiMedia_GetSurfaceAttributes(VADriverContextP ctx,VAConfigID config,VASurfaceAttrib * attrib_list,uint32_t num_attribs)6779 VAStatus DdiMedia_GetSurfaceAttributes(
6780     VADriverContextP    ctx,
6781     VAConfigID          config,
6782     VASurfaceAttrib    *attrib_list,
6783     uint32_t            num_attribs
6784 )
6785 {
6786     DDI_UNUSED(ctx);
6787     DDI_UNUSED(config);
6788     DDI_UNUSED(attrib_list);
6789     DDI_UNUSED(num_attribs);
6790 
6791     DDI_FUNCTION_ENTER();
6792 
6793     VAStatus vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
6794 
6795     return vaStatus;
6796 }
6797 
6798 //!
6799 //! \brief  Aquire buffer handle
6800 //!
6801 //! \param  [in] ctx
6802 //!         Pointer to VA driver context
6803 //! \param  [in] buf_id
6804 //!         VA buffer ID
6805 //! \param  [in] buf_info
6806 //!         VA buffer Info
6807 //!
6808 //! \return VAStatus
6809 //!     VA_STATUS_SUCCESS if success, else fail reason
6810 //!
DdiMedia_AcquireBufferHandle(VADriverContextP ctx,VABufferID buf_id,VABufferInfo * buf_info)6811 VAStatus DdiMedia_AcquireBufferHandle(
6812     VADriverContextP ctx,
6813     VABufferID buf_id,
6814     VABufferInfo *buf_info)
6815 {
6816     DDI_FUNCTION_ENTER();
6817 
6818     DDI_CHK_NULL(ctx,          "nullptr ctx",          VA_STATUS_ERROR_INVALID_CONTEXT);
6819     DDI_CHK_NULL(buf_info,     "nullptr buf_info",     VA_STATUS_ERROR_INVALID_PARAMETER);
6820 
6821     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
6822     DDI_CHK_NULL(mediaCtx,          "Invalid Media ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
6823 
6824     DDI_MEDIA_BUFFER   *buf     = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id);
6825     DDI_CHK_NULL(buf,          "Invalid Media Buffer", VA_STATUS_ERROR_INVALID_BUFFER);
6826     DDI_CHK_NULL(buf->bo,      "Invalid Media Buffer", VA_STATUS_ERROR_INVALID_BUFFER);
6827 
6828     // If user did not specify memtype he want's we use something we prefer, we prefer PRIME
6829     if (!buf_info->mem_type)
6830     {
6831        buf_info->mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
6832     }
6833     // now chekcing memtype whether we support it
6834     if ((buf_info->mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME) &&
6835         (buf_info->mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM))
6836     {
6837         return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
6838     }
6839 
6840     DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
6841     // already acquired?
6842     if (buf->uiExportcount)
6843     {   // yes, already acquired
6844         // can't provide access thru another memtype
6845         if (buf->uiMemtype != buf_info->mem_type)
6846         {
6847             DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
6848             return VA_STATUS_ERROR_INVALID_PARAMETER;
6849         }
6850     }
6851     else
6852     {   // no, not acquired - doing this now
6853         switch (buf_info->mem_type) {
6854         case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: {
6855             uint32_t flink = 0;
6856             if (mos_bo_flink(buf->bo, &flink) != 0)
6857             {
6858                 DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
6859                 return VA_STATUS_ERROR_INVALID_BUFFER;
6860             }
6861             buf->handle = (intptr_t)flink;
6862             break;
6863         }
6864         case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
6865             int32_t prime_fd = 0;
6866             if (mos_bo_export_to_prime(buf->bo, &prime_fd) != 0)
6867             {
6868                 DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
6869                 return VA_STATUS_ERROR_INVALID_BUFFER;
6870             }
6871 
6872             buf->handle = (intptr_t)prime_fd;
6873             break;
6874         }
6875         }
6876         // saving memtepy which was provided to the user
6877         buf->uiMemtype = buf_info->mem_type;
6878     }
6879 
6880     ++buf->uiExportcount;
6881     mos_bo_reference(buf->bo);
6882 
6883     buf_info->type = buf->uiType;
6884     buf_info->handle = buf->handle;
6885     buf_info->mem_size = buf->uiNumElements * buf->iSize;
6886 
6887     DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
6888     return VA_STATUS_SUCCESS;
6889 }
6890 
6891 //!
6892 //! \brief  Release buffer handle
6893 //!
6894 //! \param  [in] ctx
6895 //!         Pointer to VA driver context
6896 //! \param  [in] buf_id
6897 //!         VA bufferID
6898 //!
6899 //! \return VAStatus
6900 //!     VA_STATUS_SUCCESS if success, else fail reason
6901 //!
DdiMedia_ReleaseBufferHandle(VADriverContextP ctx,VABufferID buf_id)6902 VAStatus DdiMedia_ReleaseBufferHandle(
6903     VADriverContextP ctx,
6904     VABufferID buf_id)
6905 {
6906     DDI_FUNCTION_ENTER();
6907 
6908     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
6909 
6910     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
6911     DDI_CHK_NULL(mediaCtx, "Invalid Media ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
6912 
6913     DDI_MEDIA_BUFFER   *buf     = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id);
6914     DDI_CHK_NULL(buf,          "Invalid Media Buffer", VA_STATUS_ERROR_INVALID_BUFFER);
6915     DDI_CHK_NULL(buf->bo,      "Invalid Media Buffer", VA_STATUS_ERROR_INVALID_BUFFER);
6916 
6917     DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
6918     if (!buf->uiMemtype || !buf->uiExportcount)
6919     {
6920         DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
6921         return VA_STATUS_SUCCESS;
6922     }
6923     mos_bo_unreference(buf->bo);
6924     --buf->uiExportcount;
6925 
6926     if (!buf->uiExportcount) {
6927         switch (buf->uiMemtype) {
6928         case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
6929             close((intptr_t)buf->handle);
6930             break;
6931         }
6932         }
6933         buf->uiMemtype = 0;
6934     }
6935     DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
6936 
6937     if (!buf->uiExportcount && buf->bPostponedBufFree) {
6938         MOS_FreeMemory(buf);
6939         DdiMedia_DestroyBufFromVABufferID(mediaCtx, buf_id);
6940     }
6941 
6942     return VA_STATUS_SUCCESS;
6943 }
6944 
DdiMedia_GetPlaneNum(PDDI_MEDIA_SURFACE mediaSurface,bool hasAuxPlane)6945 static uint32_t DdiMedia_GetPlaneNum(PDDI_MEDIA_SURFACE mediaSurface, bool hasAuxPlane)
6946 {
6947     DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface", VA_STATUS_ERROR_INVALID_PARAMETER);
6948 
6949     uint32_t fourcc = DdiMedia_MediaFormatToOsFormat(mediaSurface->format);
6950     uint32_t plane_num = 0;
6951     switch(fourcc)
6952     {
6953         case VA_FOURCC_NV12:
6954         case VA_FOURCC_NV21:
6955         case VA_FOURCC_P010:
6956         case VA_FOURCC_P012:
6957         case VA_FOURCC_P016:
6958             plane_num = hasAuxPlane ? 4 : 2;
6959             break;
6960         case VA_FOURCC_I420:
6961         case VA_FOURCC_YV12:
6962         case VA_FOURCC_411P:
6963         case VA_FOURCC_422H:
6964         case VA_FOURCC_422V:
6965         case VA_FOURCC_444P:
6966         case VA_FOURCC_IMC3:
6967         case VA_FOURCC_RGBP:
6968         case VA_FOURCC_BGRP:
6969             plane_num = 3;
6970             break;
6971         case VA_FOURCC_YUY2:
6972         case VA_FOURCC_UYVY:
6973         case VA_FOURCC_YVYU:
6974         case VA_FOURCC_VYUY:
6975         case VA_FOURCC_Y800:
6976         case VA_FOURCC_Y210:
6977 #if VA_CHECK_VERSION(1, 9, 0)
6978         case VA_FOURCC_Y212:
6979 #endif
6980         case VA_FOURCC_Y216:
6981         case VA_FOURCC_Y410:
6982 #if VA_CHECK_VERSION(1, 9, 0)
6983         case VA_FOURCC_Y412:
6984 #endif
6985         case VA_FOURCC_Y416:
6986         case VA_FOURCC_AYUV:
6987 #if VA_CHECK_VERSION(1, 13, 0)
6988         case VA_FOURCC_XYUV:
6989 #endif
6990         case VA_FOURCC_RGBA:
6991         case VA_FOURCC_RGBX:
6992         case VA_FOURCC_BGRA:
6993         case VA_FOURCC_BGRX:
6994         case VA_FOURCC_ARGB:
6995         case VA_FOURCC_ABGR:
6996         case VA_FOURCC_XRGB:
6997         case VA_FOURCC_XBGR:
6998         case VA_FOURCC_RGB565:
6999         case VA_FOURCC_R8G8B8:
7000         case VA_FOURCC_A2R10G10B10:
7001         case VA_FOURCC_A2B10G10R10:
7002         case VA_FOURCC_X2R10G10B10:
7003         case VA_FOURCC_X2B10G10R10:
7004             plane_num = hasAuxPlane ? 2 : 1;
7005             break;
7006         default:
7007             DDI_ASSERTMESSAGE("Unsupported format.\n");
7008     }
7009     return plane_num;
7010 }
7011 
DdiMedia_GetDrmFormatOfSeparatePlane(uint32_t fourcc,int plane)7012 static uint32_t DdiMedia_GetDrmFormatOfSeparatePlane(uint32_t fourcc, int plane)
7013 {
7014     if (plane == 0)
7015     {
7016         switch (fourcc)
7017         {
7018         case VA_FOURCC_NV12:
7019         case VA_FOURCC_I420:
7020         case VA_FOURCC_IMC3:
7021         case VA_FOURCC_YV12:
7022         case VA_FOURCC_YV16:
7023         case VA_FOURCC_422H:
7024         case VA_FOURCC_422V:
7025         case VA_FOURCC_444P:
7026         case VA_FOURCC_Y800:
7027         case VA_FOURCC_RGBP:
7028         case VA_FOURCC_BGRP:
7029             return DRM_FORMAT_R8;
7030         case VA_FOURCC_P010:
7031         case VA_FOURCC_P012:
7032         case VA_FOURCC_P016:
7033         case VA_FOURCC_I010:
7034             return DRM_FORMAT_R16;
7035 
7036         case VA_FOURCC_YUY2:
7037             return DRM_FORMAT_YUYV;
7038         case VA_FOURCC_YVYU:
7039             return DRM_FORMAT_YVYU;
7040         case VA_FOURCC_VYUY:
7041             return DRM_FORMAT_VYUY;
7042         case VA_FOURCC_UYVY:
7043             return DRM_FORMAT_UYVY;
7044         case VA_FOURCC_AYUV:
7045             return DRM_FORMAT_AYUV;
7046 #if VA_CHECK_VERSION(1, 13, 0)
7047         case VA_FOURCC_XYUV:
7048             return DRM_FORMAT_XYUV8888;
7049 #endif
7050         case VA_FOURCC_Y210:
7051             return DRM_FORMAT_Y210;
7052         case VA_FOURCC_Y216:
7053             return DRM_FORMAT_Y216;
7054         case VA_FOURCC_Y410:
7055             return DRM_FORMAT_Y410;
7056         case VA_FOURCC_Y416:
7057             return DRM_FORMAT_Y416;
7058 #if VA_CHECK_VERSION(1, 9, 0)
7059         case VA_FOURCC_Y212:
7060             return DRM_FORMAT_Y216;
7061         case VA_FOURCC_Y412:
7062             return DRM_FORMAT_Y416;
7063 #endif
7064 
7065         case VA_FOURCC_ARGB:
7066             return DRM_FORMAT_ARGB8888;
7067         case VA_FOURCC_ABGR:
7068             return DRM_FORMAT_ABGR8888;
7069         case VA_FOURCC_RGBA:
7070             return DRM_FORMAT_RGBA8888;
7071         case VA_FOURCC_BGRA:
7072             return DRM_FORMAT_BGRA8888;
7073         case VA_FOURCC_XRGB:
7074             return DRM_FORMAT_XRGB8888;
7075         case VA_FOURCC_XBGR:
7076             return DRM_FORMAT_XBGR8888;
7077         case VA_FOURCC_RGBX:
7078             return DRM_FORMAT_RGBX8888;
7079         case VA_FOURCC_BGRX:
7080             return DRM_FORMAT_BGRX8888;
7081         case VA_FOURCC_A2R10G10B10:
7082             return DRM_FORMAT_ARGB2101010;
7083         case VA_FOURCC_A2B10G10R10:
7084             return DRM_FORMAT_ABGR2101010;
7085         case VA_FOURCC_X2R10G10B10:
7086             return DRM_FORMAT_XRGB2101010;
7087         case VA_FOURCC_X2B10G10R10:
7088             return DRM_FORMAT_XBGR2101010;
7089         }
7090     }
7091     else
7092     {
7093         switch (fourcc)
7094         {
7095         case VA_FOURCC_NV12:
7096             return DRM_FORMAT_GR88;
7097         case VA_FOURCC_I420:
7098         case VA_FOURCC_IMC3:
7099         case VA_FOURCC_YV12:
7100         case VA_FOURCC_YV16:
7101         case VA_FOURCC_422H:
7102         case VA_FOURCC_422V:
7103         case VA_FOURCC_444P:
7104         case VA_FOURCC_RGBP:
7105         case VA_FOURCC_BGRP:
7106             return DRM_FORMAT_R8;
7107         case VA_FOURCC_P010:
7108         case VA_FOURCC_P012:
7109         case VA_FOURCC_P016:
7110             return DRM_FORMAT_GR1616;
7111         case VA_FOURCC_I010:
7112             return DRM_FORMAT_R16;
7113         }
7114     }
7115     return 0;
7116 }
DdiMedia_GetDrmFormatOfCompositeObject(uint32_t fourcc)7117 static uint32_t DdiMedia_GetDrmFormatOfCompositeObject(uint32_t fourcc)
7118 {
7119     switch (fourcc)
7120     {
7121     case VA_FOURCC_NV12:
7122         return DRM_FORMAT_NV12;
7123     case VA_FOURCC_I420:
7124         return DRM_FORMAT_YUV420;
7125     case VA_FOURCC_IMC3:
7126         return DRM_FORMAT_YUV420;
7127     case VA_FOURCC_YV12:
7128         return DRM_FORMAT_YVU420;
7129     case VA_FOURCC_YV16:
7130         return DRM_FORMAT_YVU422;
7131     case VA_FOURCC_422H:
7132         return DRM_FORMAT_YUV422;
7133     case VA_FOURCC_422V:
7134         return DRM_FORMAT_YUV422;
7135     case VA_FOURCC_444P:
7136         return DRM_FORMAT_YUV444;
7137     case VA_FOURCC_YUY2:
7138         return DRM_FORMAT_YUYV;
7139     case VA_FOURCC_YVYU:
7140         return DRM_FORMAT_YVYU;
7141     case VA_FOURCC_VYUY:
7142         return DRM_FORMAT_VYUY;
7143     case VA_FOURCC_UYVY:
7144         return DRM_FORMAT_UYVY;
7145     case VA_FOURCC_AYUV:
7146         return DRM_FORMAT_AYUV;
7147 #if VA_CHECK_VERSION(1, 13, 0)
7148     case VA_FOURCC_XYUV:
7149         return DRM_FORMAT_XYUV8888;
7150 #endif
7151     case VA_FOURCC_Y210:
7152         return DRM_FORMAT_Y210;
7153 #if VA_CHECK_VERSION(1, 9, 0)
7154     case VA_FOURCC_Y212:
7155         return DRM_FORMAT_Y216;
7156 #endif
7157     case VA_FOURCC_Y216:
7158         return DRM_FORMAT_Y216;
7159     case VA_FOURCC_Y410:
7160         return DRM_FORMAT_Y410;
7161 #if VA_CHECK_VERSION(1, 9, 0)
7162     case VA_FOURCC_Y412:
7163         return DRM_FORMAT_Y416;
7164 #endif
7165     case VA_FOURCC_Y416:
7166         return DRM_FORMAT_Y416;
7167     case VA_FOURCC_Y800:
7168         return DRM_FORMAT_R8;
7169     case VA_FOURCC_P010:
7170         return DRM_FORMAT_P010;
7171     case VA_FOURCC_P012:
7172         return DRM_FORMAT_P016;
7173     case VA_FOURCC_P016:
7174         return DRM_FORMAT_P016;
7175     case VA_FOURCC_ARGB:
7176         return DRM_FORMAT_ARGB8888;
7177     case VA_FOURCC_ABGR:
7178         return DRM_FORMAT_ABGR8888;
7179     case VA_FOURCC_RGBA:
7180         return DRM_FORMAT_RGBA8888;
7181     case VA_FOURCC_BGRA:
7182         return DRM_FORMAT_BGRA8888;
7183     case VA_FOURCC_XRGB:
7184         return DRM_FORMAT_XRGB8888;
7185     case VA_FOURCC_XBGR:
7186         return DRM_FORMAT_XBGR8888;
7187     case VA_FOURCC_RGBX:
7188         return DRM_FORMAT_RGBX8888;
7189     case VA_FOURCC_BGRX:
7190         return DRM_FORMAT_BGRX8888;
7191     case VA_FOURCC_A2R10G10B10:
7192         return DRM_FORMAT_ARGB2101010;
7193     case VA_FOURCC_A2B10G10R10:
7194         return DRM_FORMAT_ABGR2101010;
7195     case VA_FOURCC_X2R10G10B10:
7196         return DRM_FORMAT_XRGB2101010;
7197     case VA_FOURCC_X2B10G10R10:
7198         return DRM_FORMAT_XBGR2101010;
7199     }
7200     return 0;
7201 }
7202 
7203 
7204 //!
7205 //! \brief   API for export surface handle to other component
7206 //!
7207 //! \param [in] dpy
7208 //!          VA display.
7209 //! \param [in] surface_id
7210 //!          Surface to export.
7211 //! \param [in] mem_type
7212 //!          Memory type to export to.
7213 //! \param [in] flags
7214 //!          Combination of flags to apply
7215 //!\param [out] descriptor
7216 //!Pointer to the descriptor structure to fill
7217 //!with the handle details.  The type of this structure depends on
7218 //!the value of mem_type.
7219 //! \return VAStatus
7220 //!     VA_STATUS_SUCCESS if success, else fail reason
7221 //!
DdiMedia_ExportSurfaceHandle(VADriverContextP ctx,VASurfaceID surface_id,uint32_t mem_type,uint32_t flags,void * descriptor)7222 VAStatus DdiMedia_ExportSurfaceHandle(
7223     VADriverContextP ctx,
7224     VASurfaceID surface_id,
7225     uint32_t mem_type,
7226     uint32_t flags,
7227     void * descriptor)
7228 {
7229     DDI_CHK_NULL(descriptor,    "nullptr descriptor",   VA_STATUS_ERROR_INVALID_PARAMETER);
7230     DDI_CHK_NULL(ctx,                     "nullptr ctx",                     VA_STATUS_ERROR_INVALID_CONTEXT);
7231 
7232     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
7233     DDI_CHK_NULL(mediaCtx,               "nullptr mediaCtx",               VA_STATUS_ERROR_INVALID_CONTEXT);
7234     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
7235     DDI_CHK_LESS((uint32_t)(surface_id), mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surfaces", VA_STATUS_ERROR_INVALID_SURFACE);
7236 
7237     DDI_MEDIA_SURFACE  *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface_id);
7238     DDI_CHK_NULL(mediaSurface,                   "nullptr mediaSurface",                   VA_STATUS_ERROR_INVALID_SURFACE);
7239     DDI_CHK_NULL(mediaSurface->bo,               "nullptr mediaSurface->bo",               VA_STATUS_ERROR_INVALID_SURFACE);
7240     DDI_CHK_NULL(mediaSurface->pGmmResourceInfo, "nullptr mediaSurface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_SURFACE);
7241 
7242     if (
7243 #if VA_CHECK_VERSION(1, 21, 0)
7244         mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3 &&
7245 #endif
7246         mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
7247     {
7248         DDI_ASSERTMESSAGE("vaExportSurfaceHandle: memory type %08x is not supported.\n", mem_type);
7249         return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
7250     }
7251 
7252     if (mos_bo_export_to_prime(mediaSurface->bo, (int32_t*)&mediaSurface->name))
7253     {
7254         DDI_ASSERTMESSAGE("Failed drm_intel_gem_export_to_prime operation!!!\n");
7255         return VA_STATUS_ERROR_OPERATION_FAILED;
7256     }
7257 
7258     VADRMPRIMESurfaceDescriptor *desc = (VADRMPRIMESurfaceDescriptor *)descriptor;
7259 
7260 #if VA_CHECK_VERSION(1, 21, 0)
7261     if(mem_type == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3)
7262     {
7263         VADRMPRIME3SurfaceDescriptor *desc = (VADRMPRIME3SurfaceDescriptor *)descriptor;
7264         if(mediaSurface->pGmmResourceInfo->GetSetCpSurfTag(false, 0))
7265         {
7266             desc->flags |= VA_SURFACE_EXTBUF_DESC_PROTECTED;
7267         }
7268     }
7269 #endif
7270 
7271     desc->fourcc = DdiMedia_MediaFormatToOsFormat(mediaSurface->format);
7272     if(desc->fourcc == VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT)
7273     {
7274         // close the handle to avoid leak
7275         close(mediaSurface->name);
7276         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
7277     }
7278     desc->width           = mediaSurface->iWidth;
7279     desc->height          = mediaSurface->iRealHeight;
7280     desc->num_objects     = 1;
7281     desc->objects[0].fd   = mediaSurface->name;
7282     desc->objects[0].size = mediaSurface->pGmmResourceInfo->GetSizeSurface();
7283 
7284     DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
7285 
7286     if(VA_STATUS_SUCCESS != mediaCtx->m_caps->GetSurfaceModifier(mediaSurface, desc->objects[0].drm_format_modifier))
7287     {
7288         close(mediaSurface->name);
7289         DDI_ASSERTMESSAGE("could not find related modifier values");
7290         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
7291     }
7292 
7293     int composite_object = flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS;
7294 
7295     uint32_t formats[4];
7296 
7297     // Query Aux Plane info form GMM
7298     bool hasAuxPlane           = false;
7299     GMM_RESOURCE_FLAG GmmFlags = mediaSurface->pGmmResourceInfo->GetResFlags();
7300 
7301     if (((GmmFlags.Gpu.MMC                           ||
7302           GmmFlags.Gpu.CCS)                          &&
7303          (GmmFlags.Info.MediaCompressed              ||
7304           GmmFlags.Info.RenderCompressed)            &&
7305           mediaCtx->m_auxTableMgr) )
7306           {
7307               hasAuxPlane = true;
7308           }
7309           else
7310           {
7311               hasAuxPlane = false;
7312           }
7313 
7314     uint32_t num_planes = DdiMedia_GetPlaneNum(mediaSurface, hasAuxPlane);
7315 
7316     if(composite_object)
7317     {
7318         formats[0] = DdiMedia_GetDrmFormatOfCompositeObject(desc->fourcc);
7319         if(!formats[0])
7320         {
7321             close(mediaSurface->name);
7322             DDI_ASSERTMESSAGE("vaExportSurfaceHandle: fourcc %08x is not supported for export as a composite object.\n", desc->fourcc);
7323             return VA_STATUS_ERROR_INVALID_SURFACE;
7324         }
7325     }
7326     else
7327     {
7328         for (int i = 0; i < num_planes; i++)
7329         {
7330             formats[i] = DdiMedia_GetDrmFormatOfSeparatePlane(desc->fourcc,i);
7331             if (!formats[i])
7332             {
7333                 close(mediaSurface->name);
7334                 DDI_ASSERTMESSAGE("vaExportSurfaceHandle: fourcc %08x is not supported for export as separate planes.\n", desc->fourcc);
7335                 return VA_STATUS_ERROR_INVALID_SURFACE;
7336             }
7337         }
7338     }
7339 
7340     uint32_t pitch, height, chromaPitch, chromaHeight = 0;
7341     pitch = mediaSurface->iPitch;
7342     height = mediaSurface->iRealHeight;
7343     DdiMedia_GetChromaPitchHeight(desc->fourcc, pitch, height, &chromaPitch, &chromaHeight);
7344 
7345     // Get Yoffset from GMM
7346     GMM_REQ_OFFSET_INFO reqInfo = {0};
7347     reqInfo.Plane               = GMM_PLANE_Y;
7348     reqInfo.ReqRender           = 1;
7349     mediaSurface->pGmmResourceInfo->GetOffset(reqInfo);
7350     uint32_t offsetY            = reqInfo.Render.Offset;
7351 
7352     // Get Uoffset from GMM
7353     MOS_ZeroMemory(&reqInfo, sizeof(GMM_REQ_OFFSET_INFO));
7354     reqInfo.Plane               = GMM_PLANE_U;
7355     reqInfo.ReqRender           = 1;
7356     mediaSurface->pGmmResourceInfo->GetOffset(reqInfo);
7357     uint32_t offsetU            = reqInfo.Render.Offset;
7358 
7359     // Get Voffset from GMM
7360     MOS_ZeroMemory(&reqInfo, sizeof(GMM_REQ_OFFSET_INFO));
7361     reqInfo.Plane               = GMM_PLANE_V;
7362     reqInfo.ReqRender           = 1;
7363     mediaSurface->pGmmResourceInfo->GetOffset(reqInfo);
7364     uint32_t offsetV            = reqInfo.Render.Offset;
7365 
7366     // Get Aux Plane offset
7367     uint32_t auxOffsetY = (uint32_t)mediaSurface->pGmmResourceInfo->GetPlanarAuxOffset(0, GMM_AUX_Y_CCS);
7368     uint32_t auxOffsetUV = (uint32_t)mediaSurface->pGmmResourceInfo->GetPlanarAuxOffset(0, GMM_AUX_UV_CCS);
7369 
7370     if (composite_object) {
7371         desc->num_layers = 1;
7372         desc->layers[0].drm_format = formats[0];
7373         desc->layers[0].num_planes = num_planes;
7374         if (hasAuxPlane)
7375         {
7376             // For semi-planar formats like NV12, CCS planes follow the Y and UV planes,
7377             // i.e. planes 0 and 1 are used for Y and UV surfaces, planes 2 and 3 for the respective CCS.
7378             for (int i = 0; i < num_planes/2; i++)
7379             {
7380                 desc->layers[0].object_index[2*i] = 0;
7381                 desc->layers[0].object_index[2*i+1] = 0;
7382                 if (i == 0)
7383                 {
7384                     // Y plane
7385                     desc->layers[0].offset[i] = offsetY;
7386                     desc->layers[0].pitch[i]  = mediaSurface->iPitch;
7387                     // Y aux plane
7388                     desc->layers[0].offset[i + num_planes/2] = auxOffsetY;
7389                     desc->layers[0].pitch[i + num_planes/2] = mediaSurface->iPitch/8;
7390                 }
7391                 else
7392                 {
7393                     // UV plane
7394                     desc->layers[0].offset[i] = offsetU;
7395                     desc->layers[0].pitch[i]  = mediaSurface->iPitch;
7396                     // UV aux plane
7397                     desc->layers[0].offset[i + num_planes/2] = auxOffsetUV;
7398                     desc->layers[0].pitch[i + num_planes/2] = mediaSurface->iPitch/8;
7399                 }
7400             }
7401         }else
7402         {
7403             for (int i = 0; i < num_planes; i++)
7404             {
7405                 desc->layers[0].object_index[i] = 0;
7406                 switch(i)
7407                 {
7408                 case 0:
7409                     desc->layers[0].offset[i] = offsetY;
7410                     desc->layers[0].pitch[i]  = pitch;
7411                     break;
7412                 case 1:
7413                     if (desc->fourcc == VA_FOURCC_YV12)
7414                     {
7415                         desc->layers[0].offset[i] = offsetV;
7416                     }
7417                     else
7418                     {
7419                         desc->layers[0].offset[i] = offsetU;
7420                     }
7421                     desc->layers[0].pitch[i]  = chromaPitch;
7422                     break;
7423                 case 2:
7424                     if (desc->fourcc == VA_FOURCC_YV12)
7425                     {
7426                         desc->layers[0].offset[i] = offsetU;
7427                     }
7428                     else
7429                     {
7430                         desc->layers[0].offset[i] = offsetV;
7431                     }
7432                     desc->layers[0].pitch[i]  = chromaPitch;
7433                     break;
7434                 default:
7435                     DDI_ASSERTMESSAGE("vaExportSurfaceHandle: invalid plan numbers");
7436                 }
7437             }
7438         }
7439     }
7440     else
7441     {
7442         if (hasAuxPlane)
7443         {
7444             desc->num_layers = num_planes / 2;
7445 
7446             for (int i = 0; i < desc->num_layers; i++)
7447             {
7448                 desc->layers[i].drm_format = formats[i];
7449                 desc->layers[i].num_planes = 2;
7450 
7451                 desc->layers[i].object_index[0] = 0;
7452 
7453                 if (i == 0)
7454                 {
7455                     desc->layers[i].offset[0] = offsetY;
7456                     desc->layers[i].offset[1] = auxOffsetY;
7457                     desc->layers[i].pitch[0]  = mediaSurface->iPitch;
7458                     desc->layers[i].pitch[1]  = mediaSurface->iPitch/8;
7459                 }
7460                 else
7461                 {
7462                     desc->layers[i].offset[0] = offsetU;
7463                     desc->layers[i].offset[1] = auxOffsetUV;
7464                     desc->layers[i].pitch[0]  = mediaSurface->iPitch;
7465                     desc->layers[i].pitch[1]  = mediaSurface->iPitch/8;
7466                 }
7467             }
7468         }else
7469         {
7470             desc->num_layers = num_planes;
7471 
7472             for (int i = 0; i < num_planes; i++)
7473             {
7474                 desc->layers[i].drm_format = formats[i];
7475                 desc->layers[i].num_planes = 1;
7476 
7477                 desc->layers[i].object_index[0] = 0;
7478 
7479                 switch(i)
7480                 {
7481                 case 0:
7482                     desc->layers[i].offset[0] = offsetY;
7483                     desc->layers[i].pitch[0]  = pitch;
7484                     break;
7485                 case 1:
7486                     if (desc->fourcc == VA_FOURCC_YV12)
7487                     {
7488                         desc->layers[i].offset[0] = offsetV;
7489                     }
7490                     else
7491                     {
7492                         desc->layers[i].offset[0] = offsetU;
7493                     }
7494                     desc->layers[i].pitch[0]  = chromaPitch;
7495                     break;
7496                 case 2:
7497                     if (desc->fourcc == VA_FOURCC_YV12)
7498                     {
7499                         desc->layers[i].offset[0] = offsetU;
7500                     }
7501                     else
7502                     {
7503                         desc->layers[i].offset[0] = offsetV;
7504                     }
7505                     desc->layers[i].pitch[0]  = chromaPitch;
7506                     break;
7507                 default:
7508                     DDI_ASSERTMESSAGE("vaExportSurfaceHandle: invalid plan numbers");
7509                 }
7510             }
7511         }
7512     }
7513 
7514     return VA_STATUS_SUCCESS;
7515 }
7516 
7517 //!
7518 //! \brief  Init VA driver 0.31
7519 //!
7520 //! \param  [in] ctx
7521 //!         Pointer to VA driver context
7522 //!
7523 //! \return VAStatus
7524 //!     VA_STATUS_SUCCESS if success, else fail reason
7525 //!
__vaDriverInit(VADriverContextP ctx)7526 VAStatus __vaDriverInit(VADriverContextP ctx )
7527 {
7528     return DdiMedia__Initialize(ctx, nullptr, nullptr);
7529 }
7530 
7531 #ifdef __cplusplus
7532 extern "C" {
7533 #endif
7534 
7535 //!
7536 //! \brief Get VA_MAJOR_VERSION and VA_MINOR_VERSION from libva
7537 //!         To form the function name in the format of _vaDriverInit_[VA_MAJOR_VERSION]_[VA_MINOR_VERSION]
7538 //!
7539 #define VA_DRV_INIT_DEF(_major,_minor) __vaDriverInit_##_major##_##_minor
7540 #define VA_DRV_INIT_FUNC(va_major_version, va_minor_version) VA_DRV_INIT_DEF(va_major_version,va_minor_version)
7541 #define VA_DRV_INIT_FUC_NAME VA_DRV_INIT_FUNC(VA_MAJOR_VERSION,VA_MINOR_VERSION)
7542 
7543 //!
7544 //! \brief  VA driver init function name
7545 //!
7546 //! \param  [in] ctx
7547 //!         Pointer to VA driver context
7548 //!
7549 //! \return VAStatus
7550 //!     VA_STATUS_SUCCESS if success, else fail reason
7551 //!
VA_DRV_INIT_FUC_NAME(VADriverContextP ctx)7552 MEDIAAPI_EXPORT VAStatus VA_DRV_INIT_FUC_NAME(VADriverContextP ctx )
7553 {
7554     return __vaDriverInit(ctx);
7555 }
7556 
7557 //!
7558 //! \brief  Private API for openCL
7559 //!
7560 //! \param  [in] dpy
7561 //!         VA display
7562 //! \param  [in] surface
7563 //!         VA surface ID
7564 //! \param  [in] prime_fd
7565 //!         Prime fd
7566 //!
7567 //! \return VAStatus
7568 //!     VA_STATUS_SUCCESS if success, else fail reason
7569 //!
DdiMedia_ExtGetSurfaceHandle(VADisplay dpy,VASurfaceID * surface,int32_t * prime_fd)7570 MEDIAAPI_EXPORT VAStatus DdiMedia_ExtGetSurfaceHandle(
7571     VADisplay      dpy,
7572     VASurfaceID   *surface,
7573     int32_t       *prime_fd)
7574 {
7575     DDI_CHK_NULL(dpy,                     "nullptr dpy",                     VA_STATUS_ERROR_INVALID_DISPLAY);
7576     DDI_CHK_NULL(surface,                 "nullptr surfaces",                VA_STATUS_ERROR_INVALID_PARAMETER);
7577     DDI_CHK_NULL(prime_fd,                "nullptr id",                      VA_STATUS_ERROR_INVALID_PARAMETER);
7578 
7579     VADriverContextP   ctx      = ((VADisplayContextP)dpy)->pDriverContext;
7580     DDI_CHK_NULL(ctx,                     "nullptr ctx",                     VA_STATUS_ERROR_INVALID_CONTEXT);
7581 
7582     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
7583     DDI_CHK_NULL(mediaCtx,               "nullptr mediaCtx",               VA_STATUS_ERROR_INVALID_CONTEXT);
7584     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT);
7585     DDI_CHK_LESS((uint32_t)(*surface), mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surfaces", VA_STATUS_ERROR_INVALID_SURFACE);
7586 
7587     DDI_MEDIA_SURFACE  *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, *surface);
7588     if (mediaSurface)
7589     {
7590         if (mediaSurface->bo)
7591         {
7592             int32_t ret = mos_bo_export_to_prime(mediaSurface->bo, (int32_t*)&mediaSurface->name);
7593             if (ret)
7594             {
7595                 //LOGE("Failed drm_intel_gem_export_to_prime operation!!!\n");
7596                 return VA_STATUS_ERROR_OPERATION_FAILED;
7597             }
7598         }
7599     }
7600     else
7601     {
7602         return VA_STATUS_ERROR_INVALID_SURFACE;
7603     }
7604 
7605     *prime_fd = mediaSurface->name;
7606 
7607     return VA_STATUS_SUCCESS;
7608 }
7609 
7610 //!
7611 //! \brief  Map buffer 2
7612 //!
7613 //! \param  [in] dpy
7614 //!         VA display
7615 //! \param  [in] buf_id
7616 //!         VA buffer ID
7617 //! \param  [out] pbuf
7618 //!         Pointer to buffer
7619 //! \param  [in] flag
7620 //!         Flag
7621 //!
7622 //! \return VAStatus
7623 //!     VA_STATUS_SUCCESS if success, else fail reason
7624 //!
DdiMedia_MapBuffer2(VADisplay dpy,VABufferID buf_id,void ** pbuf,int32_t flag)7625 MEDIAAPI_EXPORT VAStatus DdiMedia_MapBuffer2(
7626     VADisplay           dpy,
7627     VABufferID          buf_id,
7628     void              **pbuf,
7629     int32_t             flag
7630 )
7631 {
7632     DDI_CHK_NULL(dpy,                     "nullptr dpy",                     VA_STATUS_ERROR_INVALID_DISPLAY);
7633 
7634     VADriverContextP ctx = ((VADisplayContextP)dpy)->pDriverContext;
7635 
7636     if ((flag == 0) || (flag & ~(MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY)))
7637         return VA_STATUS_ERROR_INVALID_PARAMETER;
7638 
7639     return DdiMedia_MapBufferInternal(ctx, buf_id, pbuf, flag);
7640 }
7641 
7642 #ifdef __cplusplus
7643 }
7644 #endif
7645 
7646