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