2402479bf6b43164afaad66905e3f9193bc32a30
[GitHub/LineageOS/android_hardware_samsung_slsi_openmax.git] / osal / Exynos_OSAL_Android.cpp
1 /*
2 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*
18 * @file Exynos_OSAL_Android.cpp
19 * @brief
20 * @author Seungbeom Kim (sbcrux.kim@samsung.com)
21 * @author Hyeyeon Chung (hyeon.chung@samsung.com)
22 * @author Yunji Kim (yunji.kim@samsung.com)
23 * @author Jinsung Yang (jsgood.yang@samsung.com)
24 * @version 2.0.0
25 * @history
26 * 2012.02.20 : Create
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include <system/window.h>
33 #include <cutils/properties.h>
34 #include <ui/GraphicBuffer.h>
35 #include <ui/GraphicBufferMapper.h>
36 #include <ui/Rect.h>
37 #include <media/hardware/OMXPluginBase.h>
38 #include <media/hardware/HardwareAPI.h>
39 #include <hardware/hardware.h>
40 #include <media/hardware/MetadataBufferType.h>
41 #ifdef USE_DMA_BUF
42 #include <gralloc_priv.h>
43 #endif
44
45 #include <ion/ion.h>
46 #include "exynos_ion.h"
47
48 #include "Exynos_OSAL_Mutex.h"
49 #include "Exynos_OSAL_Semaphore.h"
50 #include "Exynos_OMX_Baseport.h"
51 #include "Exynos_OMX_Basecomponent.h"
52 #include "Exynos_OMX_Macros.h"
53 #include "Exynos_OSAL_Android.h"
54 #include "Exynos_OSAL_ETC.h"
55 #include "exynos_format.h"
56
57 #include "ExynosVideoApi.h"
58
59 #undef EXYNOS_LOG_TAG
60 #define EXYNOS_LOG_TAG "Exynos_OSAL_Android"
61 //#define EXYNOS_LOG_OFF
62 #include "Exynos_OSAL_Log.h"
63
64 using namespace android;
65
66 #ifdef __cplusplus
67 extern "C" {
68 #endif
69
70 typedef struct _EXYNOS_OMX_SHARED_BUFFER {
71 OMX_S32 bufferFd;
72 OMX_S32 bufferFd1;
73 OMX_S32 bufferFd2;
74
75 ion_user_handle_t ionHandle;
76 ion_user_handle_t ionHandle1;
77 ion_user_handle_t ionHandle2;
78
79 OMX_U32 cnt;
80 } EXYNOS_OMX_SHARED_BUFFER;
81
82 typedef struct _EXYNOS_OMX_REF_HANDLE {
83 OMX_HANDLETYPE hMutex;
84 OMX_PTR pGrallocModule;
85 EXYNOS_OMX_SHARED_BUFFER SharedBuffer[MAX_BUFFER_REF];
86 } EXYNOS_OMX_REF_HANDLE;
87
88 static int lockCnt = 0;
89
90 int getIonFd(gralloc_module_t const *module)
91 {
92 private_module_t* m = const_cast<private_module_t*>(reinterpret_cast<const private_module_t*>(module));
93 return m->ionfd;
94 }
95
96 OMX_ERRORTYPE setBufferProcessTypeForDecoder(EXYNOS_OMX_BASEPORT *pExynosPort)
97 {
98 OMX_ERRORTYPE ret = OMX_ErrorNone;
99
100 if (pExynosPort == NULL) {
101 ret = OMX_ErrorUndefined;
102 goto EXIT;
103 }
104
105 #ifdef USE_ANB_OUTBUF_SHARE
106 if (pExynosPort->bufferProcessType & BUFFER_ANBSHARE) {
107 int i;
108 if (pExynosPort->supportFormat == NULL) {
109 ret = OMX_ErrorUndefined;
110 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: supported format is empty", __FUNCTION__);
111 goto EXIT;
112 }
113
114 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
115 /* check to support NV12T format */
116 for (i = 0; pExynosPort->supportFormat[i] != OMX_COLOR_FormatUnused; i++) {
117 /* prefer to use NV12T */
118 if (pExynosPort->supportFormat[i] == (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled) {
119 pExynosPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
120 break;
121 }
122 }
123 pExynosPort->bufferProcessType = BUFFER_SHARE;
124
125 Exynos_OSAL_Log(EXYNOS_LOG_INFO, "output buffer sharing mode is on (%x)", pExynosPort->portDefinition.format.video.eColorFormat);
126 } else
127 #endif
128 if (pExynosPort->bufferProcessType & BUFFER_COPY) {
129 if (pExynosPort->bStoreMetaData == OMX_TRUE) {
130 ret = OMX_ErrorUndefined;
131 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: bufferProcessType is invalid", __FUNCTION__);
132 goto EXIT;
133 }
134
135 pExynosPort->bufferProcessType = BUFFER_COPY;
136 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
137 }
138
139 EXIT:
140 return ret;
141 }
142
143 void resetBufferProcessTypeForDecoder(EXYNOS_OMX_BASEPORT *pExynosPort)
144 {
145 int i;
146
147 if (pExynosPort == NULL)
148 return;
149
150 pExynosPort->bufferProcessType = (EXYNOS_OMX_BUFFERPROCESS_TYPE)(BUFFER_COPY | BUFFER_ANBSHARE);
151 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
152
153 return;
154 }
155
156 OMX_ERRORTYPE Exynos_OSAL_LockANBHandle(
157 OMX_IN OMX_PTR handle,
158 OMX_IN OMX_U32 width,
159 OMX_IN OMX_U32 height,
160 OMX_IN OMX_COLOR_FORMATTYPE format,
161 OMX_OUT OMX_U32 *pStride,
162 OMX_OUT OMX_PTR planes)
163 {
164 FunctionIn();
165
166 OMX_ERRORTYPE ret = OMX_ErrorNone;
167 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
168 buffer_handle_t bufferHandle = (buffer_handle_t) handle;
169 #ifdef USE_DMA_BUF
170 private_handle_t *priv_hnd = (private_handle_t *) bufferHandle;
171 #endif
172 Rect bounds((uint32_t)width, (uint32_t)height);
173 ExynosVideoPlane *vplanes = (ExynosVideoPlane *) planes;
174 void *vaddr[MAX_BUFFER_PLANE] = {NULL, };
175
176 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: handle: 0x%x, format = %x", __FUNCTION__, handle, priv_hnd->format);
177
178 int usage = 0;
179 switch ((int)format) {
180 case OMX_COLOR_FormatYUV420Planar:
181 case OMX_COLOR_FormatYUV420SemiPlanar:
182 case OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace:
183 case OMX_SEC_COLOR_Format10bitYUV420SemiPlanar:
184 case OMX_SEC_COLOR_FormatNV12Tiled:
185 usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
186 break;
187 #ifdef USE_ANDROIDOPAQUE
188 case OMX_COLOR_FormatAndroidOpaque:
189 {
190 OMX_COLOR_FORMATTYPE formatType;
191 formatType = Exynos_OSAL_GetANBColorFormat(priv_hnd);
192 if ((formatType == OMX_COLOR_FormatYUV420SemiPlanar) ||
193 (formatType == (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled))
194 usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
195 else
196 usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_VIDEO_ENCODER;
197 }
198 break;
199 #endif
200 default:
201 usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
202 break;
203 }
204
205 if (mapper.lock(bufferHandle, usage, bounds, vaddr) != 0) {
206 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: mapper.lock() fail", __func__);
207 ret = OMX_ErrorUndefined;
208 goto EXIT;
209 }
210 lockCnt++;
211 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: lockCnt:%d", __func__, lockCnt);
212
213 #ifdef USE_DMA_BUF
214 vplanes[0].fd = priv_hnd->fd;
215 vplanes[0].offset = 0;
216 vplanes[1].fd = priv_hnd->fd1;
217 vplanes[1].offset = 0;
218 vplanes[2].fd = priv_hnd->fd2;
219 vplanes[2].offset = 0;
220 #endif
221
222 if (priv_hnd->flags & GRALLOC_USAGE_PROTECTED) {
223 /* in case of DRM, vaddrs are invalid */
224 vplanes[0].addr = INT_TO_PTR(priv_hnd->fd);
225 vplanes[1].addr = INT_TO_PTR(priv_hnd->fd1);
226 vplanes[2].addr = INT_TO_PTR(priv_hnd->fd2);
227 } else {
228 vplanes[0].addr = vaddr[0];
229 vplanes[1].addr = vaddr[1];
230 vplanes[2].addr = vaddr[2];
231 }
232
233 if ((priv_hnd->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV) &&
234 (vaddr[2] != NULL))
235 vplanes[2].addr = vaddr[2];
236
237 *pStride = (OMX_U32)priv_hnd->stride;
238
239 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: buffer locked: 0x%x", __func__, *vaddr);
240
241 EXIT:
242 FunctionOut();
243
244 return ret;
245 }
246
247 OMX_ERRORTYPE Exynos_OSAL_UnlockANBHandle(OMX_IN OMX_PTR handle)
248 {
249 FunctionIn();
250
251 OMX_ERRORTYPE ret = OMX_ErrorNone;
252 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
253 buffer_handle_t bufferHandle = (buffer_handle_t) handle;
254
255 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: handle: 0x%x", __func__, handle);
256
257 if (mapper.unlock(bufferHandle) != 0) {
258 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: mapper.unlock() fail", __func__);
259 ret = OMX_ErrorUndefined;
260 goto EXIT;
261 }
262 lockCnt--;
263 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: lockCnt:%d", __func__, lockCnt);
264
265 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: buffer unlocked: 0x%x", __func__, handle);
266
267 EXIT:
268 FunctionOut();
269
270 return ret;
271 }
272
273 OMX_COLOR_FORMATTYPE Exynos_OSAL_GetANBColorFormat(OMX_IN OMX_PTR handle)
274 {
275 FunctionIn();
276
277 OMX_COLOR_FORMATTYPE ret = OMX_COLOR_FormatUnused;
278 private_handle_t *priv_hnd = (private_handle_t *) handle;
279
280 ret = Exynos_OSAL_HAL2OMXColorFormat(priv_hnd->format);
281 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ColorFormat: 0x%x", ret);
282
283 EXIT:
284 FunctionOut();
285
286 return ret;
287 }
288
289 OMX_ERRORTYPE Exynos_OSAL_LockMetaData(
290 OMX_IN OMX_PTR pBuffer,
291 OMX_IN OMX_U32 width,
292 OMX_IN OMX_U32 height,
293 OMX_IN OMX_COLOR_FORMATTYPE format,
294 OMX_OUT OMX_U32 *pStride,
295 OMX_OUT OMX_PTR planes)
296 {
297 FunctionIn();
298
299 OMX_ERRORTYPE ret = OMX_ErrorNone;
300 OMX_PTR pBuf = NULL;
301
302 ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pBuffer, &pBuf);
303 if (ret == OMX_ErrorNone)
304 ret = Exynos_OSAL_LockANBHandle(pBuf, width, height, format, pStride, planes);
305
306 EXIT:
307 FunctionOut();
308
309 return ret;
310 }
311
312 OMX_ERRORTYPE Exynos_OSAL_UnlockMetaData(OMX_IN OMX_PTR pBuffer)
313 {
314 FunctionIn();
315
316 OMX_ERRORTYPE ret = OMX_ErrorNone;
317 OMX_PTR pBuf = NULL;
318
319 ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pBuffer, &pBuf);
320 if (ret == OMX_ErrorNone)
321 ret = Exynos_OSAL_UnlockANBHandle(pBuf);
322
323 EXIT:
324 FunctionOut();
325
326 return ret;
327 }
328
329 OMX_HANDLETYPE Exynos_OSAL_RefANB_Create()
330 {
331 OMX_ERRORTYPE ret = OMX_ErrorNone;
332 EXYNOS_OMX_REF_HANDLE *phREF = NULL;
333 gralloc_module_t *module = NULL;
334
335 int i = 0;
336
337 FunctionIn();
338
339 phREF = (EXYNOS_OMX_REF_HANDLE *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_REF_HANDLE));
340 if (phREF == NULL)
341 goto EXIT;
342
343 Exynos_OSAL_Memset(phREF, 0, sizeof(EXYNOS_OMX_REF_HANDLE));
344 for (i = 0; i < MAX_BUFFER_REF; i++) {
345 phREF->SharedBuffer[i].bufferFd = -1;
346 phREF->SharedBuffer[i].bufferFd1 = -1;
347 phREF->SharedBuffer[i].bufferFd2 = -1;
348 }
349 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&module) != 0) {
350 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: hw_get_module(GRALLOC_HARDWARE_MODULE_ID) fail", __func__);
351 ret = OMX_ErrorUndefined;
352 goto EXIT;
353 }
354
355 phREF->pGrallocModule = (OMX_PTR)module;
356
357 ret = Exynos_OSAL_MutexCreate(&phREF->hMutex);
358 if (ret != OMX_ErrorNone) {
359 Exynos_OSAL_Free(phREF);
360 phREF = NULL;
361 }
362
363 EXIT:
364 FunctionOut();
365
366 return ((OMX_HANDLETYPE)phREF);
367 }
368
369 OMX_ERRORTYPE Exynos_OSAL_RefANB_Reset(OMX_HANDLETYPE hREF)
370 {
371 OMX_ERRORTYPE ret = OMX_ErrorNone;
372 EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
373 gralloc_module_t *module = NULL;
374
375 int i = 0;
376
377 FunctionIn();
378
379 if (phREF == NULL) {
380 ret = OMX_ErrorBadParameter;
381 goto EXIT;
382 }
383
384 module = (gralloc_module_t *)phREF->pGrallocModule;
385
386 Exynos_OSAL_MutexLock(phREF->hMutex);
387
388 for (i = 0; i < MAX_BUFFER_REF; i++) {
389 if (phREF->SharedBuffer[i].bufferFd > -1) {
390 while(phREF->SharedBuffer[i].cnt > 0) {
391 if (phREF->SharedBuffer[i].ionHandle != -1)
392 ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle);
393 if (phREF->SharedBuffer[i].ionHandle1 != -1)
394 ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle1);
395 if (phREF->SharedBuffer[i].ionHandle2 != -1)
396 ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle2);
397 phREF->SharedBuffer[i].cnt--;
398 }
399 phREF->SharedBuffer[i].bufferFd = -1;
400 phREF->SharedBuffer[i].bufferFd1 = -1;
401 phREF->SharedBuffer[i].bufferFd2 = -1;
402 phREF->SharedBuffer[i].ionHandle = -1;
403 phREF->SharedBuffer[i].ionHandle1 = -1;
404 phREF->SharedBuffer[i].ionHandle2 = -1;
405 }
406 }
407 Exynos_OSAL_MutexUnlock(phREF->hMutex);
408
409 EXIT:
410 FunctionOut();
411
412 return ret;
413 }
414
415 OMX_ERRORTYPE Exynos_OSAL_RefANB_Terminate(OMX_HANDLETYPE hREF)
416 {
417 OMX_ERRORTYPE ret = OMX_ErrorNone;
418 EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
419
420 FunctionIn();
421
422 if (phREF == NULL) {
423 ret = OMX_ErrorBadParameter;
424 goto EXIT;
425 }
426
427 Exynos_OSAL_RefANB_Reset(phREF);
428
429 phREF->pGrallocModule = NULL;
430
431 ret = Exynos_OSAL_MutexTerminate(phREF->hMutex);
432 if (ret != OMX_ErrorNone)
433 goto EXIT;
434
435 Exynos_OSAL_Free(phREF);
436 phREF = NULL;
437
438 EXIT:
439 FunctionOut();
440
441 return ret;
442 }
443
444 OMX_ERRORTYPE Exynos_OSAL_RefANB_Increase(
445 OMX_HANDLETYPE hREF,
446 OMX_PTR pBuffer,
447 PLANE_TYPE ePlaneType)
448 {
449 OMX_ERRORTYPE ret = OMX_ErrorNone;
450 EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
451 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
452
453 buffer_handle_t bufferHandle = (buffer_handle_t)pBuffer;
454 private_handle_t *priv_hnd = (private_handle_t *)bufferHandle;
455 gralloc_module_t *module = NULL;
456
457 ion_user_handle_t ionHandle = -1;
458 ion_user_handle_t ionHandle1 = -1;
459 ion_user_handle_t ionHandle2 = -1;
460 int i, nPlaneCnt;
461
462 FunctionIn();
463
464 if (phREF == NULL) {
465 ret = OMX_ErrorBadParameter;
466 goto EXIT;
467 }
468
469 eColorFormat = Exynos_OSAL_HAL2OMXColorFormat(priv_hnd->format);
470 if (eColorFormat == OMX_COLOR_FormatUnused) {
471 ret = OMX_ErrorUndefined;
472 goto EXIT;
473 }
474
475 nPlaneCnt = Exynos_OSAL_GetPlaneCount(eColorFormat, ePlaneType);
476 module = (gralloc_module_t *)phREF->pGrallocModule;
477
478 Exynos_OSAL_MutexLock(phREF->hMutex);
479
480 if ((priv_hnd->fd >= 0) &&
481 (nPlaneCnt >= 1)) {
482 if (ion_import(getIonFd(module), priv_hnd->fd, &ionHandle) < 0) {
483 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_import is failed(client:%d, fd:%d)", getIonFd(module), priv_hnd->fd);
484 ionHandle = -1;
485 }
486 }
487
488 if ((priv_hnd->fd1 >= 0) &&
489 (nPlaneCnt >= 2)) {
490 if (ion_import(getIonFd(module), priv_hnd->fd1, &ionHandle1) < 0) {
491 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_import is failed(client:%d, fd1:%d)", getIonFd(module), priv_hnd->fd1);
492 ionHandle1 = -1;
493 }
494 }
495
496 if ((priv_hnd->fd2 >= 0) &&
497 (nPlaneCnt == 3)) {
498 if (ion_import(getIonFd(module), priv_hnd->fd2, &ionHandle2) < 0) {
499 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_import is failed(client:%d, fd2:%d)", getIonFd(module), priv_hnd->fd2);
500 ionHandle2 = -1;
501 }
502 }
503
504 for (i = 0; i < MAX_BUFFER_REF; i++) {
505 if (phREF->SharedBuffer[i].bufferFd == priv_hnd->fd) {
506 phREF->SharedBuffer[i].cnt++;
507 break;
508 }
509 }
510
511 if (i >= MAX_BUFFER_REF) {
512 for (i = 0; i < MAX_BUFFER_REF; i++) {
513 if (phREF->SharedBuffer[i].bufferFd == -1) {
514 phREF->SharedBuffer[i].bufferFd = priv_hnd->fd;
515 phREF->SharedBuffer[i].bufferFd1 = priv_hnd->fd1;
516 phREF->SharedBuffer[i].bufferFd2 = priv_hnd->fd2;
517 phREF->SharedBuffer[i].ionHandle = ionHandle;
518 phREF->SharedBuffer[i].ionHandle1 = ionHandle1;
519 phREF->SharedBuffer[i].ionHandle2 = ionHandle2;
520 phREF->SharedBuffer[i].cnt++;
521 break;
522 }
523 }
524 }
525
526 if (i >= MAX_BUFFER_REF) {
527 ret = OMX_ErrorUndefined;
528 Exynos_OSAL_MutexUnlock(phREF->hMutex);
529 goto EXIT;
530 }
531
532 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "inc fd:%d cnt:%d", phREF->SharedBuffer[i].bufferFd, phREF->SharedBuffer[i].cnt);
533 Exynos_OSAL_MutexUnlock(phREF->hMutex);
534
535 EXIT:
536 FunctionOut();
537
538 return ret;
539 }
540
541 OMX_ERRORTYPE Exynos_OSAL_RefANB_Decrease(OMX_HANDLETYPE hREF, OMX_S32 bufferFd)
542 {
543
544 OMX_ERRORTYPE ret = OMX_ErrorNone;
545 EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
546 gralloc_module_t *module = NULL;
547
548 int i;
549
550 FunctionIn();
551
552 if ((phREF == NULL) || (bufferFd < 0)) {
553 ret = OMX_ErrorBadParameter;
554 goto EXIT;
555 }
556
557 module = (gralloc_module_t *)phREF->pGrallocModule;
558
559 Exynos_OSAL_MutexLock(phREF->hMutex);
560
561 for (i = 0; i < MAX_BUFFER_REF; i++) {
562 if (phREF->SharedBuffer[i].bufferFd == bufferFd) {
563 if (phREF->SharedBuffer[i].ionHandle != -1)
564 ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle);
565 if (phREF->SharedBuffer[i].ionHandle1 != -1)
566 ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle1);
567 if (phREF->SharedBuffer[i].ionHandle2 != -1)
568 ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle2);
569 phREF->SharedBuffer[i].cnt--;
570
571 if (phREF->SharedBuffer[i].cnt == 0) {
572 phREF->SharedBuffer[i].bufferFd = -1;
573 phREF->SharedBuffer[i].bufferFd1 = -1;
574 phREF->SharedBuffer[i].bufferFd2 = -1;
575 phREF->SharedBuffer[i].ionHandle = -1;
576 phREF->SharedBuffer[i].ionHandle1 = -1;
577 phREF->SharedBuffer[i].ionHandle2 = -1;
578 }
579 break;
580 }
581 }
582
583 if (i >= MAX_BUFFER_REF) {
584 ret = OMX_ErrorUndefined;
585 Exynos_OSAL_MutexUnlock(phREF->hMutex);
586 goto EXIT;
587 }
588
589 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "dec fd:%d cnt:%d", phREF->SharedBuffer[i].bufferFd, phREF->SharedBuffer[i].cnt);
590 Exynos_OSAL_MutexUnlock(phREF->hMutex);
591
592 EXIT:
593 FunctionOut();
594
595 return ret;
596 }
597
598 OMX_ERRORTYPE useAndroidNativeBuffer(
599 EXYNOS_OMX_BASEPORT *pExynosPort,
600 OMX_BUFFERHEADERTYPE **ppBufferHdr,
601 OMX_U32 nPortIndex,
602 OMX_PTR pAppPrivate,
603 OMX_U32 nSizeBytes,
604 OMX_U8 *pBuffer)
605 {
606 OMX_ERRORTYPE ret = OMX_ErrorNone;
607 OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL;
608 unsigned int i = 0;
609 OMX_U32 width, height;
610 OMX_U32 stride;
611 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
612
613 FunctionIn();
614
615 if (pExynosPort == NULL) {
616 ret = OMX_ErrorBadParameter;
617 goto EXIT;
618 }
619 if (pExynosPort->portState != OMX_StateIdle) {
620 ret = OMX_ErrorIncorrectStateOperation;
621 goto EXIT;
622 }
623 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
624 ret = OMX_ErrorBadPortIndex;
625 goto EXIT;
626 }
627
628 temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
629 if (temp_bufferHeader == NULL) {
630 ret = OMX_ErrorInsufficientResources;
631 goto EXIT;
632 }
633 Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
634
635 for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
636 if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
637 pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader;
638 pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED);
639 INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE);
640 if (pExynosPort->eANBType == NATIVE_GRAPHIC_BUFFER1) {
641 android_native_buffer_t *pANB = (android_native_buffer_t *)pBuffer;
642 temp_bufferHeader->pBuffer = (OMX_U8 *)pANB->handle;
643 } else {
644 temp_bufferHeader->pBuffer = (OMX_U8 *)pBuffer;
645 }
646 temp_bufferHeader->nAllocLen = nSizeBytes;
647 temp_bufferHeader->pAppPrivate = pAppPrivate;
648 if (nPortIndex == INPUT_PORT_INDEX)
649 temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX;
650 else
651 temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX;
652
653 width = pExynosPort->portDefinition.format.video.nFrameWidth;
654 height = pExynosPort->portDefinition.format.video.nFrameHeight;
655 Exynos_OSAL_LockANBHandle(temp_bufferHeader->pBuffer, width, height,
656 pExynosPort->portDefinition.format.video.eColorFormat,
657 &stride, planes);
658 #ifdef USE_DMA_BUF
659 pExynosPort->extendBufferHeader[i].buf_fd[0] = planes[0].fd;
660 pExynosPort->extendBufferHeader[i].buf_fd[1] = planes[1].fd;
661 pExynosPort->extendBufferHeader[i].buf_fd[2] = planes[2].fd;
662 #endif
663 pExynosPort->extendBufferHeader[i].pYUVBuf[0] = planes[0].addr;
664 pExynosPort->extendBufferHeader[i].pYUVBuf[1] = planes[1].addr;
665 pExynosPort->extendBufferHeader[i].pYUVBuf[2] = planes[2].addr;
666 Exynos_OSAL_UnlockANBHandle(temp_bufferHeader->pBuffer);
667 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "useAndroidNativeBuffer: buf %d pYUVBuf[0]:0x%x , pYUVBuf[1]:0x%x ",
668 i, pExynosPort->extendBufferHeader[i].pYUVBuf[0],
669 pExynosPort->extendBufferHeader[i].pYUVBuf[1]);
670
671 pExynosPort->assignedBufferNum++;
672 if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
673 pExynosPort->portDefinition.bPopulated = OMX_TRUE;
674 /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
675 Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
676 /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
677 }
678 *ppBufferHdr = temp_bufferHeader;
679 ret = OMX_ErrorNone;
680
681 goto EXIT;
682 }
683 }
684
685 Exynos_OSAL_Free(temp_bufferHeader);
686 ret = OMX_ErrorInsufficientResources;
687
688 EXIT:
689 FunctionOut();
690
691 return ret;
692 }
693
694 OMX_ERRORTYPE Exynos_OSAL_GetAndroidParameter(
695 OMX_IN OMX_HANDLETYPE hComponent,
696 OMX_IN OMX_INDEXTYPE nIndex,
697 OMX_INOUT OMX_PTR ComponentParameterStructure)
698 {
699 OMX_ERRORTYPE ret = OMX_ErrorNone;
700 OMX_COMPONENTTYPE *pOMXComponent = NULL;
701 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
702
703 FunctionIn();
704
705 if (hComponent == NULL) {
706 ret = OMX_ErrorBadParameter;
707 goto EXIT;
708 }
709
710 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
711 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
712 if (ret != OMX_ErrorNone)
713 goto EXIT;
714
715 if (pOMXComponent->pComponentPrivate == NULL) {
716 ret = OMX_ErrorBadParameter;
717 goto EXIT;
718 }
719
720 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
721 if (pExynosComponent->currentState == OMX_StateInvalid) {
722 ret = OMX_ErrorInvalidState;
723 goto EXIT;
724 }
725
726 if (ComponentParameterStructure == NULL) {
727 ret = OMX_ErrorBadParameter;
728 goto EXIT;
729 }
730
731 switch ((int)nIndex) {
732 #ifdef USE_ANB
733 case OMX_IndexParamGetAndroidNativeBuffer:
734 {
735 GetAndroidNativeBufferUsageParams *pANBParams = (GetAndroidNativeBufferUsageParams *) ComponentParameterStructure;
736 OMX_U32 portIndex = pANBParams->nPortIndex;
737
738 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamGetAndroidNativeBuffer", __func__);
739
740 ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(GetAndroidNativeBufferUsageParams));
741 if (ret != OMX_ErrorNone) {
742 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(GetAndroidNativeBufferUsageParams) is failed", __func__);
743 goto EXIT;
744 }
745
746 if (portIndex >= pExynosComponent->portParam.nPorts) {
747 ret = OMX_ErrorBadPortIndex;
748 goto EXIT;
749 }
750
751 /* NOTE: OMX_IndexParamGetAndroidNativeBuffer returns original 'nUsage' without any
752 * modifications since currently not defined what the 'nUsage' is for.
753 */
754 pANBParams->nUsage |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
755 #if defined(USE_IMPROVED_BUFFER) && !defined(USE_CSC_HW) && !defined(USE_NON_CACHED_GRAPHICBUFFER)
756 pANBParams->nUsage |= (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
757 #endif
758 #if defined(USE_MFC5X_ALIGNMENT)
759 if ((pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferProcessType & BUFFER_SHARE) &&
760 (pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)) {
761 pANBParams->nUsage |= GRALLOC_USAGE_PRIVATE_0;
762 }
763 #endif
764 if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) { // secure decoder component
765 /* never knows actual image size before parsing a header info
766 * could not guarantee DRC(Dynamic Resolution Chnage) case */
767 EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
768 unsigned int HD_SIZE = 1280 * 720 * 3 / 2; /* 720p */
769
770 if ((pExynosPort->portDefinition.format.video.nFrameWidth *
771 pExynosPort->portDefinition.format.video.nFrameHeight * 3 / 2) > HD_SIZE) { /* over than 720p */
772 pANBParams->nUsage |= GRALLOC_USAGE_PROTECTED_DPB; /* try to use a CMA area */
773 }
774 }
775 }
776 break;
777 case OMX_IndexParamConsumerUsageBits:
778 {
779 OMX_U32 *pUsageBits = (OMX_U32 *)ComponentParameterStructure;
780
781 switch ((int)pExynosComponent->codecType) {
782 case HW_VIDEO_ENC_CODEC:
783 (*pUsageBits) = GRALLOC_USAGE_HW_VIDEO_ENCODER;
784 break;
785 case HW_VIDEO_ENC_SECURE_CODEC:
786 (*pUsageBits) = GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_PROTECTED;
787 break;
788 default:
789 (*pUsageBits) = 0;
790 ret = OMX_ErrorUnsupportedIndex;
791 break;
792 }
793 }
794 break;
795 #endif
796 default:
797 {
798 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex);
799 ret = OMX_ErrorUnsupportedIndex;
800 goto EXIT;
801 }
802 break;
803 }
804
805 EXIT:
806 FunctionOut();
807
808 return ret;
809 }
810
811 OMX_ERRORTYPE Exynos_OSAL_SetAndroidParameter(
812 OMX_IN OMX_HANDLETYPE hComponent,
813 OMX_IN OMX_INDEXTYPE nIndex,
814 OMX_IN OMX_PTR ComponentParameterStructure)
815 {
816 OMX_ERRORTYPE ret = OMX_ErrorNone;
817 OMX_COMPONENTTYPE *pOMXComponent = NULL;
818 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
819
820 FunctionIn();
821
822 if (hComponent == NULL) {
823 ret = OMX_ErrorBadParameter;
824 goto EXIT;
825 }
826
827 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
828 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
829 if (ret != OMX_ErrorNone) {
830 goto EXIT;
831 }
832
833 if (pOMXComponent->pComponentPrivate == NULL) {
834 ret = OMX_ErrorBadParameter;
835 goto EXIT;
836 }
837
838 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
839 if (pExynosComponent->currentState == OMX_StateInvalid ) {
840 ret = OMX_ErrorInvalidState;
841 goto EXIT;
842 }
843
844 if (ComponentParameterStructure == NULL) {
845 ret = OMX_ErrorBadParameter;
846 goto EXIT;
847 }
848
849 switch ((int)nIndex) {
850 #ifdef USE_ANB
851 case OMX_IndexParamEnableAndroidBuffers:
852 {
853 EnableAndroidNativeBuffersParams *pANBParams = (EnableAndroidNativeBuffersParams *) ComponentParameterStructure;
854 OMX_U32 portIndex = pANBParams->nPortIndex;
855 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
856
857 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamEnableAndroidNativeBuffers", __func__);
858
859 ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(EnableAndroidNativeBuffersParams));
860 if (ret != OMX_ErrorNone) {
861 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(EnableAndroidNativeBuffersParams) is failed", __func__);
862 goto EXIT;
863 }
864
865 if (portIndex >= pExynosComponent->portParam.nPorts) {
866 ret = OMX_ErrorBadPortIndex;
867 goto EXIT;
868 }
869
870 pExynosPort = &pExynosComponent->pExynosPort[portIndex];
871 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
872 ret = OMX_ErrorBadPortIndex;
873 goto EXIT;
874 }
875
876 if (pExynosPort->bStoreMetaData != OMX_TRUE) {
877 if (portIndex == OUTPUT_PORT_INDEX) {
878 if (pANBParams->enable == OMX_TRUE) {
879 ret = setBufferProcessTypeForDecoder(pExynosPort);
880 if (ret != OMX_ErrorNone)
881 goto EXIT;
882 } else if ((pANBParams->enable == OMX_FALSE) &&
883 (pExynosPort->bIsANBEnabled == OMX_TRUE)) {
884 /* reset to initialized value */
885 resetBufferProcessTypeForDecoder(pExynosPort);
886 }
887 }
888
889 pExynosPort->bIsANBEnabled = pANBParams->enable;
890 }
891 }
892 break;
893
894 case OMX_IndexParamUseAndroidNativeBuffer:
895 {
896 UseAndroidNativeBufferParams *pANBParams = (UseAndroidNativeBufferParams *) ComponentParameterStructure;
897 OMX_U32 portIndex = pANBParams->nPortIndex;
898 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
899 android_native_buffer_t *pANB;
900 OMX_U32 nSizeBytes;
901
902 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamUseAndroidNativeBuffer, portIndex: %d", __func__, portIndex);
903
904 ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(UseAndroidNativeBufferParams));
905 if (ret != OMX_ErrorNone) {
906 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(UseAndroidNativeBufferParams) is failed", __func__);
907 goto EXIT;
908 }
909
910 if (portIndex >= pExynosComponent->portParam.nPorts) {
911 ret = OMX_ErrorBadPortIndex;
912 goto EXIT;
913 }
914
915 pExynosPort = &pExynosComponent->pExynosPort[portIndex];
916 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
917 ret = OMX_ErrorBadPortIndex;
918 goto EXIT;
919 }
920
921 if (pExynosPort->portState != OMX_StateIdle) {
922 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Port state should be IDLE", __func__);
923 ret = OMX_ErrorIncorrectStateOperation;
924 goto EXIT;
925 }
926
927 pANB = pANBParams->nativeBuffer.get();
928
929 /* MALI alignment restriction */
930 nSizeBytes = ALIGN(pANB->width, 16) * ALIGN(pANB->height, 16);
931 nSizeBytes += ALIGN(pANB->width / 2, 16) * ALIGN(pANB->height / 2, 16) * 2;
932
933 ret = useAndroidNativeBuffer(pExynosPort,
934 pANBParams->bufferHeader,
935 pANBParams->nPortIndex,
936 pANBParams->pAppPrivate,
937 nSizeBytes,
938 (OMX_U8 *) pANB);
939 if (ret != OMX_ErrorNone) {
940 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: useAndroidNativeBuffer is failed: err=0x%x", __func__,ret);
941 goto EXIT;
942 }
943 }
944 break;
945 #endif
946
947 #ifdef USE_STOREMETADATA
948 case OMX_IndexParamStoreMetaDataBuffer:
949 {
950 StoreMetaDataInBuffersParams *pMetaParams = (StoreMetaDataInBuffersParams *)ComponentParameterStructure;
951 OMX_U32 portIndex = pMetaParams->nPortIndex;
952 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
953
954 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamStoreMetaDataBuffer", __func__);
955
956 ret = Exynos_OMX_Check_SizeVersion(pMetaParams, sizeof(StoreMetaDataInBuffersParams));
957 if (ret != OMX_ErrorNone) {
958 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(StoreMetaDataInBuffersParams) is failed", __func__);
959 goto EXIT;
960 }
961
962 if (portIndex >= pExynosComponent->portParam.nPorts) {
963 ret = OMX_ErrorBadPortIndex;
964 goto EXIT;
965 }
966
967 if ((pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) ||
968 (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)) {
969 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
970 if ((portIndex == INPUT_PORT_INDEX) ||
971 (pOutputPort->bDynamicDPBMode == OMX_FALSE)) {
972 ret = OMX_ErrorUndefined;
973 goto EXIT;
974 }
975 }
976
977 pExynosPort = &pExynosComponent->pExynosPort[portIndex];
978 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
979 ret = OMX_ErrorBadPortIndex;
980 goto EXIT;
981 }
982
983 if (((pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) ||
984 (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)) &&
985 (portIndex == OUTPUT_PORT_INDEX)) {
986 if (pMetaParams->bStoreMetaData == OMX_TRUE) {
987 pExynosPort->bStoreMetaData = pMetaParams->bStoreMetaData;
988 ret = setBufferProcessTypeForDecoder(pExynosPort);
989 } else if ((pMetaParams->bStoreMetaData == OMX_FALSE) &&
990 (pExynosPort->bStoreMetaData == OMX_TRUE)) {
991 /* reset to initialized value */
992 resetBufferProcessTypeForDecoder(pExynosPort);
993 }
994 }
995
996 pExynosPort->bStoreMetaData = pMetaParams->bStoreMetaData;
997 }
998 break;
999 #endif
1000
1001 default:
1002 {
1003 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex);
1004 ret = OMX_ErrorUnsupportedIndex;
1005 goto EXIT;
1006 }
1007 break;
1008 }
1009
1010 EXIT:
1011 FunctionOut();
1012
1013 return ret;
1014 }
1015
1016 OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(OMX_IN OMX_BYTE pBuffer,
1017 OMX_OUT OMX_PTR *ppBuf)
1018 {
1019 OMX_ERRORTYPE ret = OMX_ErrorNone;
1020 MetadataBufferType type;
1021
1022 FunctionIn();
1023
1024 /*
1025 * meta data contains the following data format.
1026 * payload depends on the MetadataBufferType
1027 * ---------------------------------------------------------------
1028 * | MetadataBufferType | payload |
1029 * ---------------------------------------------------------------
1030 *
1031 * If MetadataBufferType is kMetadataBufferTypeCameraSource, then
1032 * ---------------------------------------------------------------
1033 * | kMetadataBufferTypeCameraSource | addr. of Y | addr. of UV |
1034 * ---------------------------------------------------------------
1035 *
1036 * If MetadataBufferType is kMetadataBufferTypeGrallocSource, then
1037 * ---------------------------------------------------------------
1038 * | kMetadataBufferTypeGrallocSource | buffer_handle_t |
1039 * ---------------------------------------------------------------
1040 */
1041
1042 /* MetadataBufferType */
1043 Exynos_OSAL_Memcpy(&type, (MetadataBufferType *)pBuffer, sizeof(MetadataBufferType));
1044
1045 switch ((int)type) {
1046 case kMetadataBufferTypeCameraSource:
1047 {
1048 void *pAddress = NULL;
1049
1050 /* Address. of Y */
1051 Exynos_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType), sizeof(void *));
1052 ppBuf[0] = (void *)pAddress;
1053
1054 /* Address. of CbCr */
1055 Exynos_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType) + sizeof(void *), sizeof(void *));
1056 ppBuf[1] = (void *)pAddress;
1057
1058 if ((ppBuf[0] == NULL) || (ppBuf[1] == NULL))
1059 ret = OMX_ErrorBadParameter;
1060 }
1061 break;
1062 case kMetadataBufferTypeGrallocSource:
1063 {
1064 buffer_handle_t pBufHandle;
1065
1066 /* buffer_handle_t */
1067 Exynos_OSAL_Memcpy(&pBufHandle, pBuffer + sizeof(MetadataBufferType), sizeof(buffer_handle_t));
1068 ppBuf[0] = (OMX_PTR)pBufHandle;
1069
1070 if (ppBuf[0] == NULL) {
1071 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "GrallocBuffer's pHandle is NULL");
1072 ret = OMX_ErrorBadParameter;
1073 }
1074 }
1075 break;
1076 default:
1077 {
1078 ret = OMX_ErrorBadParameter;
1079 }
1080 break;
1081 }
1082
1083 EXIT:
1084 FunctionOut();
1085
1086 return ret;
1087 }
1088
1089 OMX_ERRORTYPE Exynos_OSAL_GetBufferFdFromMetaData(
1090 OMX_IN OMX_BYTE pBuffer,
1091 OMX_OUT OMX_PTR *ppBuf)
1092 {
1093 OMX_ERRORTYPE ret = OMX_ErrorNone;
1094 MetadataBufferType type = kMetadataBufferTypeInvalid;
1095
1096 FunctionIn();
1097
1098 /* MetadataBufferType */
1099 Exynos_OSAL_Memcpy(&type, (MetadataBufferType *)pBuffer, sizeof(MetadataBufferType));
1100
1101 switch ((int)type) {
1102 case kMetadataBufferTypeCameraSource:
1103 {
1104 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Unsupport Type of MetadataBuffer", __FUNCTION__, __LINE__);
1105 }
1106 break;
1107 case kMetadataBufferTypeGrallocSource:
1108 {
1109 VideoGrallocMetadata *pMetaData = (VideoGrallocMetadata *)pBuffer;
1110 buffer_handle_t bufferHandle = (buffer_handle_t)pMetaData->pHandle;
1111 native_handle_t *pNativeHandle = (native_handle_t *)bufferHandle;
1112
1113 /* ION FD. */
1114 ppBuf[0] = INT_TO_PTR(pNativeHandle->data[0]);
1115 }
1116 break;
1117 default:
1118 {
1119 ret = OMX_ErrorBadParameter;
1120 }
1121 break;
1122 }
1123
1124 EXIT:
1125 FunctionOut();
1126
1127 return ret;
1128 }
1129
1130 OMX_ERRORTYPE Exynos_OSAL_SetDataLengthToMetaData(
1131 OMX_IN OMX_BYTE pBuffer,
1132 OMX_IN OMX_U32 dataLength)
1133 {
1134 OMX_ERRORTYPE ret = OMX_ErrorNone;
1135 MetadataBufferType type = kMetadataBufferTypeInvalid;
1136
1137 FunctionIn();
1138
1139 /* MetadataBufferType */
1140 Exynos_OSAL_Memcpy(&type, (MetadataBufferType *)pBuffer, sizeof(MetadataBufferType));
1141
1142 switch ((int)type) {
1143 case kMetadataBufferTypeCameraSource:
1144 {
1145 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Unsupport Type of MetadataBuffer", __FUNCTION__, __LINE__);
1146 }
1147 break;
1148 case kMetadataBufferTypeGrallocSource:
1149 {
1150 VideoGrallocMetadata *pMetaData = (VideoGrallocMetadata *)pBuffer;
1151 buffer_handle_t bufferHandle = (buffer_handle_t)pMetaData->pHandle;
1152 native_handle_t *pNativeHandle = (native_handle_t *)bufferHandle;
1153
1154 /* size of stream */
1155 pNativeHandle->data[3] = dataLength;
1156 }
1157 break;
1158 default:
1159 {
1160 ret = OMX_ErrorBadParameter;
1161 }
1162 break;
1163 }
1164
1165 EXIT:
1166 FunctionOut();
1167
1168 return ret;
1169 }
1170
1171 OMX_PTR Exynos_OSAL_AllocMetaDataBuffer(
1172 OMX_HANDLETYPE hSharedMemory,
1173 EXYNOS_CODEC_TYPE codecType,
1174 OMX_U32 nPortIndex,
1175 OMX_U32 nSizeBytes,
1176 MEMORY_TYPE eMemoryType)
1177 {
1178 /*
1179 * meta data contains the following data format.
1180 * payload depends on the MetadataBufferType
1181 * ---------------------------------------------------------------
1182 * | MetadataBufferType | payload |
1183 * ---------------------------------------------------------------
1184 * If MetadataBufferType is kMetadataBufferTypeGrallocSource, then
1185 * ---------------------------------------------------------------
1186 * | kMetadataBufferTypeGrallocSource | buffer_handle_t |
1187 * ---------------------------------------------------------------
1188 */
1189
1190 #define ENC_OUT_FD_NUM 1
1191 #define EXTRA_DATA_NUM 3
1192
1193 VideoGrallocMetadata *pMetaData = NULL;
1194 buffer_handle_t bufferHandle = NULL;
1195 native_handle_t *pNativeHandle = NULL;
1196
1197 OMX_PTR pTempBuffer = NULL;
1198 OMX_PTR pTempVirAdd = NULL;
1199 OMX_U32 nTempFD = 0;
1200
1201 if (((codecType == HW_VIDEO_ENC_CODEC) ||
1202 (codecType == HW_VIDEO_ENC_SECURE_CODEC)) &&
1203 (nPortIndex == OUTPUT_PORT_INDEX)) {
1204 pTempBuffer = Exynos_OSAL_Malloc(MAX_METADATA_BUFFER_SIZE);
1205 if (pTempBuffer == NULL) {
1206 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Error InsufficientResources", __FUNCTION__, __LINE__);
1207 goto EXIT;
1208 }
1209
1210 pNativeHandle = native_handle_create(ENC_OUT_FD_NUM, EXTRA_DATA_NUM);
1211 if (pNativeHandle == NULL) {
1212 Exynos_OSAL_Free(pTempBuffer);
1213 pTempBuffer = NULL;
1214 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Error InsufficientResources", __FUNCTION__, __LINE__);
1215 goto EXIT;
1216 }
1217
1218 pTempVirAdd = Exynos_OSAL_SharedMemory_Alloc(hSharedMemory, nSizeBytes, eMemoryType);
1219 if (pTempVirAdd == NULL) {
1220 native_handle_delete(pNativeHandle);
1221 pNativeHandle = NULL;
1222 Exynos_OSAL_Free(pTempBuffer);
1223 pTempBuffer = NULL;
1224 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Error InsufficientResources", __FUNCTION__, __LINE__);
1225 goto EXIT;
1226 }
1227
1228 nTempFD = Exynos_OSAL_SharedMemory_VirtToION(hSharedMemory, pTempVirAdd);
1229
1230 pNativeHandle->data[0] = (int)nTempFD;
1231 pNativeHandle->data[1] = PTR_TO_INT(pTempVirAdd); /* caution : data loss & FIXME : remove */
1232 pNativeHandle->data[2] = (int)nSizeBytes;
1233 pNativeHandle->data[3] = (int)0;
1234
1235 pMetaData = (VideoGrallocMetadata *)pTempBuffer;
1236 bufferHandle = (buffer_handle_t)pNativeHandle;
1237
1238 pMetaData->eType = kMetadataBufferTypeGrallocSource;
1239 pMetaData->pHandle = bufferHandle;
1240 } else {
1241 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Unsupport MetadataBuffer", __FUNCTION__, __LINE__);
1242 pTempBuffer = NULL;
1243 }
1244
1245 EXIT:
1246 return pTempBuffer;
1247 }
1248
1249 OMX_ERRORTYPE Exynos_OSAL_FreeMetaDataBuffer(
1250 OMX_HANDLETYPE hSharedMemory,
1251 EXYNOS_CODEC_TYPE codecType,
1252 OMX_U32 nPortIndex,
1253 OMX_PTR pTempBuffer)
1254 {
1255 OMX_ERRORTYPE ret = OMX_ErrorNone;
1256
1257 OMX_U32 nTempFD = 0;
1258 OMX_PTR pTempVirAdd = NULL;
1259
1260 VideoGrallocMetadata *pMetaData = NULL;
1261 buffer_handle_t bufferHandle = NULL;
1262 native_handle_t *pNativeHandle = NULL;
1263
1264 if (((codecType == HW_VIDEO_ENC_CODEC) ||
1265 (codecType == HW_VIDEO_ENC_SECURE_CODEC)) &&
1266 (nPortIndex == OUTPUT_PORT_INDEX)) {
1267 if (*(MetadataBufferType *)(pTempBuffer) != (MetadataBufferType)kMetadataBufferTypeGrallocSource) {
1268 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Invalid MetaDataBuffer", __FUNCTION__, __LINE__);
1269 ret = OMX_ErrorBadParameter;
1270 goto EXIT;
1271 }
1272
1273 pMetaData = (VideoGrallocMetadata *)pTempBuffer;
1274 bufferHandle = (buffer_handle_t)pMetaData->pHandle;
1275 pNativeHandle = (native_handle_t *)bufferHandle;
1276
1277 nTempFD = (OMX_U32)pNativeHandle->data[0];
1278 pTempVirAdd = Exynos_OSAL_SharedMemory_IONToVirt(hSharedMemory, nTempFD);
1279
1280 Exynos_OSAL_SharedMemory_Free(hSharedMemory, pTempVirAdd);
1281
1282 native_handle_delete(pNativeHandle);
1283
1284 Exynos_OSAL_Free(pTempBuffer);
1285
1286 ret = OMX_ErrorNone;
1287 } else {
1288 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Unsupport MetadataBuffer", __FUNCTION__, __LINE__);
1289 ret = OMX_ErrorNotImplemented;
1290 }
1291
1292 EXIT:
1293 return ret;
1294 }
1295
1296 OMX_ERRORTYPE Exynos_OSAL_SetPrependSPSPPSToIDR(
1297 OMX_PTR pComponentParameterStructure,
1298 OMX_PTR pbPrependSpsPpsToIdr)
1299 {
1300 OMX_ERRORTYPE ret = OMX_ErrorNone;
1301 PrependSPSPPSToIDRFramesParams *pParams = (PrependSPSPPSToIDRFramesParams *)pComponentParameterStructure;
1302
1303 ret = Exynos_OMX_Check_SizeVersion(pParams, sizeof(PrependSPSPPSToIDRFramesParams));
1304 if (ret != OMX_ErrorNone) {
1305 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(PrependSPSPPSToIDRFramesParams) is failed", __func__);
1306 goto EXIT;
1307 }
1308
1309 (*((OMX_BOOL *)pbPrependSpsPpsToIdr)) = pParams->bEnable;
1310
1311 EXIT:
1312 return ret;
1313 }
1314
1315 OMX_U32 Exynos_OSAL_GetDisplayExtraBufferCount(void)
1316 {
1317 char value[PROPERTY_VALUE_MAX] = {0, };
1318
1319 if (property_get("debug.hwc.otf", value, NULL)) {
1320 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "DisplayExtraBufferCount is 3. The OTF exist");
1321 return 3; /* Display System has OTF */
1322 }
1323
1324 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "DisplayExtraBufferCount is 2. The OTF not exist");
1325 return 2; /* min count */
1326 }
1327
1328 #ifdef __cplusplus
1329 }
1330 #endif