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