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