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