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