Add feature for tizen allocator
[platform/adaptation/ap_samsung/libomxil-e9110-v4l2.git] / openmax / osal / Exynos_OSAL_Tizen.c
1 /*
2  * Copyright 2016 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_Tizen.c
19  * @brief
20  * @author      Taehwan Kim (t_h.kim@samsung.com)
21  * @version     1.0.0
22  * @history
23  *   2016.06.13 : Create
24  */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28
29 #include "Exynos_OSAL_Semaphore.h"
30 #include "Exynos_OMX_Baseport.h"
31 #include "Exynos_OMX_Basecomponent.h"
32 #include "Exynos_OMX_Macros.h"
33 #include "Exynos_OSAL_Platform.h"
34 #include "Exynos_OSAL_ETC.h"
35 #include "exynos_format.h"
36
37 #include "ExynosVideoApi.h"
38
39 #ifdef TIZEN_FEATURE_TIZEN_ALLOCATOR
40 #include <tbm_bufmgr.h>
41 #include <tbm_surface.h>
42 #include <tbm_surface_internal.h>
43 #else
44 #include <mmf/mm_types.h>
45 #endif
46
47 #undef  EXYNOS_LOG_TAG
48 #define EXYNOS_LOG_TAG    "Exynos_OSAL_Tizen"
49 //#define EXYNOS_LOG_OFF
50 #include "Exynos_OSAL_Log.h"
51
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55
56 typedef struct __EnableGemBuffersParams
57 {
58   OMX_U32           nSize;
59   OMX_VERSIONTYPE   nVersion;
60   OMX_U32           nPortIndex;
61   OMX_BOOL          bStoreMetaData;
62 } EnableGemBuffersParams;
63
64 static OMX_ERRORTYPE setBufferProcessTypeForDecoder(EXYNOS_OMX_BASEPORT *pExynosPort)
65 {
66     OMX_ERRORTYPE ret = OMX_ErrorNone;
67
68     FunctionIn();
69
70     if (pExynosPort == NULL) {
71         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
72         ret = OMX_ErrorUndefined;
73         goto EXIT;
74     }
75
76     if ((pExynosPort->bufferProcessType == BUFFER_COPY) &&
77         (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
78         int i;
79         if (pExynosPort->supportFormat == NULL) {
80             ret = OMX_ErrorUndefined;
81             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] supported format is empty", __FUNCTION__);
82             goto EXIT;
83         }
84
85         pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
86         /* check to support NV12T format */
87         for (i = 0; pExynosPort->supportFormat[i] != OMX_COLOR_FormatUnused; i++) {
88             /* prefer to use NV12T */
89             if (pExynosPort->supportFormat[i] == (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled) {
90                 pExynosPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
91                 break;
92             }
93         }
94         pExynosPort->bufferProcessType = BUFFER_SHARE;
95
96         Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s] output buffer sharing mode is on (%x)",
97                                                 __FUNCTION__, pExynosPort->portDefinition.format.video.eColorFormat);
98     }
99
100 EXIT:
101     FunctionOut();
102
103     return ret;
104 }
105
106 static void resetBufferProcessTypeForDecoder(EXYNOS_OMX_BASEPORT *pExynosPort)
107 {
108     FunctionIn();
109
110     if (pExynosPort == NULL) {
111         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
112         goto EXIT;
113     }
114
115     pExynosPort->bufferProcessType = BUFFER_COPY;
116     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
117
118 EXIT:
119     FunctionOut();
120
121     return;
122 }
123
124 OMX_ERRORTYPE Exynos_OSAL_GetParameter(
125     OMX_IN OMX_HANDLETYPE hComponent,
126     OMX_IN OMX_INDEXTYPE  nIndex,
127     OMX_INOUT OMX_PTR     pComponentParameterStructure)
128 {
129     OMX_ERRORTYPE                ret                = OMX_ErrorNone;
130     OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
131     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
132
133     FunctionIn();
134
135     if (hComponent == NULL) {
136         ret = OMX_ErrorBadParameter;
137         goto EXIT;
138     }
139
140     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
141     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
142     if (ret != OMX_ErrorNone)
143         goto EXIT;
144
145     if (pOMXComponent->pComponentPrivate == NULL) {
146         ret = OMX_ErrorBadParameter;
147         goto EXIT;
148     }
149
150     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
151     if (pExynosComponent->currentState == OMX_StateInvalid) {
152         ret = OMX_ErrorInvalidState;
153         goto EXIT;
154     }
155
156     if (pComponentParameterStructure == NULL) {
157         ret = OMX_ErrorBadParameter;
158         goto EXIT;
159     }
160
161     switch ((int)nIndex) {
162     case OMX_IndexParamPortDefinition:
163     {
164         OMX_PARAM_PORTDEFINITIONTYPE    *pPortDef       = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
165         EXYNOS_OMX_BASEPORT             *pExynosPort    = &pExynosComponent->pExynosPort[pPortDef->nPortIndex];
166
167         if (pExynosPort->eMetaDataType == METADATA_TYPE_DATA)
168 #ifdef TIZEN_FEATURE_TIZEN_ALLOCATOR
169             pPortDef->nBufferSize = (ALIGN(pExynosPort->portDefinition.format.video.nFrameWidth, 16) *
170                                      ALIGN(pExynosPort->portDefinition.format.video.nFrameHeight, 16) * 3) / 2;
171 #else
172             pPortDef->nBufferSize = sizeof(MMVideoBuffer);
173 #endif
174     }
175         break;
176     default:
177     {
178         ret = OMX_ErrorUnsupportedIndex;
179         goto EXIT;
180     }
181         break;
182     }
183
184 EXIT:
185     FunctionOut();
186
187     return ret;
188 }
189
190 OMX_ERRORTYPE Exynos_OSAL_SetParameter(
191     OMX_IN OMX_HANDLETYPE hComponent,
192     OMX_IN OMX_INDEXTYPE  nIndex,
193     OMX_IN OMX_PTR        pComponentParameterStructure)
194 {
195     OMX_ERRORTYPE                ret                = OMX_ErrorNone;
196     OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
197     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
198
199     FunctionIn();
200
201     if (hComponent == NULL) {
202         ret = OMX_ErrorBadParameter;
203         goto EXIT;
204     }
205
206     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
207     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
208     if (ret != OMX_ErrorNone)
209         goto EXIT;
210
211     if (pOMXComponent->pComponentPrivate == NULL) {
212         ret = OMX_ErrorBadParameter;
213         goto EXIT;
214     }
215
216     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
217     if (pExynosComponent->currentState == OMX_StateInvalid) {
218         ret = OMX_ErrorInvalidState;
219         goto EXIT;
220     }
221
222     if (pComponentParameterStructure == NULL) {
223         ret = OMX_ErrorBadParameter;
224         goto EXIT;
225     }
226
227     Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
228     switch ((int)nIndex) {
229     case OMX_IndexParamStoreMetaDataBuffer:
230     {
231         EnableGemBuffersParams *pGBParams   = (EnableGemBuffersParams *)pComponentParameterStructure;
232         OMX_U32                 nPortIndex  = pGBParams->nPortIndex;
233         EXYNOS_OMX_BASEPORT    *pExynosPort = NULL;
234
235         ret = Exynos_OMX_Check_SizeVersion(pGBParams, sizeof(EnableGemBuffersParams));
236         if (ret != OMX_ErrorNone) {
237             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
238             goto EXIT;
239         }
240
241         if (nPortIndex >= pExynosComponent->portParam.nPorts) {
242             ret = OMX_ErrorBadPortIndex;
243             goto EXIT;
244         }
245
246         if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) ||
247             (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC)) {
248             /* decoder */
249             if (nPortIndex != OUTPUT_PORT_INDEX) {
250                 ret = OMX_ErrorNotImplemented;
251                 goto EXIT;
252             }
253         } else {
254             /* encoder */
255             if (nPortIndex != INPUT_PORT_INDEX) {
256                 ret = OMX_ErrorNotImplemented;
257                 goto EXIT;
258             }
259         }
260
261         pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
262         if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
263             ret = OMX_ErrorBadPortIndex;
264             goto EXIT;
265         }
266
267         Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][META] %s port: metadata mode(%x) -> %s",
268                                         pExynosComponent, __FUNCTION__,
269                                         (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
270                                         pExynosPort->eMetaDataType,
271                                         (pGBParams->bStoreMetaData == OMX_TRUE)? "enable":"disable");
272
273         if ((pGBParams->bStoreMetaData == OMX_TRUE) &&
274             (pExynosPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
275             pExynosPort->eMetaDataType = METADATA_TYPE_DATA;
276         }
277
278         /* in case of decoder output */
279         if ((nPortIndex == OUTPUT_PORT_INDEX) &&
280             ((pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) ||
281                 (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC))) {
282             if (pGBParams->bStoreMetaData == OMX_TRUE) {
283                 ret = setBufferProcessTypeForDecoder(pExynosPort);
284                 if (ret != OMX_ErrorNone)
285                     goto EXIT;
286             } else if ((pGBParams->bStoreMetaData == OMX_FALSE) &&
287                        (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
288                 resetBufferProcessTypeForDecoder(pExynosPort);
289             }
290         }
291
292         if ((pGBParams->bStoreMetaData == OMX_FALSE) &&
293             (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
294             pExynosPort->eMetaDataType = METADATA_TYPE_DISABLED;
295         }
296     }
297         break;
298     default:
299     {
300         ret = OMX_ErrorUnsupportedIndex;
301         goto EXIT;
302     }
303         break;
304     }
305
306 EXIT:
307     FunctionOut();
308
309     return ret;
310 }
311
312 /*
313  * meta data contains the following data format.
314  * 1) METADATA_TYPE_DATA
315  * --------------------------------------------------------------------
316  * | MMVideoBuffer                                                    | [DEC] out, [ENC] in
317  * --------------------------------------------------------------------
318  */
319 OMX_ERRORTYPE Exynos_OSAL_LockMetaData(
320     OMX_IN OMX_PTR                          pBuffer,
321     OMX_IN EXYNOS_OMX_LOCK_RANGE            range,
322     OMX_OUT OMX_U32                        *pStride,
323     OMX_OUT EXYNOS_OMX_MULTIPLANE_BUFFER   *pBufferInfo,
324     OMX_IN EXYNOS_METADATA_TYPE             eMetaType)
325 {
326     OMX_ERRORTYPE ret = OMX_ErrorNone;
327
328     FunctionIn();
329
330     if (pBuffer == NULL) {
331         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
332         ret = OMX_ErrorBadParameter;
333         goto EXIT;
334     }
335
336     /* not used yet */
337
338 EXIT:
339     FunctionOut();
340
341     return ret;
342 }
343
344 OMX_ERRORTYPE Exynos_OSAL_UnlockMetaData(
345     OMX_IN OMX_PTR              pBuffer,
346     OMX_IN EXYNOS_METADATA_TYPE eMetaType)
347 {
348     OMX_ERRORTYPE ret = OMX_ErrorNone;
349
350     FunctionIn();
351
352     if (pBuffer == NULL) {
353         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
354         ret = OMX_ErrorBadParameter;
355         goto EXIT;
356     }
357
358     /* not used yet */
359
360 EXIT:
361     FunctionOut();
362
363     return ret;
364 }
365
366 OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(
367     OMX_IN OMX_PTR                          pBuffer,
368     OMX_OUT EXYNOS_OMX_MULTIPLANE_BUFFER   *pBufferInfo,
369     OMX_IN EXYNOS_METADATA_TYPE             eMetaDataType)
370 {
371     OMX_ERRORTYPE    ret            = OMX_ErrorNone;
372 #ifdef TIZEN_FEATURE_TIZEN_ALLOCATOR
373     tbm_surface_h surface;
374     tbm_bo bo[2];
375 #else
376     MMVideoBuffer   *pMetaBuffer    = NULL;
377 #endif
378
379     int i;
380
381     FunctionIn();
382
383     if ((pBuffer == NULL) ||
384         (pBufferInfo == NULL) ||
385         (eMetaDataType == METADATA_TYPE_DISABLED)) {
386         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
387         ret = OMX_ErrorBadParameter;
388         goto EXIT;
389     }
390
391     if (eMetaDataType == METADATA_TYPE_DATA) {
392 #ifdef TIZEN_FEATURE_TIZEN_ALLOCATOR
393         surface = (tbm_surface_h)pBuffer;
394
395         bo[0] = tbm_surface_internal_get_bo(surface, 0);
396         bo[1] = tbm_surface_internal_get_bo(surface, 1);
397
398         for (i = 0; i < 2; i++) {
399             pBufferInfo->fd[i]   = (unsigned long)(tbm_bo_get_handle (bo[i], TBM_DEVICE_MM).u32);
400             pBufferInfo->addr[i] = (OMX_PTR)(tbm_bo_get_handle (bo[i], TBM_DEVICE_CPU).ptr);
401 #else
402         pMetaBuffer = (MMVideoBuffer *)pBuffer;
403
404         for (i = 0; i < pMetaBuffer->plane_num; i++) {
405             pBufferInfo->fd[i]   = (unsigned long)(pMetaBuffer->handle.dmabuf_fd[i]);
406             pBufferInfo->addr[i] = (OMX_PTR)(pMetaBuffer->data[i]);
407 #endif
408
409             Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s] Plane[%d]: FD(%u), VA(%p)",
410                                                     __FUNCTION__, i, pBufferInfo->fd[i], pBufferInfo->addr[i]);
411         }
412     } else {
413         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] not implemented yet(meta type:0x%x)", __FUNCTION__, eMetaDataType);
414         ret = OMX_ErrorNotImplemented;
415         goto EXIT;
416     }
417
418 EXIT:
419     FunctionOut();
420
421     return ret;
422 }
423
424 // Porting exynos 9110, code from SM-R765(7270), But not used
425 OMX_ERRORTYPE Exynos_OSAL_SetDataLengthToMetaData(
426     OMX_IN OMX_BYTE             pBuffer,
427     OMX_IN OMX_U32              dataLength,
428     OMX_IN EXYNOS_METADATA_TYPE eMetaDataType)
429 {
430     OMX_ERRORTYPE ret = OMX_ErrorNone;
431
432     FunctionIn();
433
434     if (pBuffer == NULL) {
435         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
436         ret = OMX_ErrorBadParameter;
437         goto EXIT;
438     }
439
440     /* not used yet */
441     /* This is for that MetaData is configured by component */
442
443 EXIT:
444     FunctionOut();
445
446     return ret;
447 }
448
449 OMX_PTR Exynos_OSAL_AllocMetaDataBuffer(
450     OMX_HANDLETYPE          hSharedMemory,
451     EXYNOS_METADATA_TYPE    eMetaDataType,
452     OMX_U32                 nSizeBytes,
453     MEMORY_TYPE             eMemoryType)
454 {
455     OMX_PTR pBuffer = NULL;
456
457     FunctionIn();
458
459     if (eMetaDataType == METADATA_TYPE_DATA) {
460 #ifdef TIZEN_FEATURE_TIZEN_ALLOCATOR
461         pBuffer = Exynos_OSAL_Malloc(sizeof(tbm_surface_h));
462 #else
463         pBuffer = Exynos_OSAL_Malloc(sizeof(MMVideoBuffer));
464 #endif
465         if (pBuffer == NULL) {
466             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate metadata buffer", __FUNCTION__);
467             goto EXIT;
468         }
469     } else {
470         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] not implemented yet(meta type:0x%x)", __FUNCTION__, eMetaDataType);
471     }
472
473 EXIT:
474     FunctionOut();
475
476     return pBuffer;
477 }
478
479 OMX_ERRORTYPE Exynos_OSAL_FreeMetaDataBuffer(
480     OMX_HANDLETYPE          hSharedMemory,
481     EXYNOS_METADATA_TYPE    eMetaDataType,
482     OMX_PTR                 pTempBuffer)
483 {
484     OMX_ERRORTYPE ret = OMX_ErrorNone;
485
486     FunctionIn();
487
488     if (eMetaDataType == METADATA_TYPE_DATA) {
489         Exynos_OSAL_Free(pTempBuffer);
490         ret = OMX_ErrorNone;
491     } else {
492         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] not implemented yet(meta type:0x%x)", __FUNCTION__, eMetaDataType);
493         ret = OMX_ErrorNotImplemented;
494         goto EXIT;
495     }
496 EXIT:
497     FunctionOut();
498
499     return ret;
500 }
501
502 #ifdef __cplusplus
503 }
504 #endif