for callback invoke when resolution is changed
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / openmax / component / common / Exynos_OMX_Baseport.c
1 /*
2  *
3  * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /*
19  * @file       Exynos_OMX_Baseport.c
20  * @brief
21  * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
22  *             HyeYeon Chung (hyeon.chung@samsung.com)
23  * @version    2.0.0
24  * @history
25  *    2012.02.20 : Create
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "Exynos_OMX_Macros.h"
33 #include "Exynos_OSAL_Event.h"
34 #include "Exynos_OSAL_Semaphore.h"
35 #include "Exynos_OSAL_Mutex.h"
36
37 #include "Exynos_OMX_Baseport.h"
38 #include "Exynos_OMX_Basecomponent.h"
39
40 #undef  EXYNOS_LOG_TAG
41 #define EXYNOS_LOG_TAG    "EXYNOS_BASE_PORT"
42 #define EXYNOS_LOG_OFF
43 //#define EXYNOS_TRACE_ON
44 #include "Exynos_OSAL_Log.h"
45
46
47 OMX_ERRORTYPE Exynos_OMX_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader)
48 {
49     OMX_ERRORTYPE             ret = OMX_ErrorNone;
50     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
51     EXYNOS_OMX_BASEPORT      *pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
52     OMX_U32                   i = 0;
53
54     Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
55     for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
56         if (bufferHeader == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
57             pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_FALSE;
58             break;
59         }
60     }
61     Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
62
63     if ((bufferHeader != NULL) && (bufferHeader->pBuffer != NULL))
64     {
65         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d  EmptyBufferDone", __FUNCTION__, __LINE__);
66         pExynosComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader);
67     }
68
69     return ret;
70 }
71
72 OMX_ERRORTYPE Exynos_OMX_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader)
73 {
74     OMX_ERRORTYPE             ret = OMX_ErrorNone;
75     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
76     EXYNOS_OMX_BASEPORT      *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
77     OMX_U32                   i = 0;
78
79     Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
80     for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
81         if (bufferHeader == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
82             pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_FALSE;
83             break;
84         }
85     }
86
87     Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
88
89     if ((bufferHeader != NULL) && (bufferHeader->pBuffer != NULL))
90     {
91         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d  FillBufferDone", __FUNCTION__, __LINE__);
92         pExynosComponent->pCallbacks->FillBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader);
93     }
94
95     return ret;
96 }
97
98 OMX_ERRORTYPE Exynos_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent)
99 {
100     OMX_ERRORTYPE             ret = OMX_ErrorNone;
101     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
102     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
103     OMX_S32                   portIndex = 0;
104     EXYNOS_OMX_DATABUFFER    *flushPortBuffer[2] = {NULL, NULL};
105     OMX_U32                   i = 0, cnt = 0;
106
107     FunctionIn();
108
109     if (pOMXComponent == NULL) {
110         ret = OMX_ErrorBadParameter;
111         goto EXIT;
112     }
113     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
114     if (ret != OMX_ErrorNone) {
115         goto EXIT;
116     }
117
118     if (pOMXComponent->pComponentPrivate == NULL) {
119         ret = OMX_ErrorBadParameter;
120         goto EXIT;
121     }
122     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
123
124     cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1;
125
126 #ifdef TIZEN_FEATURE_E3250
127     Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "bufferFlushProcess cnt:%d port:%d", cnt, nPortIndex);
128 #endif
129
130     for (i = 0; i < cnt; i++) {
131         if (nPortIndex == ALL_PORT_INDEX)
132             portIndex = i;
133         else
134             portIndex = nPortIndex;
135
136         pExynosComponent->exynos_BufferFlush(pOMXComponent, portIndex, bEvent);
137     }
138
139 EXIT:
140     if (ret != OMX_ErrorNone) {
141         Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__);
142
143         if ((pOMXComponent != NULL) && (pExynosComponent != NULL)) {
144             pExynosComponent->pCallbacks->EventHandler(pOMXComponent, pExynosComponent->callbackData, OMX_EventError, ret, 0, NULL);
145         }
146     }
147
148     FunctionOut();
149
150     return ret;
151 }
152
153 OMX_ERRORTYPE Exynos_OMX_EnablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
154 {
155     OMX_ERRORTYPE          ret = OMX_ErrorNone;
156     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
157     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
158     OMX_U32                i = 0, cnt = 0;
159
160     FunctionIn();
161 #ifdef TIZEN_FEATURE_E3250
162     Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "enablePort idx:%d", portIndex);
163 #endif
164
165     pExynosPort = &pExynosComponent->pExynosPort[portIndex];
166
167     if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
168         Exynos_OSAL_SemaphoreWait(pExynosPort->loadedResource);
169         pExynosPort->portDefinition.bPopulated = OMX_TRUE;
170     }
171     pExynosPort->exceptionFlag = GENERAL_STATE;
172     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
173
174     ret = OMX_ErrorNone;
175
176 EXIT:
177     FunctionOut();
178
179     return ret;
180 }
181
182 OMX_ERRORTYPE Exynos_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex)
183 {
184     OMX_ERRORTYPE          ret = OMX_ErrorNone;
185     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
186     OMX_S32                portIndex = 0;
187     OMX_U32                i = 0, cnt = 0;
188
189     FunctionIn();
190
191     if (pOMXComponent == NULL) {
192         ret = OMX_ErrorBadParameter;
193         goto EXIT;
194     }
195     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
196     if (ret != OMX_ErrorNone) {
197         goto EXIT;
198     }
199
200     if (pOMXComponent->pComponentPrivate == NULL) {
201         ret = OMX_ErrorBadParameter;
202         goto EXIT;
203     }
204     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
205
206     cnt = (nPortIndex == ALL_PORT_INDEX) ? ALL_PORT_NUM : 1;
207
208 #ifdef TIZEN_FEATURE_E3250
209     Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "portEnableProcess cnt:%d port:%d", cnt, nPortIndex);
210 #endif
211
212     for (i = 0; i < cnt; i++) {
213         if (nPortIndex == ALL_PORT_INDEX)
214             portIndex = i;
215         else
216             portIndex = nPortIndex;
217
218         ret = Exynos_OMX_EnablePort(pOMXComponent, portIndex);
219         if (ret == OMX_ErrorNone) {
220             pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
221                             pExynosComponent->callbackData,
222                             OMX_EventCmdComplete,
223                             OMX_CommandPortEnable, portIndex, NULL);
224         }
225     }
226
227 EXIT:
228     if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
229             pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
230                             pExynosComponent->callbackData,
231                             OMX_EventError,
232                             ret, 0, NULL);
233         }
234
235     FunctionOut();
236
237     return ret;
238 }
239
240 OMX_ERRORTYPE Exynos_OMX_DisablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
241 {
242     OMX_ERRORTYPE          ret = OMX_ErrorNone;
243     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
244     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
245     OMX_U32                i = 0, elemNum = 0;
246     EXYNOS_OMX_MESSAGE       *message;
247
248     FunctionIn();
249 #ifdef TIZEN_FEATURE_E3250
250     Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "disablePort idx:%d", portIndex);
251 #endif
252
253     pExynosPort = &pExynosComponent->pExynosPort[portIndex];
254
255     if (!CHECK_PORT_ENABLED(pExynosPort)) {
256         ret = OMX_ErrorNone;
257         goto EXIT;
258     }
259
260     if (pExynosComponent->currentState != OMX_StateLoaded) {
261         if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
262             while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
263                 message = (EXYNOS_OMX_MESSAGE*)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
264                 Exynos_OSAL_Free(message);
265             }
266         }
267         pExynosPort->portDefinition.bPopulated = OMX_FALSE;
268         Exynos_OSAL_SemaphoreWait(pExynosPort->unloadedResource);
269     }
270     pExynosPort->portDefinition.bEnabled = OMX_FALSE;
271     ret = OMX_ErrorNone;
272
273 EXIT:
274     FunctionOut();
275
276     return ret;
277 }
278
279 OMX_ERRORTYPE Exynos_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex)
280 {
281     OMX_ERRORTYPE          ret = OMX_ErrorNone;
282     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
283     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
284     OMX_S32                portIndex = 0;
285     OMX_U32                i = 0, cnt = 0;
286     EXYNOS_OMX_DATABUFFER    *flushPortBuffer[2] = {NULL, NULL};
287
288     FunctionIn();
289
290     if (pOMXComponent == NULL) {
291         ret = OMX_ErrorBadParameter;
292         goto EXIT;
293     }
294     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
295     if (ret != OMX_ErrorNone) {
296         goto EXIT;
297     }
298
299     if (pOMXComponent->pComponentPrivate == NULL) {
300         ret = OMX_ErrorBadParameter;
301         goto EXIT;
302     }
303     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
304
305     cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1;
306
307 #ifdef TIZEN_FEATURE_E3250
308     Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "portDisableProcess cnt:%d port:%d", cnt, nPortIndex);
309 #endif
310
311     /* port flush*/
312     for(i = 0; i < cnt; i++) {
313         if (nPortIndex == ALL_PORT_INDEX)
314             portIndex = i;
315         else
316             portIndex = nPortIndex;
317
318         Exynos_OMX_BufferFlushProcess(pOMXComponent, portIndex, OMX_FALSE);
319     }
320
321     for(i = 0; i < cnt; i++) {
322         if (nPortIndex == ALL_PORT_INDEX)
323             portIndex = i;
324         else
325             portIndex = nPortIndex;
326
327         ret = Exynos_OMX_DisablePort(pOMXComponent, portIndex);
328         pExynosComponent->pExynosPort[portIndex].bIsPortDisabled = OMX_FALSE;
329         if (ret == OMX_ErrorNone) {
330             pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
331                             pExynosComponent->callbackData,
332                             OMX_EventCmdComplete,
333                             OMX_CommandPortDisable, portIndex, NULL);
334         }
335     }
336
337 EXIT:
338     if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
339         pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
340                         pExynosComponent->callbackData,
341                         OMX_EventError,
342                         ret, 0, NULL);
343     }
344
345     FunctionOut();
346
347     return ret;
348 }
349
350 OMX_ERRORTYPE Exynos_OMX_EmptyThisBuffer(
351     OMX_IN OMX_HANDLETYPE        hComponent,
352     OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
353 {
354     OMX_ERRORTYPE           ret = OMX_ErrorNone;
355     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
356     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
357     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
358     OMX_BOOL               findBuffer = OMX_FALSE;
359     EXYNOS_OMX_MESSAGE       *message;
360     OMX_U32                i = 0;
361
362     FunctionIn();
363
364     if (hComponent == NULL) {
365         ret = OMX_ErrorBadParameter;
366         goto EXIT;
367     }
368     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
369     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
370     if (ret != OMX_ErrorNone) {
371         goto EXIT;
372     }
373
374     if (pOMXComponent->pComponentPrivate == NULL) {
375         ret = OMX_ErrorBadParameter;
376         goto EXIT;
377     }
378     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
379     if (pExynosComponent->currentState == OMX_StateInvalid) {
380         ret = OMX_ErrorInvalidState;
381         goto EXIT;
382     }
383
384     if (pBuffer == NULL) {
385         ret = OMX_ErrorBadParameter;
386         goto EXIT;
387     }
388     if (pBuffer->nInputPortIndex != INPUT_PORT_INDEX) {
389         ret = OMX_ErrorBadPortIndex;
390         goto EXIT;
391     }
392
393     ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
394     if (ret != OMX_ErrorNone) {
395         goto EXIT;
396     }
397
398     if ((pExynosComponent->currentState != OMX_StateIdle) &&
399         (pExynosComponent->currentState != OMX_StateExecuting) &&
400         (pExynosComponent->currentState != OMX_StatePause)) {
401         ret = OMX_ErrorIncorrectStateOperation;
402         goto EXIT;
403     }
404
405     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
406     if ((!CHECK_PORT_ENABLED(pExynosPort)) ||
407         ((CHECK_PORT_BEING_FLUSHED(pExynosPort) || CHECK_PORT_BEING_DISABLED(pExynosPort)) &&
408         (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) ||
409         ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) &&
410         (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) {
411         ret = OMX_ErrorIncorrectStateOperation;
412         goto EXIT;
413     }
414
415     Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
416     for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
417         if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
418             pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_TRUE;
419             findBuffer = OMX_TRUE;
420             break;
421         }
422     }
423
424     if (findBuffer == OMX_FALSE) {
425         ret = OMX_ErrorBadParameter;
426         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
427         goto EXIT;
428     }
429
430     message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
431     if (message == NULL) {
432         ret = OMX_ErrorInsufficientResources;
433         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
434         goto EXIT;
435     }
436     message->messageType = EXYNOS_OMX_CommandEmptyBuffer;
437     message->messageParam = (OMX_U32) i;
438     message->pCmdData = (OMX_PTR)pBuffer;
439
440     ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message);
441     if (ret != 0) {
442         ret = OMX_ErrorUndefined;
443         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
444         goto EXIT;
445     }
446     ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
447     Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
448
449 EXIT:
450     FunctionOut();
451
452     return ret;
453 }
454
455 OMX_ERRORTYPE Exynos_OMX_FillThisBuffer(
456     OMX_IN OMX_HANDLETYPE        hComponent,
457     OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
458 {
459     OMX_ERRORTYPE           ret = OMX_ErrorNone;
460     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
461     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
462     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
463     OMX_BOOL               findBuffer = OMX_FALSE;
464     EXYNOS_OMX_MESSAGE       *message;
465     OMX_U32                i = 0;
466
467     FunctionIn();
468
469     if (hComponent == NULL) {
470         ret = OMX_ErrorBadParameter;
471         goto EXIT;
472     }
473     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
474     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
475     if (ret != OMX_ErrorNone) {
476         goto EXIT;
477     }
478
479     if (pOMXComponent->pComponentPrivate == NULL) {
480         ret = OMX_ErrorBadParameter;
481         goto EXIT;
482     }
483     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
484     if (pExynosComponent->currentState == OMX_StateInvalid) {
485         ret = OMX_ErrorInvalidState;
486         goto EXIT;
487     }
488
489     if (pBuffer == NULL) {
490         ret = OMX_ErrorBadParameter;
491         goto EXIT;
492     }
493     if (pBuffer->nOutputPortIndex != OUTPUT_PORT_INDEX) {
494         ret = OMX_ErrorBadPortIndex;
495         goto EXIT;
496     }
497
498     ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
499     if (ret != OMX_ErrorNone) {
500         goto EXIT;
501     }
502
503     if ((pExynosComponent->currentState != OMX_StateIdle) &&
504         (pExynosComponent->currentState != OMX_StateExecuting) &&
505         (pExynosComponent->currentState != OMX_StatePause)) {
506         ret = OMX_ErrorIncorrectStateOperation;
507         goto EXIT;
508     }
509
510     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
511     if ((!CHECK_PORT_ENABLED(pExynosPort)) ||
512         ((CHECK_PORT_BEING_FLUSHED(pExynosPort) || CHECK_PORT_BEING_DISABLED(pExynosPort)) &&
513         (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) ||
514         ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) &&
515         (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) {
516         ret = OMX_ErrorIncorrectStateOperation;
517         goto EXIT;
518     }
519
520     Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
521     for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
522         if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
523             pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_TRUE;
524             findBuffer = OMX_TRUE;
525             break;
526         }
527     }
528
529     if (findBuffer == OMX_FALSE) {
530         ret = OMX_ErrorBadParameter;
531         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
532         goto EXIT;
533     }
534
535     message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
536     if (message == NULL) {
537         ret = OMX_ErrorInsufficientResources;
538         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
539         goto EXIT;
540     }
541     message->messageType = EXYNOS_OMX_CommandFillBuffer;
542     message->messageParam = (OMX_U32) i;
543     message->pCmdData = (OMX_PTR)pBuffer;
544
545     ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message);
546     if (ret != 0) {
547         ret = OMX_ErrorUndefined;
548         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
549         goto EXIT;
550     }
551
552     ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
553     Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
554
555 EXIT:
556     FunctionOut();
557
558     return ret;
559 }
560
561 OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent)
562 {
563     OMX_ERRORTYPE          ret = OMX_ErrorNone;
564     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
565     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
566     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
567     EXYNOS_OMX_BASEPORT      *pExynosInputPort = NULL;
568     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = NULL;
569     int i = 0;
570
571     FunctionIn();
572
573     if (hComponent == NULL) {
574         ret = OMX_ErrorBadParameter;
575         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
576         goto EXIT;
577     }
578     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
579     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
580     if (ret != OMX_ErrorNone) {
581         goto EXIT;
582     }
583
584     if (pOMXComponent->pComponentPrivate == NULL) {
585         ret = OMX_ErrorBadParameter;
586         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
587         goto EXIT;
588     }
589     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
590
591     INIT_SET_SIZE_VERSION(&pExynosComponent->portParam, OMX_PORT_PARAM_TYPE);
592     pExynosComponent->portParam.nPorts = ALL_PORT_NUM;
593     pExynosComponent->portParam.nStartPortNumber = INPUT_PORT_INDEX;
594
595     pExynosPort = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM);
596     if (pExynosPort == NULL) {
597         ret = OMX_ErrorInsufficientResources;
598         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
599         goto EXIT;
600     }
601     Exynos_OSAL_Memset(pExynosPort, 0, sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM);
602     pExynosComponent->pExynosPort = pExynosPort;
603
604     /* Input Port */
605     pExynosInputPort = &pExynosPort[INPUT_PORT_INDEX];
606
607     Exynos_OSAL_QueueCreate(&pExynosInputPort->bufferQ, MAX_QUEUE_ELEMENTS);
608
609     pExynosInputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
610     if (pExynosInputPort->extendBufferHeader == NULL) {
611         Exynos_OSAL_Free(pExynosPort);
612         pExynosPort = NULL;
613         ret = OMX_ErrorInsufficientResources;
614         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
615         goto EXIT;
616     }
617     Exynos_OSAL_Memset(pExynosInputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
618
619     pExynosInputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM);
620     if (pExynosInputPort->bufferStateAllocate == NULL) {
621         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
622         pExynosInputPort->extendBufferHeader = NULL;
623         Exynos_OSAL_Free(pExynosPort);
624         pExynosPort = NULL;
625         ret = OMX_ErrorInsufficientResources;
626         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
627         goto EXIT;
628     }
629     Exynos_OSAL_Memset(pExynosInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM);
630
631     pExynosInputPort->bufferSemID = NULL;
632     pExynosInputPort->assignedBufferNum = 0;
633     pExynosInputPort->portState = OMX_StateMax;
634     pExynosInputPort->bIsPortFlushed = OMX_FALSE;
635     pExynosInputPort->bIsPortDisabled = OMX_FALSE;
636     pExynosInputPort->tunneledComponent = NULL;
637     pExynosInputPort->tunneledPort = 0;
638     pExynosInputPort->tunnelBufferNum = 0;
639     pExynosInputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
640     pExynosInputPort->tunnelFlags = 0;
641     ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->loadedResource);
642     if (ret != OMX_ErrorNone) {
643         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
644         pExynosInputPort->bufferStateAllocate = NULL;
645         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
646         pExynosInputPort->extendBufferHeader = NULL;
647         Exynos_OSAL_Free(pExynosPort);
648         pExynosPort = NULL;
649         goto EXIT;
650     }
651     ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->unloadedResource);
652     if (ret != OMX_ErrorNone) {
653         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
654         pExynosInputPort->loadedResource = NULL;
655         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
656         pExynosInputPort->bufferStateAllocate = NULL;
657         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
658         pExynosInputPort->extendBufferHeader = NULL;
659         Exynos_OSAL_Free(pExynosPort);
660         pExynosPort = NULL;
661         goto EXIT;
662     }
663
664     INIT_SET_SIZE_VERSION(&pExynosInputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
665     pExynosInputPort->portDefinition.nPortIndex = INPUT_PORT_INDEX;
666     pExynosInputPort->portDefinition.eDir = OMX_DirInput;
667     pExynosInputPort->portDefinition.nBufferCountActual = 0;
668     pExynosInputPort->portDefinition.nBufferCountMin = 0;
669     pExynosInputPort->portDefinition.nBufferSize = 0;
670     pExynosInputPort->portDefinition.bEnabled = OMX_FALSE;
671     pExynosInputPort->portDefinition.bPopulated = OMX_FALSE;
672     pExynosInputPort->portDefinition.eDomain = OMX_PortDomainMax;
673     pExynosInputPort->portDefinition.bBuffersContiguous = OMX_FALSE;
674     pExynosInputPort->portDefinition.nBufferAlignment = 0;
675     pExynosInputPort->markType.hMarkTargetComponent = NULL;
676     pExynosInputPort->markType.pMarkData = NULL;
677     pExynosInputPort->exceptionFlag = GENERAL_STATE;
678
679     /* Output Port */
680     pExynosOutputPort = &pExynosPort[OUTPUT_PORT_INDEX];
681
682     Exynos_OSAL_QueueCreate(&pExynosOutputPort->bufferQ, MAX_QUEUE_ELEMENTS); /* For in case of "Output Buffer Share", MAX ELEMENTS(DPB + EDPB) */
683
684     pExynosOutputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
685     if (pExynosOutputPort->extendBufferHeader == NULL) {
686         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
687         pExynosInputPort->unloadedResource = NULL;
688         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
689         pExynosInputPort->loadedResource = NULL;
690         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
691         pExynosInputPort->bufferStateAllocate = NULL;
692         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
693         pExynosInputPort->extendBufferHeader = NULL;
694         Exynos_OSAL_Free(pExynosPort);
695         pExynosPort = NULL;
696         ret = OMX_ErrorInsufficientResources;
697         goto EXIT;
698     }
699     Exynos_OSAL_Memset(pExynosOutputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
700
701     pExynosOutputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM);
702     if (pExynosOutputPort->bufferStateAllocate == NULL) {
703         Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader);
704         pExynosOutputPort->extendBufferHeader = NULL;
705
706         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
707         pExynosInputPort->unloadedResource = NULL;
708         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
709         pExynosInputPort->loadedResource = NULL;
710         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
711         pExynosInputPort->bufferStateAllocate = NULL;
712         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
713         pExynosInputPort->extendBufferHeader = NULL;
714         Exynos_OSAL_Free(pExynosPort);
715         pExynosPort = NULL;
716         ret = OMX_ErrorInsufficientResources;
717         goto EXIT;
718     }
719     Exynos_OSAL_Memset(pExynosOutputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM);
720
721     pExynosOutputPort->bufferSemID = NULL;
722     pExynosOutputPort->assignedBufferNum = 0;
723     pExynosOutputPort->portState = OMX_StateMax;
724     pExynosOutputPort->bIsPortFlushed = OMX_FALSE;
725     pExynosOutputPort->bIsPortDisabled = OMX_FALSE;
726     pExynosOutputPort->tunneledComponent = NULL;
727     pExynosOutputPort->tunneledPort = 0;
728     pExynosOutputPort->tunnelBufferNum = 0;
729     pExynosOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
730     pExynosOutputPort->tunnelFlags = 0;
731     ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->loadedResource);
732     if (ret != OMX_ErrorNone) {
733         Exynos_OSAL_Free(pExynosOutputPort->bufferStateAllocate);
734         pExynosOutputPort->bufferStateAllocate = NULL;
735         Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader);
736         pExynosOutputPort->extendBufferHeader = NULL;
737
738         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
739         pExynosInputPort->unloadedResource = NULL;
740         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
741         pExynosInputPort->loadedResource = NULL;
742         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
743         pExynosInputPort->bufferStateAllocate = NULL;
744         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
745         pExynosInputPort->extendBufferHeader = NULL;
746         Exynos_OSAL_Free(pExynosPort);
747         pExynosPort = NULL;
748         goto EXIT;
749     }
750     ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->unloadedResource);
751     if (ret != OMX_ErrorNone) {
752         Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->loadedResource);
753         pExynosOutputPort->loadedResource = NULL;
754         Exynos_OSAL_Free(pExynosOutputPort->bufferStateAllocate);
755         pExynosOutputPort->bufferStateAllocate = NULL;
756         Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader);
757         pExynosOutputPort->extendBufferHeader = NULL;
758
759         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
760         pExynosInputPort->unloadedResource = NULL;
761         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
762         pExynosInputPort->loadedResource = NULL;
763         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
764         pExynosInputPort->bufferStateAllocate = NULL;
765         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
766         pExynosInputPort->extendBufferHeader = NULL;
767         Exynos_OSAL_Free(pExynosPort);
768         pExynosPort = NULL;
769         goto EXIT;
770     }
771
772     INIT_SET_SIZE_VERSION(&pExynosOutputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
773     pExynosOutputPort->portDefinition.nPortIndex = OUTPUT_PORT_INDEX;
774     pExynosOutputPort->portDefinition.eDir = OMX_DirOutput;
775     pExynosOutputPort->portDefinition.nBufferCountActual = 0;
776     pExynosOutputPort->portDefinition.nBufferCountMin = 0;
777     pExynosOutputPort->portDefinition.nBufferSize = 0;
778     pExynosOutputPort->portDefinition.bEnabled = OMX_FALSE;
779     pExynosOutputPort->portDefinition.bPopulated = OMX_FALSE;
780     pExynosOutputPort->portDefinition.eDomain = OMX_PortDomainMax;
781     pExynosOutputPort->portDefinition.bBuffersContiguous = OMX_FALSE;
782     pExynosOutputPort->portDefinition.nBufferAlignment = 0;
783     pExynosOutputPort->markType.hMarkTargetComponent = NULL;
784     pExynosOutputPort->markType.pMarkData = NULL;
785     pExynosOutputPort->exceptionFlag = GENERAL_STATE;
786
787     pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
788     pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
789     pExynosComponent->checkTimeStamp.startTimeStamp = 0;
790     pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
791
792     pOMXComponent->EmptyThisBuffer = &Exynos_OMX_EmptyThisBuffer;
793     pOMXComponent->FillThisBuffer  = &Exynos_OMX_FillThisBuffer;
794
795     ret = OMX_ErrorNone;
796 EXIT:
797     FunctionOut();
798
799     return ret;
800 }
801
802 OMX_ERRORTYPE Exynos_OMX_Port_Destructor(OMX_HANDLETYPE hComponent)
803 {
804     OMX_ERRORTYPE          ret = OMX_ErrorNone;
805     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
806     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
807     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
808
809     FunctionIn();
810
811     int i = 0;
812
813     if (hComponent == NULL) {
814         ret = OMX_ErrorBadParameter;
815         goto EXIT;
816     }
817     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
818     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
819     if (ret != OMX_ErrorNone) {
820         goto EXIT;
821     }
822     if (pOMXComponent->pComponentPrivate == NULL) {
823         ret = OMX_ErrorBadParameter;
824         goto EXIT;
825     }
826     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
827     for (i = 0; i < ALL_PORT_NUM; i++) {
828         pExynosPort = &pExynosComponent->pExynosPort[i];
829
830         Exynos_OSAL_SemaphoreTerminate(pExynosPort->loadedResource);
831         pExynosPort->loadedResource = NULL;
832         Exynos_OSAL_SemaphoreTerminate(pExynosPort->unloadedResource);
833         pExynosPort->unloadedResource = NULL;
834         Exynos_OSAL_Free(pExynosPort->bufferStateAllocate);
835         pExynosPort->bufferStateAllocate = NULL;
836         Exynos_OSAL_Free(pExynosPort->extendBufferHeader);
837         pExynosPort->extendBufferHeader = NULL;
838
839         Exynos_OSAL_QueueTerminate(&pExynosPort->bufferQ);
840     }
841     Exynos_OSAL_Free(pExynosComponent->pExynosPort);
842     pExynosComponent->pExynosPort = NULL;
843     ret = OMX_ErrorNone;
844 EXIT:
845     FunctionOut();
846
847     return ret;
848 }
849
850 OMX_ERRORTYPE Exynos_ResetDataBuffer(EXYNOS_OMX_DATABUFFER *pDataBuffer)
851 {
852     OMX_ERRORTYPE ret = OMX_ErrorNone;
853
854     if (pDataBuffer == NULL) {
855         ret = OMX_ErrorBadParameter;
856         goto EXIT;
857     }
858
859     pDataBuffer->dataValid     = OMX_FALSE;
860     pDataBuffer->dataLen       = 0;
861     pDataBuffer->remainDataLen = 0;
862     pDataBuffer->usedDataLen   = 0;
863     pDataBuffer->bufferHeader  = NULL;
864     pDataBuffer->nFlags        = 0;
865     pDataBuffer->timeStamp     = 0;
866     pDataBuffer->pPrivate      = NULL;
867
868 EXIT:
869     return ret;
870 }
871
872 OMX_ERRORTYPE Exynos_ResetCodecData(EXYNOS_OMX_DATA *pData)
873 {
874     OMX_ERRORTYPE ret = OMX_ErrorNone;
875
876     if (pData == NULL) {
877         ret = OMX_ErrorBadParameter;
878         goto EXIT;
879     }
880
881     pData->dataLen       = 0;
882     pData->usedDataLen   = 0;
883     pData->remainDataLen = 0;
884     pData->nFlags        = 0;
885     pData->timeStamp     = 0;
886     pData->pPrivate      = NULL;
887     pData->bufferHeader  = NULL;
888
889 EXIT:
890     return ret;
891 }
892
893 OMX_ERRORTYPE Exynos_Shared_BufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_PLANE nPlane)
894 {
895     OMX_ERRORTYPE ret = OMX_ErrorNone;
896
897     if (nPlane == ONE_PLANE) {
898         /* Case of Shared Buffer, Only support singlePlaneBuffer */
899         pData->buffer.singlePlaneBuffer.dataBuffer = pUseBuffer->bufferHeader->pBuffer;
900     } else {
901         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not support plane");
902         ret = OMX_ErrorNotImplemented;
903         goto EXIT;
904     }
905
906     pData->allocSize     = pUseBuffer->allocSize;
907     pData->dataLen       = pUseBuffer->dataLen;
908     pData->usedDataLen   = pUseBuffer->usedDataLen;
909     pData->remainDataLen = pUseBuffer->remainDataLen;
910     pData->timeStamp     = pUseBuffer->timeStamp;
911     pData->nFlags        = pUseBuffer->nFlags;
912     pData->pPrivate      = pUseBuffer->pPrivate;
913     pData->bufferHeader  = pUseBuffer->bufferHeader;
914
915 EXIT:
916     return ret;
917 }
918
919 OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer)
920 {
921     OMX_ERRORTYPE ret = OMX_ErrorNone;
922
923     pUseBuffer->bufferHeader          = pData->bufferHeader;
924     pUseBuffer->allocSize             = pData->allocSize;
925     pUseBuffer->dataLen               = pData->dataLen;
926     pUseBuffer->usedDataLen           = pData->usedDataLen;
927     pUseBuffer->remainDataLen         = pData->remainDataLen;
928     pUseBuffer->timeStamp             = pData->timeStamp;
929     pUseBuffer->nFlags                = pData->nFlags;
930     pUseBuffer->pPrivate              = pData->pPrivate;
931
932     return ret;
933 }