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