1 /*
2 * Copyright (c) 2015-2019, 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 //! \file media_libva_common.cpp
23 //! \brief libva(and its extension) interface implemantation common functions
24 //!
25
26 #include "media_libva.h"
27 #include "media_libva_util.h"
28 #include "mos_solo_generic.h"
29 #include "mos_interface.h"
30
DdiMedia_GetVaContextFromHeap(PDDI_MEDIA_HEAP mediaHeap,uint32_t index,PMEDIA_MUTEX_T mutex)31 static void* DdiMedia_GetVaContextFromHeap(PDDI_MEDIA_HEAP mediaHeap, uint32_t index, PMEDIA_MUTEX_T mutex)
32 {
33 PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaCtxHeapElmt = nullptr;
34 void *context = nullptr;
35
36 DdiMediaUtil_LockMutex(mutex);
37 if(nullptr == mediaHeap || index >= mediaHeap->uiAllocatedHeapElements)
38 {
39 DdiMediaUtil_UnLockMutex(mutex);
40 return nullptr;
41 }
42 vaCtxHeapElmt = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)mediaHeap->pHeapBase;
43 vaCtxHeapElmt += index;
44 context = vaCtxHeapElmt->pVaContext;
45 DdiMediaUtil_UnLockMutex(mutex);
46
47 return context;
48 }
49
DdiMedia_MediaSurfaceToMosResource(DDI_MEDIA_SURFACE * mediaSurface,MOS_RESOURCE * mosResource)50 void DdiMedia_MediaSurfaceToMosResource(DDI_MEDIA_SURFACE *mediaSurface, MOS_RESOURCE *mosResource)
51 {
52 DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface",);
53 DDI_CHK_NULL(mosResource, "nullptr mosResource",);
54 DDI_ASSERT(mosResource->bo);
55
56 if (g_apoMosEnabled)
57 {
58 MosInterface::ConvertResourceFromDdi(mediaSurface, mosResource, OS_SPECIFIC_RESOURCE_SURFACE, 0);
59 return;
60 }
61
62 switch (mediaSurface->format)
63 {
64 case Media_Format_NV12:
65 mosResource->Format = Format_NV12;
66 break;
67 case Media_Format_NV21:
68 mosResource->Format = Format_NV21;
69 break;
70 case Media_Format_YUY2:
71 mosResource->Format = Format_YUY2;
72 break;
73 case Media_Format_X8R8G8B8:
74 mosResource->Format = Format_X8R8G8B8;
75 break;
76 case Media_Format_X8B8G8R8:
77 mosResource->Format = Format_X8B8G8R8;
78 break;
79 case Media_Format_A8B8G8R8:
80 case Media_Format_R8G8B8A8:
81 mosResource->Format = Format_A8B8G8R8;
82 break;
83 case Media_Format_A8R8G8B8:
84 mosResource->Format = Format_A8R8G8B8;
85 break;
86 case Media_Format_R5G6B5:
87 mosResource->Format = Format_R5G6B5;
88 break;
89 case Media_Format_R8G8B8:
90 mosResource->Format = Format_R8G8B8;
91 break;
92 case Media_Format_RGBP:
93 mosResource->Format = Format_RGBP;
94 break;
95 case Media_Format_BGRP:
96 mosResource->Format = Format_BGRP;
97 break;
98 case Media_Format_444P:
99 mosResource->Format = Format_444P;
100 break;
101 case Media_Format_411P:
102 mosResource->Format = Format_411P;
103 break;
104 case Media_Format_IMC3:
105 mosResource->Format = Format_IMC3;
106 break;
107 case Media_Format_400P:
108 mosResource->Format = Format_400P;
109 break;
110 case Media_Format_422H:
111 mosResource->Format = Format_422H;
112 break;
113 case Media_Format_422V:
114 mosResource->Format = Format_422V;
115 break;
116 case Media_Format_Buffer:
117 mosResource->Format = Format_Any;
118 case Media_Format_P010:
119 mosResource->Format = Format_P010;
120 break;
121 case Media_Format_P016:
122 mosResource->Format = Format_P016;
123 break;
124 case Media_Format_Y210:
125 mosResource->Format = Format_Y210;
126 break;
127 case Media_Format_Y216:
128 mosResource->Format = Format_Y216;
129 break;
130 case Media_Format_AYUV:
131 mosResource->Format = Format_AYUV;
132 break;
133 case Media_Format_Y410:
134 mosResource->Format = Format_Y410;
135 break;
136 case Media_Format_Y416:
137 mosResource->Format = Format_Y416;
138 break;
139 case Media_Format_Y8:
140 mosResource->Format = Format_Y8;
141 break;
142 case Media_Format_Y16S:
143 mosResource->Format = Format_Y16S;
144 break;
145 case Media_Format_Y16U:
146 mosResource->Format = Format_Y16U;
147 break;
148 case Media_Format_R10G10B10A2:
149 case Media_Format_R10G10B10X2:
150 mosResource->Format = Format_R10G10B10A2;
151 break;
152 case Media_Format_B10G10R10A2:
153 case Media_Format_B10G10R10X2:
154 mosResource->Format = Format_B10G10R10A2;
155 break;
156 case Media_Format_UYVY:
157 mosResource->Format = Format_UYVY;
158 break;
159 case Media_Format_VYUY:
160 mosResource->Format = Format_VYUY;
161 break;
162 case Media_Format_YVYU:
163 mosResource->Format = Format_YVYU;
164 break;
165 case Media_Format_A16R16G16B16:
166 mosResource->Format = Format_A16R16G16B16;
167 break;
168 case Media_Format_A16B16G16R16:
169 mosResource->Format = Format_A16B16G16R16;
170 break;
171 default:
172 DDI_ASSERTMESSAGE("DDI: unsupported media format for surface.");
173 break;
174 }
175 mosResource->iWidth = mediaSurface->iWidth;
176 mosResource->iHeight = mediaSurface->iHeight;
177 mosResource->iPitch = mediaSurface->iPitch;
178 mosResource->iCount = mediaSurface->iRefCount;
179 mosResource->isTiled = mediaSurface->isTiled;
180 mosResource->TileType = LinuxToMosTileType(mediaSurface->TileType);
181 mosResource->bo = mediaSurface->bo;
182 mosResource->name = mediaSurface->name;
183
184 mosResource->ppCurrentFrameSemaphore = &mediaSurface->pCurrentFrameSemaphore;
185 mosResource->ppReferenceFrameSemaphore = &mediaSurface->pReferenceFrameSemaphore;
186 mosResource->bSemInitialized = false;
187 mosResource->bMapped = false;
188
189 if(mediaSurface->bMapped == true)
190 {
191 mosResource->pData = mediaSurface->pData;
192 }
193 else
194 {
195 mosResource->pData = nullptr;
196 }
197 mosResource->pGmmResInfo = mediaSurface->pGmmResourceInfo;
198 mosResource->dwGfxAddress = 0;
199
200 // for MOS wrapper
201 mosResource->bConvertedFromDDIResource = true;
202
203 Mos_Solo_SetOsResource(mediaSurface->pGmmResourceInfo, mosResource);
204
205 }
206
DdiMedia_MediaBufferToMosResource(DDI_MEDIA_BUFFER * mediaBuffer,MOS_RESOURCE * mosResource)207 void DdiMedia_MediaBufferToMosResource(DDI_MEDIA_BUFFER *mediaBuffer, MOS_RESOURCE *mosResource)
208 {
209 DDI_CHK_NULL(mediaBuffer, "nullptr mediaBuffer",);
210 DDI_CHK_NULL(mosResource, "nullptr mosResource",);
211 DDI_ASSERT(mediaBuffer->bo);
212
213 if (g_apoMosEnabled)
214 {
215 MosInterface::ConvertResourceFromDdi(mediaBuffer, mosResource, OS_SPECIFIC_RESOURCE_BUFFER, 0);
216 return;
217 }
218
219 switch (mediaBuffer->format)
220 {
221 case Media_Format_Buffer:
222 mosResource->Format = Format_Buffer;
223 mosResource->iWidth = mediaBuffer->iSize;
224 mosResource->iHeight = 1;
225 mosResource->iPitch = mediaBuffer->iSize;
226 break;
227 case Media_Format_Perf_Buffer:
228 mosResource->Format = Format_Buffer;
229 mosResource->iWidth = mediaBuffer->iSize;
230 mosResource->iHeight = 1;
231 mosResource->iPitch = mediaBuffer->iSize;
232 break;
233 case Media_Format_2DBuffer:
234 mosResource->Format = Format_Buffer_2D;
235 mosResource->iWidth = mediaBuffer->uiWidth;
236 mosResource->iHeight = mediaBuffer->uiHeight;
237 mosResource->iPitch = mediaBuffer->uiPitch;
238 break;
239 case Media_Format_CPU:
240 return;
241 default:
242 mosResource->iWidth = mediaBuffer->iSize;
243 mosResource->iHeight = 1;
244 mosResource->iPitch = mediaBuffer->iSize;
245 DDI_ASSERTMESSAGE("DDI: unsupported media format for surface.");
246 break;
247 }
248 mosResource->iCount = mediaBuffer->iRefCount;
249 mosResource->isTiled = 0;
250 mosResource->TileType = LinuxToMosTileType(mediaBuffer->TileType);
251 mosResource->bo = mediaBuffer->bo;
252 mosResource->name = mediaBuffer->name;
253 mosResource->bMapped = false;
254
255 if(mediaBuffer->bMapped == true)
256 {
257 mosResource->pData = mediaBuffer->pData;
258 }
259 else
260 {
261 mosResource->pData = nullptr;
262 }
263 mosResource->dwGfxAddress = 0;
264 mosResource->pGmmResInfo = mediaBuffer->pGmmResourceInfo;
265
266 // for MOS wrapper
267 mosResource->bConvertedFromDDIResource = true;
268
269 Mos_Solo_SetOsResource(mediaBuffer->pGmmResourceInfo, mosResource);
270 }
271
DdiMedia_GetContextFromContextID(VADriverContextP ctx,VAContextID vaCtxID,uint32_t * ctxType)272 void* DdiMedia_GetContextFromContextID (VADriverContextP ctx, VAContextID vaCtxID, uint32_t *ctxType)
273 {
274 PDDI_MEDIA_CONTEXT mediaCtx = nullptr;
275 uint32_t index = 0;
276
277 DDI_CHK_NULL(ctx, "nullptr ctx", nullptr);
278 DDI_CHK_NULL(ctxType, "nullptr ctxType", nullptr);
279
280 mediaCtx = DdiMedia_GetMediaContext(ctx);
281 index = vaCtxID & DDI_MEDIA_MASK_VACONTEXTID;
282
283 if (index >= DDI_MEDIA_MAX_INSTANCE_NUMBER)
284 return nullptr;
285 if ((vaCtxID&DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_CENC)
286 {
287 DDI_VERBOSEMESSAGE("Cenc context detected: 0x%x", vaCtxID);
288 *ctxType = DDI_MEDIA_CONTEXT_TYPE_CENC_DECODER;
289 return DdiMedia_GetVaContextFromHeap(mediaCtx->pDecoderCtxHeap, index, &mediaCtx->DecoderMutex);
290 }
291 else if ((vaCtxID&DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_DECODER)
292 {
293 DDI_VERBOSEMESSAGE("Decode context detected: 0x%x", vaCtxID);
294 *ctxType = DDI_MEDIA_CONTEXT_TYPE_DECODER;
295 return DdiMedia_GetVaContextFromHeap(mediaCtx->pDecoderCtxHeap, index, &mediaCtx->DecoderMutex);
296 }
297 else if ((vaCtxID&DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_ENCODER)
298 {
299 *ctxType = DDI_MEDIA_CONTEXT_TYPE_ENCODER;
300 return DdiMedia_GetVaContextFromHeap(mediaCtx->pEncoderCtxHeap, index, &mediaCtx->EncoderMutex);
301 }
302 else if ((vaCtxID & DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_VP)
303 {
304 *ctxType = DDI_MEDIA_CONTEXT_TYPE_VP;
305 return DdiMedia_GetVaContextFromHeap(mediaCtx->pVpCtxHeap, index, &mediaCtx->VpMutex);
306 }
307 else if ((vaCtxID & DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_CM)
308 {
309 *ctxType = DDI_MEDIA_CONTEXT_TYPE_CM;
310 return DdiMedia_GetVaContextFromHeap(mediaCtx->pCmCtxHeap, index, &mediaCtx->CmMutex);
311 }
312 else if ((vaCtxID & DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_MFE)
313 {
314 *ctxType = DDI_MEDIA_CONTEXT_TYPE_MFE;
315 return DdiMedia_GetVaContextFromHeap(mediaCtx->pMfeCtxHeap, index, &mediaCtx->MfeMutex);
316 }
317 else
318 {
319 DDI_ASSERTMESSAGE("Invalid context: 0x%x", vaCtxID);
320 *ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
321 return nullptr;
322 }
323
324 }
325
DdiMedia_GetSurfaceFromVASurfaceID(PDDI_MEDIA_CONTEXT mediaCtx,VASurfaceID surfaceID)326 DDI_MEDIA_SURFACE* DdiMedia_GetSurfaceFromVASurfaceID (PDDI_MEDIA_CONTEXT mediaCtx, VASurfaceID surfaceID)
327 {
328 uint32_t i = 0;
329 PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = nullptr;
330 PDDI_MEDIA_SURFACE surface = nullptr;
331
332 DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", nullptr);
333
334 i = (uint32_t)surfaceID;
335 bool validSurface = (i != VA_INVALID_SURFACE);
336 if(validSurface)
337 {
338 DDI_CHK_LESS(i, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "invalid surface id", nullptr);
339 DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
340 surfaceElement = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)mediaCtx->pSurfaceHeap->pHeapBase;
341 surfaceElement += i;
342 surface = surfaceElement->pSurface;
343 DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
344 }
345
346 return surface;
347 }
348
DdiMedia_GetVASurfaceIDFromSurface(PDDI_MEDIA_SURFACE surface)349 VASurfaceID DdiMedia_GetVASurfaceIDFromSurface(PDDI_MEDIA_SURFACE surface)
350 {
351 DDI_CHK_NULL(surface, "nullptr surface", VA_INVALID_SURFACE);
352
353 PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surface->pMediaCtx->pSurfaceHeap->pHeapBase;
354 for(uint32_t i = 0; i < surface->pMediaCtx->pSurfaceHeap->uiAllocatedHeapElements; i ++)
355 {
356 if(surface == surfaceElement->pSurface)
357 {
358 return surfaceElement->uiVaSurfaceID;
359 }
360 surfaceElement ++;
361 }
362 return VA_INVALID_SURFACE;
363 }
364
DdiMedia_ReplaceSurfaceWithNewFormat(PDDI_MEDIA_SURFACE surface,DDI_MEDIA_FORMAT expectedFormat)365 PDDI_MEDIA_SURFACE DdiMedia_ReplaceSurfaceWithNewFormat(PDDI_MEDIA_SURFACE surface, DDI_MEDIA_FORMAT expectedFormat)
366 {
367 DDI_CHK_NULL(surface, "nullptr surface", nullptr);
368
369 PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surface->pMediaCtx->pSurfaceHeap->pHeapBase;
370 PDDI_MEDIA_CONTEXT mediaCtx = surface->pMediaCtx;
371
372 //check some conditions
373 if(expectedFormat == surface->format)
374 {
375 return surface;
376 }
377 //create new dst surface and copy the structure
378 PDDI_MEDIA_SURFACE dstSurface = (DDI_MEDIA_SURFACE *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_SURFACE));
379 if (nullptr == surfaceElement)
380 {
381 MOS_FreeMemory(dstSurface);
382 return nullptr;
383 }
384
385 MOS_SecureMemcpy(dstSurface,sizeof(DDI_MEDIA_SURFACE),surface,sizeof(DDI_MEDIA_SURFACE));
386 DDI_CHK_NULL(dstSurface, "nullptr dstSurface", nullptr);
387 dstSurface->format = expectedFormat;
388 dstSurface->uiLockedBufID = VA_INVALID_ID;
389 dstSurface->uiLockedImageID = VA_INVALID_ID;
390 dstSurface->pSurfDesc = nullptr;
391 //lock surface heap
392 DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
393 uint32_t i;
394 //get current element heap and index
395 for(i = 0; i < mediaCtx->pSurfaceHeap->uiAllocatedHeapElements; i ++)
396 {
397 if(surface == surfaceElement->pSurface)
398 {
399 break;
400 }
401 surfaceElement ++;
402 }
403 //if cant find
404 if(i == surface->pMediaCtx->pSurfaceHeap->uiAllocatedHeapElements)
405 {
406 DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
407 MOS_FreeMemory(dstSurface);
408 return nullptr;
409 }
410 //FreeSurface
411 DdiMediaUtil_FreeSurface(surface);
412 MOS_FreeMemory(surface);
413 //CreateNewSurface
414 DdiMediaUtil_CreateSurface(dstSurface,mediaCtx);
415 surfaceElement->pSurface = dstSurface;
416
417 DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
418
419 return dstSurface;
420 }
421
DdiMedia_GetBufferFromVABufferID(PDDI_MEDIA_CONTEXT mediaCtx,VABufferID bufferID)422 DDI_MEDIA_BUFFER* DdiMedia_GetBufferFromVABufferID (PDDI_MEDIA_CONTEXT mediaCtx, VABufferID bufferID)
423 {
424 uint32_t i = 0;
425 PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufHeapElement = nullptr;
426 PDDI_MEDIA_BUFFER buf = nullptr;
427
428 i = (uint32_t)bufferID;
429 DDI_CHK_LESS(i, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "invalid buffer id", nullptr);
430 DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
431 bufHeapElement = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)mediaCtx->pBufferHeap->pHeapBase;
432 bufHeapElement += i;
433 buf = bufHeapElement->pBuffer;
434 DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
435
436 return buf;
437 }
438
DdiMedia_DestroyBufFromVABufferID(PDDI_MEDIA_CONTEXT mediaCtx,VABufferID bufferID)439 bool DdiMedia_DestroyBufFromVABufferID (PDDI_MEDIA_CONTEXT mediaCtx, VABufferID bufferID)
440 {
441 DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
442 DdiMediaUtil_ReleasePMediaBufferFromHeap(mediaCtx->pBufferHeap, bufferID);
443 mediaCtx->uiNumBufs--;
444 DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
445 return true;
446 }
447
DdiMedia_GetContextFromVABufferID(PDDI_MEDIA_CONTEXT mediaCtx,VABufferID bufferID)448 void* DdiMedia_GetContextFromVABufferID (PDDI_MEDIA_CONTEXT mediaCtx, VABufferID bufferID)
449 {
450 uint32_t i;
451 PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufHeapElement;
452 void * ctx;
453
454 i = (uint32_t)bufferID;
455 DDI_CHK_LESS(i, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "invalid buffer id", nullptr);
456 DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
457 bufHeapElement = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)mediaCtx->pBufferHeap->pHeapBase;
458 ctx = bufHeapElement->pCtx;
459 DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
460
461 return ctx;
462 }
463