1 /*
2 * Copyright (c) 2009-2017, 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_util.h
24 //! \brief     libva(and its extension) utility head file
25 //!
26 #ifndef __MEDIA_LIBVA_UTIL_H__
27 #define __MEDIA_LIBVA_UTIL_H__
28 
29 #include "media_libva_common.h"
30 #include "mos_util_debug.h"
31 #include "mos_bufmgr.h"
32 
33 #define DEVICE_NAME "/dev/dri/renderD128"   // For Gen, it is always /dev/dri/renderD128 node
34 
35 //!
36 //! \brief  Media print frame per second
37 //!
38 void     DdiMediaUtil_MediaPrintFps();
39 
40 //!
41 //! \brief  Create surface
42 //!
43 //! \param  [in] surface
44 //!         Ddi media surface
45 //! \param  [in] mediaDrvCtx
46 //!         Pointer to ddi media context
47 //!
48 //! \return VAStatus
49 //!     VA_STATUS_SUCCESS if success, else fail reason
50 //!
51 VAStatus DdiMediaUtil_CreateSurface(DDI_MEDIA_SURFACE  *surface, PDDI_MEDIA_CONTEXT mediaDrvCtx);
52 
53 //!
54 //! \brief  Create buffer
55 //!
56 //! \param  [out] buffer
57 //!         Ddi media buffer
58 //! \param  [in] bufmgr
59 //!         Mos buffer manager
60 //!
61 //! \return VAStatus
62 //!     VA_STATUS_SUCCESS if success, else fail reason
63 //!
64 VAStatus DdiMediaUtil_CreateBuffer(DDI_MEDIA_BUFFER *buffer, mos_bufmgr *bufmgr);
65 
66 //!
67 //! \brief  Lock surface
68 //!
69 //! \param  [in] surface
70 //!         Ddi media surface
71 //! \param  [in] flag
72 //!         Flag
73 //!
74 //! \return void*
75 //!     Pointer to lock surface data
76 //!
77 void*    DdiMediaUtil_LockSurface(DDI_MEDIA_SURFACE  *surface, uint32_t flag);
78 
79 //!
80 //! \brief  Lock surface
81 //!
82 //! \param  [in] surface
83 //!         Ddi media surface
84 //! \param  [in] flag
85 //!         Flag
86 //!
87 //! \return void*
88 //!     Pointer to lock surface data
89 //!
90 void* DdiMediaUtil_LockSurfaceInternal(DDI_MEDIA_SURFACE *surface, uint32_t flag);
91 
92 //!
93 //! \brief  Unlock surface
94 //!
95 //! \param  [in] surface
96 //!         Ddi media surface
97 //!
98 void     DdiMediaUtil_UnlockSurface(DDI_MEDIA_SURFACE  *surface);
99 
100 //!
101 //! \brief  Unlock surface
102 //!
103 //! \param  [in] surface
104 //!         Ddi media surface
105 //!
106 void     DdiMediaUtil_UnlockSurfaceInternal(DDI_MEDIA_SURFACE *surface);
107 
108 //!
109 //! \brief  Lock buffer
110 //!
111 //! \param  [in] buf
112 //!         Ddi media buffer
113 //! \param  [in] flag
114 //!         Flag
115 //!
116 //! \return void*
117 //!     Pointer to lock buffer data
118 //!
119 void*    DdiMediaUtil_LockBuffer(DDI_MEDIA_BUFFER *buf, uint32_t flag);
120 
121 //!
122 //! \brief  Unlock buffer
123 //!
124 //! \param  [in] buf
125 //!         Ddi media buffer
126 //!
127 void     DdiMediaUtil_UnlockBuffer(DDI_MEDIA_BUFFER *buf);
128 
129 //!
130 //! \brief  Free surface
131 //!
132 //! \param  [in] surface
133 //!         Ddi media surface
134 //!
135 void     DdiMediaUtil_FreeSurface(DDI_MEDIA_SURFACE *surface);
136 
137 //!
138 //! \brief  Free buffer
139 //!
140 //! \param  [in] buf
141 //!         Ddi media buffer
142 //!
143 void     DdiMediaUtil_FreeBuffer(DDI_MEDIA_BUFFER  *buf);
144 
145 //!
146 //! \brief  Init mutex
147 //!
148 //! \param  [in] mutex
149 //!         Pointer to media mutex thread
150 //!
151 void     DdiMediaUtil_InitMutex(PMEDIA_MUTEX_T  mutex);
152 
153 //!
154 //! \brief  Destroy mutex
155 //!
156 //! \param  [in] mutex
157 //!         Pointer to media mutex thread
158 //!
159 void     DdiMediaUtil_DestroyMutex(PMEDIA_MUTEX_T  mutex);
160 //!
161 //! \brief  Lock mutex
162 //!
163 //! \param  [in] mutex
164 //!         Pointer to media mutex thread
165 //!
166 void     DdiMediaUtil_LockMutex(PMEDIA_MUTEX_T  mutex);
167 
168 //!
169 //! \brief  Unlock mutex
170 //!
171 //! \param  [in] mutex
172 //!         Pointer to media mutex thread
173 //!
174 void     DdiMediaUtil_UnLockMutex(PMEDIA_MUTEX_T  mutex);
175 
176 //!
177 //! \brief  Helper inline class intended to simplify mutex lock/unlock
178 //!         operations primarily used as a stack-allocated object.
179 //!         In that case, the compiler guarantees to call the destructor
180 //!         leaving the scope. The class becomes handy in functions
181 //!         where there are several return statements with different
182 //!         exit code value.
183 //!
184 class DdiMediaUtil_LockGuard {
185 private:
186     PMEDIA_MUTEX_T m_pMutex;
187 public:
DdiMediaUtil_LockGuard(PMEDIA_MUTEX_T pMutex)188     DdiMediaUtil_LockGuard(PMEDIA_MUTEX_T pMutex):m_pMutex(pMutex)
189     {
190         DdiMediaUtil_LockMutex(m_pMutex);
191     }
~DdiMediaUtil_LockGuard()192     ~DdiMediaUtil_LockGuard()
193     {
194         DdiMediaUtil_UnLockMutex(m_pMutex);
195     }
196 };
197 
198 //!
199 //! \brief  Destroy semaphore
200 //!
201 //! \param  [in] sem
202 //!         Pointer to media semaphore thread
203 //!
204 void     DdiMediaUtil_DestroySemaphore(PMEDIA_SEM_T  sem);
205 
206 //!
207 //! \brief  Wait semaphore
208 //!
209 //! \param  [in] sem
210 //!         Pointer to media semaphore thread
211 //!
212 void     DdiMediaUtil_WaitSemaphore(PMEDIA_SEM_T  sem);
213 //!
214 //! \brief  Try wait semaphore
215 //!
216 //! \param  [in] sem
217 //!         Pointer to media semaphore thread
218 //!
219 //! \return int32_t
220 //!     Try wait for semaphore. Return 0 if success, else -1 if fail
221 //!
222 int32_t  DdiMediaUtil_TryWaitSemaphore(PMEDIA_SEM_T  sem);
223 
224 //!
225 //! \brief  Post semaphore
226 //!
227 //! \param  [in] sem
228 //!         Pointer to media semaphore thread
229 //!
230 void     DdiMediaUtil_PostSemaphore(PMEDIA_SEM_T  sem);
231 
232 //!
233 //! \brief  Fill a rect structure with the regsion specified by parameters
234 //!
235 //! \param  [in] rect
236 //!         Input pointer to the rect
237 //! \param  [in] offset_x
238 //!         X offset of the region
239 //! \param  [in] offset_y
240 //!         Y offset of the region
241 //! \param  [in] width
242 //!         Width of the region
243 //! \param  [in] height
244 //!         Height of the region
245 //!
246 //! \return VAStatus
247 //!     VA_STATUS_SUCCESS if success, else fail reason
248 //!
249 VAStatus DdiMediaUtil_FillPositionToRect(RECT *rect, int16_t offset_x, int16_t offset_y, int16_t width, int16_t height);
250 
251 //!
252 //! \brief  Is external surface
253 //! \details    If the bo of media surface was allocated from App,
254 //!     should return true, otherwise, false. In current implemeation
255 //!     external buffer passed with pSurfDesc.
256 //!
257 //! \param  [in] surface
258 //!         Pointer to ddi media surface
259 //!
260 //! \return bool
261 //!     true if surface is external, else false
262 //!
263 bool     DdiMediaUtil_IsExternalSurface(PDDI_MEDIA_SURFACE surface);
264 
265 //!
266 //! \brief  Allocate pmedia surface from heap
267 //!
268 //! \param  [in] surfaceHeap
269 //!         Pointer to ddi media heap
270 //!
271 //! \return PDDI_MEDIA_SURFACE_HEAP_ELEMENT
272 //!     Pointer to ddi media surface heap element
273 //!
274 PDDI_MEDIA_SURFACE_HEAP_ELEMENT DdiMediaUtil_AllocPMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap);
275 
276 //!
277 //! \brief  Release pmedia surface from heap
278 //!
279 //! \param  [in] surfaceHeap
280 //!         Pointer to ddi media heap
281 //! \param  [in] vaSurfaceID
282 //!         VA surface ID
283 //!
284 void     DdiMediaUtil_ReleasePMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap, uint32_t vaSurfaceID);
285 
286 //!
287 //! \brief  Allocate pmedia buffer from heap
288 //!
289 //! \param  [in] bufferHeap
290 //!         Pointer to ddi media heap
291 //!
292 //! \return PDDI_MEDIA_BUFFER_HEAP_ELEMENT
293 //!     Pointer to ddi media buffer heap element
294 //!
295 PDDI_MEDIA_BUFFER_HEAP_ELEMENT  DdiMediaUtil_AllocPMediaBufferFromHeap(PDDI_MEDIA_HEAP bufferHeap);
296 
297 //!
298 //! \brief  Release pmedia buffer from heap
299 //!
300 //! \param  [in] bufferHeap
301 //!         Pointer to ddi media heap
302 //! \param  [in] vaBufferID
303 //!         VA buffer ID
304 //!
305 void     DdiMediaUtil_ReleasePMediaBufferFromHeap(PDDI_MEDIA_HEAP bufferHeap, uint32_t vaBufferID);
306 
307 //!
308 //! \brief  Allocate PVA image from heap
309 //!
310 //! \param  [in] imageHeap
311 //!         Pointer to ddi media heap
312 //!
313 //! \return PDDI_MEDIA_IMAGE_HEAP_ELEMENT
314 //!     Pointer to ddi media image heap element
315 //!
316 PDDI_MEDIA_IMAGE_HEAP_ELEMENT  DdiMediaUtil_AllocPVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap);
317 
318 //!
319 //! \brief  Release PVA image from heap
320 //!
321 //! \param  [in] imageHeap
322 //!         Pointer to ddi media heap
323 //! \param  [in] vaImageID
324 //!         VA image ID
325 //!
326 void     DdiMediaUtil_ReleasePVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap, uint32_t vaImageID);
327 
328 //!
329 //! \brief  Allocate PVA context from heap
330 //!
331 //! \param  [in] vaContextHeap
332 //!         Pointer to ddi media heap
333 //!
334 //! \return PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT
335 //!     Pointer to ddi media vacontext heap element
336 //!
337 PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT DdiMediaUtil_AllocPVAContextFromHeap(PDDI_MEDIA_HEAP vaContextHeap);
338 
339 //!
340 //! \brief  Release PVA context from heap
341 //!
342 //! \param  [in] vaContextHeap
343 //!         Pointer to ddi media heap
344 //! \param  [in] vaContextID
345 //!         VA context ID
346 //!
347 void     DdiMediaUtil_ReleasePVAContextFromHeap(PDDI_MEDIA_HEAP vaContextHeap, uint32_t vaContextID);
348 
349 //!
350 //! \brief  Unreference buf object media buffer
351 //!
352 //! \param  [in] buf
353 //!         Pointer to ddi media buffer
354 //!
355 void     DdiMediaUtil_UnRefBufObjInMediaBuffer(PDDI_MEDIA_BUFFER buf);
356 
357 //!
358 //! \brief  Open Intel's Graphics Device to get the file descriptor
359 //!
360 //! \param  [in] devName
361 //!         Device name
362 //!
363 //! \return int32_t
364 //!     Device name header. Return 0 if success, else -1 if fail.
365 //!
366 int32_t  DdiMediaUtil_OpenGraphicsAdaptor(char *devName);
367 
368 //!
369 //! \brief  Unregister RT surfaces
370 //!
371 //! \param  [in] ctx
372 //!     Pointer to VA driver context
373 //! \param  [in] surface
374 //!     Pointer to ddi media surface
375 //!
376 //! \return     VAStatus
377 //!     VA_STATUS_SUCCESS if success, else fail reason
378 //!
379 VAStatus DdiMediaUtil_UnRegisterRTSurfaces(VADriverContextP    ctx,PDDI_MEDIA_SURFACE surface);
380 
381 //!
382 //! \brief  Determine whethere media reset is anabled
383 //!
384 //! \param  [in] mediaCtx
385 //!     Pointer to VA driver context
386 //!
387 //! \return     VAStatus
388 //!     VA_STATUS_SUCCESS if success, else fail reason
389 //!
390 VAStatus DdiMediaUtil_SetMediaResetEnableFlag(PDDI_MEDIA_CONTEXT mediaCtx);
391 
392 //------------------------------------------------------------------------------
393 // Macros for debug messages, Assert, Null check and condition check within ddi files
394 //------------------------------------------------------------------------------
395 
396 #define DDI_ASSERT(_expr)                                                   \
397     MOS_ASSERT(MOS_COMPONENT_DDI, MOS_DDI_SUBCOMP_SELF, _expr)
398 
399 #define DDI_ASSERTMESSAGE(_message, ...)                                    \
400     MOS_ASSERTMESSAGE(MOS_COMPONENT_DDI, MOS_DDI_SUBCOMP_SELF, _message, ##__VA_ARGS__)
401 
402 #define DDI_NORMALMESSAGE(_message, ...)                                    \
403     MOS_NORMALMESSAGE(MOS_COMPONENT_DDI, MOS_DDI_SUBCOMP_SELF, _message, ##__VA_ARGS__)
404 
405 #define DDI_VERBOSEMESSAGE(_message, ...)                                   \
406     MOS_VERBOSEMESSAGE(MOS_COMPONENT_DDI, MOS_DDI_SUBCOMP_SELF, _message, ##__VA_ARGS__)
407 
408 #ifdef ANDROID
409 #define DDI_FUNCTION_ENTER()            UMD_ATRACE_BEGIN(__FUNCTION__)
410 #define DDI_FUNCTION_EXIT(status)       UMD_ATRACE_END
411 #else
412 #define DDI_FUNCTION_ENTER()                                                \
413     MOS_FUNCTION_ENTER(MOS_COMPONENT_DDI, MOS_DDI_SUBCOMP_SELF)
414 
415 #define DDI_FUNCTION_EXIT(status)                                               \
416     MOS_FUNCTION_EXIT(MOS_COMPONENT_DDI, MOS_DDI_SUBCOMP_SELF, status)
417 #endif
418 
419 // If pointer is nullptr, print the error message and return the specified value.
420 #define DDI_CHK_NULL(_ptr, _str, _ret)                                      \
421     DDI_CHK_CONDITION((nullptr == (_ptr)), _str, _ret)
422 
423 #define DDI_CHK_LARGER(p, bottom, str, ret)                                 \
424     DDI_CHK_CONDITION((p <= bottom),str,ret)
425 
426 #define DDI_CHK_LESS(p, upper, str, ret)                                    \
427     DDI_CHK_CONDITION((p >= upper),str,ret)
428 
429 // Check the return value of function.
430 // If failed,  print the error message and return,
431 // do nothing otherwise.
432 #define DDI_CHK_RET(_ret, _str)                                           \
433 {                                                                             \
434     VAStatus tmpRet = _ret;                                                   \
435     if (VA_STATUS_SUCCESS != tmpRet) {                                        \
436         DDI_ASSERTMESSAGE("%s [%d].", _str, tmpRet);                        \
437         return tmpRet;                                                        \
438     }                                                                         \
439 }
440 
441 // Check the return status of parse function in renderPicture
442 // If failed, assign new status and break
443 // do nothing otherwise.
444 #define DDI_CHK_STATUS(_ret, _newret)                                       \
445 {                                                                             \
446     if (VA_STATUS_SUCCESS != _ret) {                                          \
447         vaStatus = _newret;                                                   \
448         break;                                                                \
449     }                                                                         \
450 }
451 
452 // Check the condition, if true, print the error message
453 // and return the specified value, do nothing otherwise.
454 #define DDI_CHK_CONDITION(condition, _str, _ret)                            \
455     if (condition) {                                                          \
456         DDI_ASSERTMESSAGE(_str);                                            \
457         return _ret;                                                          \
458     }
459 
460 #define DDI_CHK_STATUS_MESSAGE(_ptr, _message, ...)                         \
461     MOS_CHK_STATUS_MESSAGE(MOS_COMPONENT_DDI, MOS_DDI_SUBCOMP_SELF, _ptr, _message, ##__VA_ARGS__)
462 
463 #define DDI_CHK_HR_MESSAGE(_ptr, _message, ...)                             \
464     MOS_CHK_HR_MESSAGE(MOS_COMPONENT_DDI, MOS_DDI_SUBCOMP_SELF, _ptr, _message, ##__VA_ARGS__)
465 
466 #ifdef ANDROID
467 // Enable new specification for video formats
468 // \see memo "Color format Usage on Android"
469 #ifndef UFO_GRALLOC_NEW_FORMAT
470 #define UFO_GRALLOC_NEW_FORMAT 1
471 #endif
472 #endif
473 
474 #endif
475