OpenMAX Bellagio 0.9.3
omx_base_port.c
Go to the documentation of this file.
1
26#include <string.h>
27#include <unistd.h>
28#include <omxcore.h>
29#include <OMX_Core.h>
30#include <OMX_Component.h>
31
32#include "omx_base_component.h"
33#include "omx_base_port.h"
34
36#define DEFAULT_NUMBER_BUFFERS_PER_PORT 2
38#define DEFAULT_MIN_NUMBER_BUFFERS_PER_PORT 2
55OMX_ERRORTYPE base_port_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,omx_base_PortType **openmaxStandPort,OMX_U32 nPortIndex, OMX_BOOL isInput) {
56
57 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for component %p\n", __func__, openmaxStandComp);
58
59 // create ports, but only if the subclass hasn't done it
60 if (!(*openmaxStandPort)) {
61 *openmaxStandPort = calloc(1,sizeof (omx_base_PortType));
62 }
63
64 if (!(*openmaxStandPort)) {
65 DEBUG(DEB_LEV_ERR, "Out of %s for component %p for a lack of resources\n", __func__, openmaxStandComp);
67 }
68
69 (*openmaxStandPort)->hTunneledComponent = NULL;
70 (*openmaxStandPort)->nTunnelFlags=0;
71 (*openmaxStandPort)->nTunneledPort=0;
72 (*openmaxStandPort)->eBufferSupplier=OMX_BufferSupplyUnspecified;
73 (*openmaxStandPort)->nNumTunnelBuffer=0;
74
75 if((*openmaxStandPort)->pAllocSem==NULL) {
76 (*openmaxStandPort)->pAllocSem = calloc(1,sizeof(tsem_t));
77 if((*openmaxStandPort)->pAllocSem==NULL) {
79 }
80 tsem_init((*openmaxStandPort)->pAllocSem, 0);
81 }
82 (*openmaxStandPort)->nNumBufferFlushed=0;
83 (*openmaxStandPort)->bIsPortFlushed=OMX_FALSE;
85 if(!(*openmaxStandPort)->pBufferQueue) {
86 (*openmaxStandPort)->pBufferQueue = calloc(1,sizeof(queue_t));
87 if((*openmaxStandPort)->pBufferQueue==NULL) return OMX_ErrorInsufficientResources;
88 queue_init((*openmaxStandPort)->pBufferQueue);
89 }
90 /*Allocate and initialise port semaphores*/
91 if(!(*openmaxStandPort)->pBufferSem) {
92 (*openmaxStandPort)->pBufferSem = calloc(1,sizeof(tsem_t));
93 if((*openmaxStandPort)->pBufferSem==NULL) return OMX_ErrorInsufficientResources;
94 tsem_init((*openmaxStandPort)->pBufferSem, 0);
95 }
96
97 (*openmaxStandPort)->nNumAssignedBuffers=0;
98 setHeader(&(*openmaxStandPort)->sPortParam, sizeof (OMX_PARAM_PORTDEFINITIONTYPE));
99 (*openmaxStandPort)->sPortParam.nPortIndex = nPortIndex;
100 (*openmaxStandPort)->sPortParam.nBufferCountActual = DEFAULT_NUMBER_BUFFERS_PER_PORT;
101 (*openmaxStandPort)->sPortParam.nBufferCountMin = DEFAULT_MIN_NUMBER_BUFFERS_PER_PORT;
102 (*openmaxStandPort)->sPortParam.bEnabled = OMX_TRUE;
103 (*openmaxStandPort)->sPortParam.bPopulated = OMX_FALSE;
104 (*openmaxStandPort)->sPortParam.eDir = (isInput == OMX_TRUE)?OMX_DirInput:OMX_DirOutput;
105
106 (*openmaxStandPort)->standCompContainer=openmaxStandComp;
107 (*openmaxStandPort)->bIsTransientToEnabled=OMX_FALSE;
108 (*openmaxStandPort)->bIsTransientToDisabled=OMX_FALSE;
109 (*openmaxStandPort)->bIsFullOfBuffers=OMX_FALSE;
110 (*openmaxStandPort)->bIsEmptyOfBuffers=OMX_FALSE;
111 (*openmaxStandPort)->bBufferStateAllocated = NULL;
112 (*openmaxStandPort)->pInternalBufferStorage = NULL;
113
114 (*openmaxStandPort)->PortDestructor = &base_port_Destructor;
115 (*openmaxStandPort)->Port_AllocateBuffer = &base_port_AllocateBuffer;
116 (*openmaxStandPort)->Port_UseBuffer = &base_port_UseBuffer;
117 (*openmaxStandPort)->Port_FreeBuffer = &base_port_FreeBuffer;
118 (*openmaxStandPort)->Port_DisablePort = &base_port_DisablePort;
119 (*openmaxStandPort)->Port_EnablePort = &base_port_EnablePort;
120 (*openmaxStandPort)->Port_SendBufferFunction = &base_port_SendBufferFunction;
121 (*openmaxStandPort)->FlushProcessingBuffers = &base_port_FlushProcessingBuffers;
122 (*openmaxStandPort)->ReturnBufferFunction = &base_port_ReturnBufferFunction;
123 (*openmaxStandPort)->ComponentTunnelRequest = &base_port_ComponentTunnelRequest;
124 (*openmaxStandPort)->Port_AllocateTunnelBuffer = &base_port_AllocateTunnelBuffer;
125 (*openmaxStandPort)->Port_FreeTunnelBuffer = &base_port_FreeTunnelBuffer;
126 (*openmaxStandPort)->bIsDestroying = OMX_FALSE;
127 pthread_mutex_init(&((*openmaxStandPort)->exitMutex), NULL);
128
129
130 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for component %p\n", __func__, openmaxStandComp);
131 return OMX_ErrorNone;
132}
133
135 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort);
136
137 if(openmaxStandPort->pAllocSem) {
138 pthread_mutex_lock(&openmaxStandPort->exitMutex);
139 openmaxStandPort->bIsDestroying = OMX_TRUE;
140 pthread_mutex_unlock(&openmaxStandPort->exitMutex);
147 tsem_deinit(openmaxStandPort->pAllocSem);
148 free(openmaxStandPort->pAllocSem);
149 openmaxStandPort->pAllocSem=NULL;
150 }
152 if(openmaxStandPort->pBufferQueue) {
153 queue_deinit(openmaxStandPort->pBufferQueue);
154 free(openmaxStandPort->pBufferQueue);
155 openmaxStandPort->pBufferQueue=NULL;
156 }
157 /*Allocate and initialize port semaphores*/
158 if(openmaxStandPort->pBufferSem) {
159 tsem_deinit(openmaxStandPort->pBufferSem);
160 free(openmaxStandPort->pBufferSem);
161 openmaxStandPort->pBufferSem=NULL;
162 }
163
164 pthread_mutex_destroy(&openmaxStandPort->exitMutex);
165
166 free(openmaxStandPort);
167 openmaxStandPort = NULL;
168 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort);
169 return OMX_ErrorNone;
170}
171
177 omx_base_component_PrivateType* omx_base_component_Private;
178 OMX_BUFFERHEADERTYPE* pBuffer;
179 int errQue;
180
181 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort);
182 omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate;
183
184 if(openmaxStandPort->sPortParam.eDomain!=OMX_PortDomainOther) { /* clock buffers not used in the clients buffer managment function */
185 pthread_mutex_lock(&omx_base_component_Private->flush_mutex);
186 openmaxStandPort->bIsPortFlushed=OMX_TRUE;
187 /*Signal the buffer management thread of port flush,if it is waiting for buffers*/
188 if(omx_base_component_Private->bMgmtSem->semval==0) {
189 tsem_up(omx_base_component_Private->bMgmtSem);
190 }
191
192 if(omx_base_component_Private->state != OMX_StateExecuting ) {
193 /*Waiting at paused state*/
194 tsem_signal(omx_base_component_Private->bStateSem);
195 }
196 DEBUG(DEB_LEV_FULL_SEQ, "In %s waiting for flush all condition port index =%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);
197 /* Wait until flush is completed */
198 pthread_mutex_unlock(&omx_base_component_Private->flush_mutex);
199 tsem_down(omx_base_component_Private->flush_all_condition);
200 }
201DEBUG(DEB_LEV_FUNCTION_NAME, "In %s flushed all the buffers under processing\n", __func__);
202
203 tsem_reset(omx_base_component_Private->bMgmtSem);
204
205 /* Flush all the buffers not under processing */
206 while (openmaxStandPort->pBufferSem->semval > 0) {
207 DEBUG(DEB_LEV_FULL_SEQ, "In %s TFlag=%x Flusing Port=%d,Semval=%d Qelem=%d\n",
208 __func__,(int)openmaxStandPort->nTunnelFlags,(int)openmaxStandPort->sPortParam.nPortIndex,
209 (int)openmaxStandPort->pBufferSem->semval,(int)openmaxStandPort->pBufferQueue->nelem);
210
211 tsem_down(openmaxStandPort->pBufferSem);
212 pBuffer = dequeue(openmaxStandPort->pBufferQueue);
213 if (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
214 DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s is returning io:%d buffer\n",
215 __func__,omx_base_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex);
216 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
217 ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
218 } else {
219 ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
220 }
221 } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
222 errQue = queue(openmaxStandPort->pBufferQueue,pBuffer);
223 if (errQue) {
224 /* /TODO the queue is full. This can be handled in a fine way with
225 * some retrials, or other checking. For the moment this is a critical error
226 * and simply causes the failure of this call
227 */
229 }
230 } else {
231 (*(openmaxStandPort->BufferProcessedCallback))(
232 openmaxStandPort->standCompContainer,
233 omx_base_component_Private->callbackData,
234 pBuffer);
235 }
236 }
237 /*Port is tunneled and supplier and didn't received all it's buffer then wait for the buffers*/
238 if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
239 while(openmaxStandPort->pBufferQueue->nelem!= openmaxStandPort->nNumAssignedBuffers){
240 tsem_down(openmaxStandPort->pBufferSem);
241 DEBUG(DEB_LEV_PARAMS, "In %s Got a buffer qelem=%d\n",__func__,openmaxStandPort->pBufferQueue->nelem);
242 }
243 tsem_reset(openmaxStandPort->pBufferSem);
244 }
245
246 pthread_mutex_lock(&omx_base_component_Private->flush_mutex);
247 openmaxStandPort->bIsPortFlushed=OMX_FALSE;
248 pthread_mutex_unlock(&omx_base_component_Private->flush_mutex);
249
250 tsem_up(omx_base_component_Private->flush_condition);
251
252 DEBUG(DEB_LEV_FULL_SEQ, "Out %s Port Index=%d bIsPortFlushed=%d Component %s\n", __func__,
253 (int)openmaxStandPort->sPortParam.nPortIndex,(int)openmaxStandPort->bIsPortFlushed,omx_base_component_Private->name);
254
255 DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__,
256 (int)openmaxStandPort->nTunnelFlags,
257 (int)openmaxStandPort->pBufferQueue->nelem,
258 (int)openmaxStandPort->pBufferSem->semval,
259 (int)omx_base_component_Private->bMgmtSem->semval,
260 omx_base_component_Private->name);
261
262 DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port %p Index=%d\n", __func__, openmaxStandPort, (int)openmaxStandPort->sPortParam.nPortIndex);
263 return OMX_ErrorNone;
264}
265
274 omx_base_component_PrivateType* omx_base_component_Private;
276
277 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s Port %p Index=%d\n", __func__, openmaxStandPort, (int)openmaxStandPort->sPortParam.nPortIndex);
278 omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate;
279 if (! PORT_IS_ENABLED(openmaxStandPort)) {
280 return OMX_ErrorNone;
281 }
282
283 if(omx_base_component_Private->state!=OMX_StateLoaded) {
284 if(!PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
285 /*Signal Buffer Mgmt Thread if it's holding any buffer*/
286 if(omx_base_component_Private->bMgmtSem->semval==0) {
287 tsem_up(omx_base_component_Private->bMgmtSem);
288 }
289 /*Wait till all buffers are freed*/
290 tsem_down(openmaxStandPort->pAllocSem);
291 tsem_reset(omx_base_component_Private->bMgmtSem);
292 } else {
293 /*Since port is being disabled then remove buffers from the queue*/
294 while(openmaxStandPort->pBufferQueue->nelem > 0) {
295 dequeue(openmaxStandPort->pBufferQueue);
296 }
297
298 err = openmaxStandPort->Port_FreeTunnelBuffer(openmaxStandPort,openmaxStandPort->sPortParam.nPortIndex);
299 if(err!=OMX_ErrorNone) {
300 DEBUG(DEB_LEV_ERR, "In %s Freeing Tunnel Buffer Error=%x\n",__func__,err);
301 }
302 DEBUG(DEB_LEV_PARAMS, "In %s Qelem=%d\n", __func__,openmaxStandPort->pBufferQueue->nelem);
303 }
304 }
305
306 DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__,
307 (int)openmaxStandPort->nTunnelFlags,
308 (int)openmaxStandPort->pBufferQueue->nelem,
309 (int)openmaxStandPort->pBufferSem->semval,
310 (int)omx_base_component_Private->bMgmtSem->semval,
311 omx_base_component_Private->name);
312 openmaxStandPort->bIsTransientToDisabled = OMX_FALSE;
313 openmaxStandPort->sPortParam.bEnabled = OMX_FALSE;
314 DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port Index=%d isEnabled=%d\n", __func__,
315 (int)openmaxStandPort->sPortParam.nPortIndex,
316 (int)openmaxStandPort->sPortParam.bEnabled);
317 return err;
318}
319
328 omx_base_component_PrivateType* omx_base_component_Private;
330 OMX_U32 i;
331
332 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort);
333 if (PORT_IS_ENABLED(openmaxStandPort)) {
334 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort);
335 return OMX_ErrorNone;
336 }
337 omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate;
338
339 openmaxStandPort->sPortParam.bEnabled = OMX_TRUE;
340
341 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s port T flag=%x popu=%d state=%x\n", __func__,
342 (int)openmaxStandPort->nTunnelFlags,
343 (int)openmaxStandPort->sPortParam.bPopulated,
344 (int)omx_base_component_Private->state);
345
346
347 if (!PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
348 /*Wait Till All buffers are allocated if the component state is not Loaded*/
349 if (omx_base_component_Private->state!=OMX_StateLoaded && omx_base_component_Private->state!=OMX_StateWaitForResources) {
350 tsem_down(openmaxStandPort->pAllocSem);
351 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
352 }
353 } else { //Port Tunneled and supplier. Then allocate tunnel buffers
354 err= openmaxStandPort->Port_AllocateTunnelBuffer(openmaxStandPort, openmaxStandPort->sPortParam.nPortIndex);
355 if(err!=OMX_ErrorNone) {
356 DEBUG(DEB_LEV_ERR, "In %s Allocating Tunnel Buffer Error=%x\n",__func__,err);
357 return err;
358 }
359 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
360 if (omx_base_component_Private->state==OMX_StateExecuting) {
361 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual;i++) {
362 tsem_up(openmaxStandPort->pBufferSem);
363 tsem_up(omx_base_component_Private->bMgmtSem);
364 }
365 }
366 DEBUG(DEB_LEV_PARAMS, "In %s Qelem=%d BSem=%d\n", __func__,openmaxStandPort->pBufferQueue->nelem,openmaxStandPort->pBufferSem->semval);
367 }
368
369 openmaxStandPort->bIsTransientToEnabled = OMX_FALSE;
370
371 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort);
372 return OMX_ErrorNone;
373}
374
384 omx_base_PortType *openmaxStandPort,
385 OMX_BUFFERHEADERTYPE** pBuffer,
386 OMX_U32 nPortIndex,
387 OMX_PTR pAppPrivate,
388 OMX_U32 nSizeBytes) {
389
390 unsigned int i;
391 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
392 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
393 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort);
394
395 if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
397 }
398 if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
400 }
401
402 if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) {
403 if (!openmaxStandPort->bIsTransientToEnabled) {
404 DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__);
406 }
407 }
408
409 if(nSizeBytes < openmaxStandPort->sPortParam.nBufferSize) {
410 DEBUG(DEB_LEV_ERR, "In %s: Requested Buffer Size %lu is less than Minimum Buffer Size %lu\n", __func__, nSizeBytes, openmaxStandPort->sPortParam.nBufferSize);
412 }
413
414 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
415 if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) {
416 openmaxStandPort->pInternalBufferStorage[i] = calloc(1,sizeof(OMX_BUFFERHEADERTYPE));
417 if (!openmaxStandPort->pInternalBufferStorage[i]) {
419 }
420 setHeader(openmaxStandPort->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE));
421 /* allocate the buffer */
422 openmaxStandPort->pInternalBufferStorage[i]->pBuffer = calloc(1,nSizeBytes);
423 if(openmaxStandPort->pInternalBufferStorage[i]->pBuffer==NULL) {
425 }
426 openmaxStandPort->pInternalBufferStorage[i]->nAllocLen = nSizeBytes;
427 openmaxStandPort->pInternalBufferStorage[i]->pPlatformPrivate = openmaxStandPort;
428 openmaxStandPort->pInternalBufferStorage[i]->pAppPrivate = pAppPrivate;
429 *pBuffer = openmaxStandPort->pInternalBufferStorage[i];
430 openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ALLOCATED;
431 openmaxStandPort->bBufferStateAllocated[i] |= HEADER_ALLOCATED;
432 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
433 openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
434 } else {
435 openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
436 }
437 openmaxStandPort->nNumAssignedBuffers++;
438 DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
439
440 if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) {
441 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
442 openmaxStandPort->bIsFullOfBuffers = OMX_TRUE;
443 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n",__func__,(int)nPortIndex);
444 tsem_up(openmaxStandPort->pAllocSem);
445 }
446 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort);
447 return OMX_ErrorNone;
448 }
449 }
450 DEBUG(DEB_LEV_ERR, "Out of %s for port %p. Error: no available buffers\n",__func__, openmaxStandPort);
452}
453
463 omx_base_PortType *openmaxStandPort,
464 OMX_BUFFERHEADERTYPE** ppBufferHdr,
465 OMX_U32 nPortIndex,
466 OMX_PTR pAppPrivate,
467 OMX_U32 nSizeBytes,
468 OMX_U8* pBuffer) {
469
470 unsigned int i;
471 OMX_BUFFERHEADERTYPE* returnBufferHeader;
472 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
473 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
474 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort);
475 if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
477 }
478 if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
480 }
481
482 if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) {
483 if (!openmaxStandPort->bIsTransientToEnabled) {
484 DEBUG(DEB_LEV_ERR, "In %s: The port of Comp %s is not allowed to receive buffers\n", __func__,omx_base_component_Private->name);
486 }
487 }
488
489 if(nSizeBytes < openmaxStandPort->sPortParam.nBufferSize) {
490 DEBUG(DEB_LEV_ERR, "In %s: Port %d Given Buffer Size %u is less than Minimum Buffer Size %u\n", __func__, (int)nPortIndex, (int)nSizeBytes, (int)openmaxStandPort->sPortParam.nBufferSize);
492 }
493
494 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
495 if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) {
496 openmaxStandPort->pInternalBufferStorage[i] = calloc(1,sizeof(OMX_BUFFERHEADERTYPE));
497 if (!openmaxStandPort->pInternalBufferStorage[i]) {
499 }
500 openmaxStandPort->bIsEmptyOfBuffers = OMX_FALSE;
501 setHeader(openmaxStandPort->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE));
502
503 openmaxStandPort->pInternalBufferStorage[i]->pBuffer = pBuffer;
504 openmaxStandPort->pInternalBufferStorage[i]->nAllocLen = nSizeBytes;
505 openmaxStandPort->pInternalBufferStorage[i]->pPlatformPrivate = openmaxStandPort;
506 openmaxStandPort->pInternalBufferStorage[i]->pAppPrivate = pAppPrivate;
507 openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ASSIGNED;
508 openmaxStandPort->bBufferStateAllocated[i] |= HEADER_ALLOCATED;
509 returnBufferHeader = calloc(1,sizeof(OMX_BUFFERHEADERTYPE));
510 if (!returnBufferHeader) {
512 }
513 setHeader(returnBufferHeader, sizeof(OMX_BUFFERHEADERTYPE));
514 returnBufferHeader->pBuffer = pBuffer;
515 returnBufferHeader->nAllocLen = nSizeBytes;
516 returnBufferHeader->pPlatformPrivate = openmaxStandPort;
517 returnBufferHeader->pAppPrivate = pAppPrivate;
518 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
519 openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
520 returnBufferHeader->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
521 } else {
522 openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
523 returnBufferHeader->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
524 }
525 *ppBufferHdr = returnBufferHeader;
526 openmaxStandPort->nNumAssignedBuffers++;
527 DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
528
529 if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) {
530 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
531 openmaxStandPort->bIsFullOfBuffers = OMX_TRUE;
532 tsem_up(openmaxStandPort->pAllocSem);
533 }
534 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort);
535 return OMX_ErrorNone;
536 }
537 }
538 DEBUG(DEB_LEV_ERR, "In %s Error: no available buffers CompName=%s\n",__func__,omx_base_component_Private->name);
540}
541
548 omx_base_PortType *openmaxStandPort,
549 OMX_U32 nPortIndex,
550 OMX_BUFFERHEADERTYPE* pBuffer) {
551
552 unsigned int i;
553 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
554 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
555 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort);
556
557 if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
559 }
560 if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
562 }
563
564 if (omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) {
565 if (!openmaxStandPort->bIsTransientToDisabled) {
566 DEBUG(DEB_LEV_FULL_SEQ, "In %s: The port is not allowed to free the buffers\n", __func__);
567 (*(omx_base_component_Private->callbacks->EventHandler))
568 (omxComponent,
569 omx_base_component_Private->callbackData,
570 OMX_EventError, /* The command was completed */
571 OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */
572 nPortIndex, /* The state has been changed in message->messageParam2 */
573 NULL);
574 }
575 }
576
577 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
578 if (openmaxStandPort->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) {
579
580 openmaxStandPort->bIsFullOfBuffers = OMX_FALSE;
581 if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ALLOCATED) {
582 if(openmaxStandPort->pInternalBufferStorage[i]->pBuffer){
583 DEBUG(DEB_LEV_PARAMS, "In %s freeing %i pBuffer=%p\n",__func__, (int)i, openmaxStandPort->pInternalBufferStorage[i]->pBuffer);
584 free(openmaxStandPort->pInternalBufferStorage[i]->pBuffer);
585 openmaxStandPort->pInternalBufferStorage[i]->pBuffer=NULL;
586 }
587 } else if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ASSIGNED) {
588 free(pBuffer);
589 }
590 if(openmaxStandPort->bBufferStateAllocated[i] & HEADER_ALLOCATED) {
591 free(openmaxStandPort->pInternalBufferStorage[i]);
592 openmaxStandPort->pInternalBufferStorage[i]=NULL;
593 }
594
595 openmaxStandPort->bBufferStateAllocated[i] = BUFFER_FREE;
596
597 openmaxStandPort->nNumAssignedBuffers--;
598 DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
599
600 if (openmaxStandPort->nNumAssignedBuffers == 0) {
601 openmaxStandPort->sPortParam.bPopulated = OMX_FALSE;
602 openmaxStandPort->bIsEmptyOfBuffers = OMX_TRUE;
603 tsem_up(openmaxStandPort->pAllocSem);
604 }
605 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort);
606 return OMX_ErrorNone;
607 }
608 }
609 DEBUG(DEB_LEV_ERR, "Out of %s for port %p with OMX_ErrorInsufficientResources\n", __func__, openmaxStandPort);
611}
612
614 omx_base_PortType *openmaxStandPort,
615 OMX_U32 nPortIndex)
616{
617 unsigned int i;
618 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
619 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
620 OMX_U8* pBuffer=NULL;
622 int errQue;
623 OMX_U32 numRetry=0,nBufferSize;
625 OMX_U32 nLocalBufferCountActual;
626
627 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort);
628
629 if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
630 DEBUG(DEB_LEV_ERR, "In %s: Bad Port Index\n", __func__);
632 }
633 if (! PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
634 DEBUG(DEB_LEV_ERR, "In %s: Port is not tunneled Flag=%x\n", __func__, (int)openmaxStandPort->nTunnelFlags);
636 }
637
638 if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) {
639 if (!openmaxStandPort->bIsTransientToEnabled) {
640 DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__);
642 }
643 }
644 /*Get nBufferSize of the peer port and allocate which one is bigger*/
645 nBufferSize = openmaxStandPort->sPortParam.nBufferSize;
646 setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
647 sPortDef.nPortIndex = openmaxStandPort->nTunneledPort;
649 if(err == OMX_ErrorNone) {
650 nBufferSize = (sPortDef.nBufferSize > openmaxStandPort->sPortParam.nBufferSize) ? sPortDef.nBufferSize: openmaxStandPort->sPortParam.nBufferSize;
651 } else {
653 }
654 /* set the number of buffer needed getting the max nBufferCountActual of the two components
655 * On the one with the minor nBufferCountActual a setParam should be called to normalize the value,
656 * if possible.
657 */
658 nLocalBufferCountActual = openmaxStandPort->sPortParam.nBufferCountActual;
659 if (nLocalBufferCountActual < sPortDef.nBufferCountActual) {
660 nLocalBufferCountActual = sPortDef.nBufferCountActual;
661 openmaxStandPort->sPortParam.nBufferCountActual = nLocalBufferCountActual;
662 } else if (sPortDef.nBufferCountActual < nLocalBufferCountActual){
663 sPortDef.nBufferCountActual = nLocalBufferCountActual;
665 if(err != OMX_ErrorNone) {
666 /* for some reasons undetected during negotiation the tunnel cannot be established.
667 */
669 }
670 }
671 if (openmaxStandPort->sPortParam.nBufferCountActual == 0) {
672 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
673 openmaxStandPort->bIsFullOfBuffers = OMX_TRUE;
674 DEBUG(DEB_LEV_ERR, "In %s Allocated nothing\n",__func__);
675 return OMX_ErrorNone;
676 }
677 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
678 if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) {
679 pBuffer = calloc(1,nBufferSize);
680 if(pBuffer==NULL) {
682 }
683 /*Retry more than once, if the tunneled component is not in Loaded->Idle State*/
684 while(numRetry <TUNNEL_USE_BUFFER_RETRY) {
685 eError=OMX_UseBuffer(openmaxStandPort->hTunneledComponent,&openmaxStandPort->pInternalBufferStorage[i],
686 openmaxStandPort->nTunneledPort,NULL,nBufferSize,pBuffer);
687 if(eError!=OMX_ErrorNone) {
688 DEBUG(DEB_LEV_FULL_SEQ,"Tunneled Component Couldn't Use buffer %i From Comp=%s Retry=%d\n",
689 i,omx_base_component_Private->name,(int)numRetry);
690
692 DEBUG(DEB_LEV_FULL_SEQ,"Waiting for next try %i \n",(int)numRetry);
694 numRetry++;
695 continue;
696 }
697 free(pBuffer);
698 pBuffer = NULL;
699 return eError;
700 }
701 else {
702 if(openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
703 openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
704 openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->nTunneledPort;
705 } else {
706 openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->nTunneledPort;
707 openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
708 }
709 break;
710 }
711 }
712 if(eError!=OMX_ErrorNone) {
713 free(pBuffer);
714 pBuffer = NULL;
715 DEBUG(DEB_LEV_ERR,"In %s Tunneled Component Couldn't Use Buffer err = %x \n",__func__,(int)eError);
716 return eError;
717 }
718 openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ALLOCATED;
719 openmaxStandPort->nNumAssignedBuffers++;
720 DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
721
722 if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) {
723 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
724 openmaxStandPort->bIsFullOfBuffers = OMX_TRUE;
725 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n",__func__, (int)nPortIndex);
726 }
727 errQue = queue(openmaxStandPort->pBufferQueue, openmaxStandPort->pInternalBufferStorage[i]);
728 if (errQue) {
729 /* /TODO the queue is full. This can be handled in a fine way with
730 * some retrials, or other checking. For the moment this is a critical error
731 * and simply causes the failure of this call
732 */
734 }
735 }
736 }
737 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p. Allocated all the buffers\n", __func__, openmaxStandPort);
738 return OMX_ErrorNone;
739}
740
742{
743 unsigned int i;
744 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
745 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
747 OMX_U32 numRetry=0;
748 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort);
749
750 if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
751 DEBUG(DEB_LEV_ERR, "In %s: Bad Port Index\n", __func__);
753 }
754 if (! PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
755 DEBUG(DEB_LEV_ERR, "In %s: Port is not tunneled\n", __func__);
757 }
758
759 if (omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) {
760 if (!openmaxStandPort->bIsTransientToDisabled) {
761 DEBUG(DEB_LEV_FULL_SEQ, "In %s: The port is not allowed to free the buffers\n", __func__);
762 (*(omx_base_component_Private->callbacks->EventHandler))
763 (omxComponent,
764 omx_base_component_Private->callbackData,
765 OMX_EventError, /* The command was completed */
766 OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */
767 nPortIndex, /* The state has been changed in message->messageParam2 */
768 NULL);
769 }
770 }
771
772 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
773 if (openmaxStandPort->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) {
774
775 openmaxStandPort->bIsFullOfBuffers = OMX_FALSE;
776 if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ALLOCATED) {
777 free(openmaxStandPort->pInternalBufferStorage[i]->pBuffer);
778 openmaxStandPort->pInternalBufferStorage[i]->pBuffer = NULL;
779 }
780 /*Retry more than once, if the tunneled component is not in Idle->Loaded State*/
781 while(numRetry <TUNNEL_USE_BUFFER_RETRY) {
782 eError=OMX_FreeBuffer(openmaxStandPort->hTunneledComponent,openmaxStandPort->nTunneledPort,openmaxStandPort->pInternalBufferStorage[i]);
783 if(eError!=OMX_ErrorNone) {
784 DEBUG(DEB_LEV_ERR,"Tunneled Component Couldn't free buffer %i \n",i);
786 DEBUG(DEB_LEV_ERR,"Waiting for next try %i \n",(int)numRetry);
788 numRetry++;
789 continue;
790 }
791 return eError;
792 } else {
793 break;
794 }
795 }
796 openmaxStandPort->bBufferStateAllocated[i] = BUFFER_FREE;
797
798 openmaxStandPort->nNumAssignedBuffers--;
799 DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
800
801 if (openmaxStandPort->nNumAssignedBuffers == 0) {
802 openmaxStandPort->sPortParam.bPopulated = OMX_FALSE;
803 openmaxStandPort->bIsEmptyOfBuffers = OMX_TRUE;
804 //tsem_up(openmaxStandPort->pAllocSem);
805 }
806 }
807 }
808 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p Qelem=%d BSem=%d\n", __func__, openmaxStandPort,
809 openmaxStandPort->pBufferQueue->nelem, openmaxStandPort->pBufferSem->semval);
810 return OMX_ErrorNone;
811}
812
819 omx_base_PortType *openmaxStandPort,
820 OMX_BUFFERHEADERTYPE* pBuffer) {
821
823 int errQue;
824 OMX_U32 portIndex;
825 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
826 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
827 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort);
828#if NO_GST_OMX_PATCH
829 unsigned int i;
830#endif
831 portIndex = (openmaxStandPort->sPortParam.eDir == OMX_DirInput)?pBuffer->nInputPortIndex:pBuffer->nOutputPortIndex;
832 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s portIndex %lu\n", __func__, portIndex);
833
834 if (portIndex != openmaxStandPort->sPortParam.nPortIndex) {
835 DEBUG(DEB_LEV_ERR, "In %s: wrong port for this operation portIndex=%d port->portIndex=%d\n", __func__, (int)portIndex, (int)openmaxStandPort->sPortParam.nPortIndex);
837 }
838
839 if(omx_base_component_Private->state == OMX_StateInvalid) {
840 DEBUG(DEB_LEV_ERR, "In %s: we are in OMX_StateInvalid\n", __func__);
842 }
843
844 if(omx_base_component_Private->state != OMX_StateExecuting &&
845 omx_base_component_Private->state != OMX_StatePause &&
846 omx_base_component_Private->state != OMX_StateIdle) {
847 DEBUG(DEB_LEV_ERR, "In %s: we are not in executing/paused/idle state, but in %d\n", __func__, omx_base_component_Private->state);
849 }
850 if (!PORT_IS_ENABLED(openmaxStandPort) || (PORT_IS_BEING_DISABLED(openmaxStandPort) && !PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) ||
851 ((omx_base_component_Private->transientState == OMX_TransStateExecutingToIdle ||
852 omx_base_component_Private->transientState == OMX_TransStatePauseToIdle) &&
853 (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)))) {
854 DEBUG(DEB_LEV_ERR, "In %s: Port %d is disabled comp = %s \n", __func__, (int)portIndex,omx_base_component_Private->name);
856 }
857
858 /* Temporarily disable this check for gst-openmax */
859#if NO_GST_OMX_PATCH
860 {
861 OMX_BOOL foundBuffer = OMX_FALSE;
862 if(pBuffer!=NULL && pBuffer->pBuffer!=NULL) {
863 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
864 if (pBuffer->pBuffer == openmaxStandPort->pInternalBufferStorage[i]->pBuffer) {
865 foundBuffer = OMX_TRUE;
866 break;
867 }
868 }
869 }
870 if (!foundBuffer) {
872 }
873 }
874#endif
875
876 if ((err = checkHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE))) != OMX_ErrorNone) {
877 DEBUG(DEB_LEV_ERR, "In %s: received wrong buffer header on input port\n", __func__);
878 return err;
879 }
880
881 /* And notify the buffer management thread we have a fresh new buffer to manage */
882 if(!PORT_IS_BEING_FLUSHED(openmaxStandPort) && !(PORT_IS_BEING_DISABLED(openmaxStandPort) && PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort))){
883 errQue = queue(openmaxStandPort->pBufferQueue, pBuffer);
884 if (errQue) {
885 /* /TODO the queue is full. This can be handled in a fine way with
886 * some retrials, or other checking. For the moment this is a critical error
887 * and simply causes the failure of this call
888 */
890 }
891 tsem_up(openmaxStandPort->pBufferSem);
892 DEBUG(DEB_LEV_PARAMS, "In %s Signalling bMgmtSem Port Index=%d\n",__func__, (int)portIndex);
893 tsem_up(omx_base_component_Private->bMgmtSem);
894 }else if(PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)){
895 DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s received io:%d buffer\n",
896 __func__,omx_base_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex);
897 errQue = queue(openmaxStandPort->pBufferQueue, pBuffer);
898 if (errQue) {
899 /* /TODO the queue is full. This can be handled in a fine way with
900 * some retrials, or other checking. For the moment this is a critical error
901 * and simply causes the failure of this call
902 */
904 }
905 tsem_up(openmaxStandPort->pBufferSem);
906 }
907 else { // If port being flushed and not tunneled then return error
908 DEBUG(DEB_LEV_FULL_SEQ, "In %s \n", __func__);
910 }
911 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort);
912 return OMX_ErrorNone;
913}
914
919 omx_base_component_PrivateType* omx_base_component_Private=openmaxStandPort->standCompContainer->pComponentPrivate;
920 queue_t* pQueue = openmaxStandPort->pBufferQueue;
921 tsem_t* pSem = openmaxStandPort->pBufferSem;
923 int errQue;
924
925 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort);
926 if (PORT_IS_TUNNELED(openmaxStandPort) &&
927 ! PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
928 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
929 pBuffer->nOutputPortIndex = openmaxStandPort->nTunneledPort;
930 pBuffer->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
931 eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
932 if(eError != OMX_ErrorNone) {
933 DEBUG(DEB_LEV_ERR, "In %s eError %08x in FillThis Buffer from Component %s Non-Supplier\n",
934 __func__, eError,omx_base_component_Private->name);
935 }
936 } else {
937 pBuffer->nInputPortIndex = openmaxStandPort->nTunneledPort;
938 pBuffer->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
939 eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
940 if(eError != OMX_ErrorNone) {
941 DEBUG(DEB_LEV_ERR, "In %s eError %08x in EmptyThis Buffer from Component %s Non-Supplier\n",
942 __func__, eError,omx_base_component_Private->name);
943 }
944 }
945 } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort) &&
946 !PORT_IS_BEING_FLUSHED(openmaxStandPort)) {
947 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
948 eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
949 if(eError != OMX_ErrorNone) {
950 DEBUG(DEB_LEV_FULL_SEQ, "In %s eError %08x in FillThis Buffer from Component %s Supplier\n",
951 __func__, eError,omx_base_component_Private->name);
952 /*If Error Occured then queue the buffer*/
953 errQue = queue(pQueue, pBuffer);
954 if (errQue) {
955 /* /TODO the queue is full. This can be handled in a fine way with
956 * some retrials, or other checking. For the moment this is a critical error
957 * and simply causes the failure of this call
958 */
960 }
961 tsem_up(pSem);
962 }
963 } else {
964 eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
965 if(eError != OMX_ErrorNone) {
966 DEBUG(DEB_LEV_FULL_SEQ, "In %s eError %08x in EmptyThis Buffer from Component %s Supplier\n",
967 __func__, eError,omx_base_component_Private->name);
968 /*If Error Occured then queue the buffer*/
969 errQue = queue(pQueue, pBuffer);
970 if (errQue) {
971 /* /TODO the queue is full. This can be handled in a fine way with
972 * some retrials, or other checking. For the moment this is a critical error
973 * and simply causes the failure of this call
974 */
976 }
977 tsem_up(pSem);
978 }
979 }
980 } else if (!PORT_IS_TUNNELED(openmaxStandPort)){
981 (*(openmaxStandPort->BufferProcessedCallback))(
982 openmaxStandPort->standCompContainer,
983 omx_base_component_Private->callbackData,
984 pBuffer);
985 } else {
986 errQue = queue(pQueue, pBuffer);
987 if (errQue) {
988 /* /TODO the queue is full. This can be handled in a fine way with
989 * some retrials, or other checking. For the moment this is a critical error
990 * and simply causes the failure of this call
991 */
993 }
994 openmaxStandPort->nNumBufferFlushed++;
995 }
996
997 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort);
998 return OMX_ErrorNone;
999}
1000
1001
1006
1007 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort);
1008 if (pTunnelSetup == NULL || hTunneledComp == 0) {
1009 /* cancel previous tunnel */
1010 openmaxStandPort->hTunneledComponent = 0;
1011 openmaxStandPort->nTunneledPort = 0;
1012 openmaxStandPort->nTunnelFlags = 0;
1014 return OMX_ErrorNone;
1015 }
1016
1017 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
1018 /* Get Port Definition of the Tunnelled Component*/
1019 param.nPortIndex=nTunneledPort;
1020 setHeader(&param, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1021 err = OMX_GetParameter(hTunneledComp, OMX_IndexParamPortDefinition, &param);
1023 if (err != OMX_ErrorNone) {
1024 DEBUG(DEB_LEV_ERR,"In %s Tunneled Port Definition error=0x%08x Line=%d\n",__func__,err,__LINE__);
1025 // compatibility not reached
1027 }
1028 openmaxStandPort->nNumTunnelBuffer = param.nBufferCountActual;
1029 if(param.eDomain!=openmaxStandPort->sPortParam.eDomain) {
1031 }
1032 if(param.eDomain==OMX_PortDomainAudio) {
1035 }
1036 } else if(param.eDomain==OMX_PortDomainVideo) {
1039 }
1040 } else if(param.eDomain==OMX_PortDomainOther) {
1043 }
1044 }
1045
1046 /* Get Buffer Supplier type of the Tunneled Component*/
1047 pSupplier.nPortIndex=nTunneledPort;
1048 setHeader(&pSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
1049 err = OMX_GetParameter(hTunneledComp, OMX_IndexParamCompBufferSupplier, &pSupplier);
1050 if (err != OMX_ErrorNone) {
1051 // compatibility not reached
1052 DEBUG(DEB_LEV_ERR,"In %s Tunneled Buffer Supplier error=0x%08x Line=%d\n",__func__,err,__LINE__);
1054 } else {
1055 DEBUG(DEB_LEV_FULL_SEQ,"Tunneled Port eBufferSupplier=%x\n", pSupplier.eBufferSupplier);
1056 }
1057
1058 // store the current callbacks, if defined
1059 openmaxStandPort->hTunneledComponent = hTunneledComp;
1060 openmaxStandPort->nTunneledPort = nTunneledPort;
1061
1062 /*Check for and set proprietary communication flag.
1063 In case a component support Deep Tunneling should set it's tunnel flag to PROPRIETARY_COMMUNICATION_ESTABLISHED */
1064 if(PORT_IS_DEEP_TUNNELED(openmaxStandPort)) {
1065 OMX_VENDOR_PROP_TUNNELSETUPTYPE pPropTunnelSetup;
1066 pPropTunnelSetup.nPortIndex = nTunneledPort;
1067
1068 err = OMX_GetParameter(hTunneledComp, OMX_IndexVendorCompPropTunnelFlags, &pPropTunnelSetup);
1069 if (err != OMX_ErrorNone) {
1070 // compatibility not reached
1071 DEBUG(DEB_LEV_ERR,"In %s Proprietary Tunneled Buffer Supplier nTunneledPort=%d error=0x%08x Line=%d \n",
1072 __func__,(int)pPropTunnelSetup.nPortIndex,err,__LINE__);
1073 openmaxStandPort->nTunnelFlags = 0;
1074 } else {
1076 }
1077 } else {
1078 openmaxStandPort->nTunnelFlags = 0;
1079 }
1080
1081 // Negotiation
1082 if (pTunnelSetup->nTunnelFlags & OMX_PORTTUNNELFLAG_READONLY) {
1083 // the buffer provider MUST be the output port provider
1084 pTunnelSetup->eSupplier = OMX_BufferSupplyInput;
1085 openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER;
1086 openmaxStandPort->eBufferSupplier=OMX_BufferSupplyInput;
1087 } else {
1088 if (pTunnelSetup->eSupplier == OMX_BufferSupplyInput) {
1089 openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER;
1090 openmaxStandPort->eBufferSupplier=OMX_BufferSupplyInput;
1091 } else if (pTunnelSetup->eSupplier == OMX_BufferSupplyUnspecified) {
1092 pTunnelSetup->eSupplier = OMX_BufferSupplyInput;
1093 openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER;
1094 openmaxStandPort->eBufferSupplier=OMX_BufferSupplyInput;
1095 }
1096 }
1097 openmaxStandPort->nTunnelFlags |= TUNNEL_ESTABLISHED;
1098
1099 /* Set Buffer Supplier type of the Tunnelled Component after final negotiation*/
1100 pSupplier.nPortIndex=nTunneledPort;
1101 pSupplier.eBufferSupplier=openmaxStandPort->eBufferSupplier;
1102 err = OMX_SetParameter(hTunneledComp, OMX_IndexParamCompBufferSupplier, &pSupplier);
1103 if (err != OMX_ErrorNone) {
1104 // compatibility not reached
1105 DEBUG(DEB_LEV_ERR,"In %s Tunneled Buffer Supplier error=0x%08x Line=%d\n",__func__,err,__LINE__);
1106 openmaxStandPort->nTunnelFlags=0;
1108 }
1109 } else {
1110 // output port
1111 // all the consistency checks are under other component responsibility
1112
1113 /* Get Port Definition of the Tunnelled Component*/
1114 param.nPortIndex=nTunneledPort;
1115 setHeader(&param, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1116 err = OMX_GetParameter(hTunneledComp, OMX_IndexParamPortDefinition, &param);
1117 if (err != OMX_ErrorNone) {
1118 DEBUG(DEB_LEV_ERR,"In %s Tunneled Port Definition error=0x%08x Line=%d\n",__func__,err,__LINE__);
1119 // compatibility not reached
1121 }
1122 if(param.eDomain!=openmaxStandPort->sPortParam.eDomain) {
1124 }
1125
1126 if(param.eDomain==OMX_PortDomainAudio) {
1129 }
1130 } else if(param.eDomain==OMX_PortDomainVideo) {
1133 }
1134 } else if(param.eDomain==OMX_PortDomainOther) {
1137 }
1138 }
1139
1140 /*Check for and set proprietary communication flag*/
1141 if(PORT_IS_DEEP_TUNNELED(openmaxStandPort)) {
1142 OMX_VENDOR_PROP_TUNNELSETUPTYPE pPropTunnelSetup;
1143 pPropTunnelSetup.nPortIndex = nTunneledPort;
1144
1145 err = OMX_GetParameter(hTunneledComp, OMX_IndexVendorCompPropTunnelFlags, &pPropTunnelSetup);
1146 if (err != OMX_ErrorNone) {
1147 // compatibility not reached
1148 DEBUG(DEB_LEV_ERR,"In %s Proprietary Tunneled Buffer Supplier nTunneledPort=%d error=0x%08x Line=%d \n",
1149 __func__,(int)pPropTunnelSetup.nPortIndex,err,__LINE__);
1150 openmaxStandPort->nTunnelFlags = 0;
1151 } else {
1153 }
1154 } else {
1155 openmaxStandPort->nTunnelFlags = 0;
1156 }
1157
1158 openmaxStandPort->nNumTunnelBuffer=param.nBufferCountActual;
1159
1160 openmaxStandPort->hTunneledComponent = hTunneledComp;
1161 openmaxStandPort->nTunneledPort = nTunneledPort;
1162 pTunnelSetup->eSupplier = OMX_BufferSupplyOutput;
1163 openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER;
1164 openmaxStandPort->nTunnelFlags |= TUNNEL_ESTABLISHED;
1165
1166 openmaxStandPort->eBufferSupplier=OMX_BufferSupplyOutput;
1167 }
1168
1169 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort);
1170 return OMX_ErrorNone;
1171}
OMX_ERRORTYPE
Definition: OMX_Core.h:127
@ OMX_ErrorInvalidState
Definition: OMX_Core.h:162
@ OMX_ErrorInsufficientResources
Definition: OMX_Core.h:131
@ OMX_ErrorBadPortIndex
Definition: OMX_Core.h:224
@ OMX_ErrorPortUnpopulated
Definition: OMX_Core.h:227
@ OMX_ErrorNone
Definition: OMX_Core.h:128
@ OMX_ErrorPortsNotCompatible
Definition: OMX_Core.h:168
@ OMX_ErrorBadParameter
Definition: OMX_Core.h:147
@ OMX_ErrorIncorrectStateTransition
Definition: OMX_Core.h:212
@ OMX_ErrorIncorrectStateOperation
Definition: OMX_Core.h:215
#define OMX_PORTTUNNELFLAG_READONLY
Definition: OMX_Core.h:627
@ OMX_IndexParamCompBufferSupplier
Definition: OMX_Index.h:89
@ OMX_IndexParamPortDefinition
Definition: OMX_Index.h:88
@ OMX_OTHER_FormatMax
Definition: OMX_Other.h:63
unsigned long OMX_U32
Definition: OMX_Types.h:145
unsigned char OMX_U8
Definition: OMX_Types.h:133
OMX_BOOL
Definition: OMX_Types.h:189
@ OMX_TRUE
Definition: OMX_Types.h:191
@ OMX_FALSE
Definition: OMX_Types.h:190
void * OMX_PTR
Definition: OMX_Types.h:199
void * OMX_HANDLETYPE
Definition: OMX_Types.h:295
@ OMX_DirInput
Definition: OMX_Types.h:226
@ OMX_DirOutput
Definition: OMX_Types.h:227
@ OMX_AUDIO_CodingMax
Definition: OMX_Audio.h:94
#define OMX_UseBuffer( hComponent, ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, pBuffer)
Definition: OMX_Core.h:985
#define OMX_FreeBuffer( hComponent, nPortIndex, pBuffer)
Definition: OMX_Core.h:1064
@ OMX_BufferSupplyOutput
Definition: OMX_Core.h:605
@ OMX_BufferSupplyInput
Definition: OMX_Core.h:604
@ OMX_BufferSupplyUnspecified
Definition: OMX_Core.h:602
#define OMX_GetParameter( hComponent, nParamIndex, pComponentParameterStructure)
Definition: OMX_Core.h:786
#define OMX_SetParameter( hComponent, nParamIndex, pComponentParameterStructure)
Definition: OMX_Core.h:825
@ OMX_PortDomainAudio
Definition: OMX_Component.h:51
@ OMX_PortDomainVideo
Definition: OMX_Component.h:52
@ OMX_PortDomainOther
Definition: OMX_Component.h:54
@ OMX_StateExecuting
Definition: OMX_Core.h:105
@ OMX_StateWaitForResources
Definition: OMX_Core.h:108
@ OMX_StateLoaded
Definition: OMX_Core.h:97
@ OMX_StateInvalid
Definition: OMX_Core.h:94
@ OMX_StateIdle
Definition: OMX_Core.h:102
@ OMX_StatePause
Definition: OMX_Core.h:107
@ OMX_EventError
Definition: OMX_Core.h:482
@ OMX_VIDEO_CodingMax
Definition: OMX_Video.h:73
void setHeader(OMX_PTR header, OMX_U32 size)
Simply fills the first two fields in any OMX structure with the size and the version.
OMX_ERRORTYPE checkHeader(OMX_PTR header, OMX_U32 size)
Checks the header of a structure for consistency with size and spec version.
@ OMX_IndexVendorCompPropTunnelFlags
@ OMX_TransStateExecutingToIdle
@ OMX_TransStateIdleToLoaded
@ OMX_TransStatePauseToIdle
@ OMX_TransStateLoadedToIdle
OMX_ERRORTYPE base_port_FlushProcessingBuffers(omx_base_PortType *openmaxStandPort)
Releases buffers under processing. This function must be implemented in the derived classes,...
OMX_ERRORTYPE base_port_SendBufferFunction(omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE *pBuffer)
the entry point for sending buffers to the port
#define DEFAULT_NUMBER_BUFFERS_PER_PORT
Definition: omx_base_port.c:36
OMX_ERRORTYPE base_port_ReturnBufferFunction(omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE *pBuffer)
Returns buffers when processed.
OMX_ERRORTYPE base_port_DisablePort(omx_base_PortType *openmaxStandPort)
Disables the port.
OMX_ERRORTYPE base_port_FreeBuffer(omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE *pBuffer)
Called by the standard function.
OMX_ERRORTYPE base_port_FreeTunnelBuffer(omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex)
Free buffers used in tunnel.
OMX_ERRORTYPE base_port_ComponentTunnelRequest(omx_base_PortType *openmaxStandPort, OMX_HANDLETYPE hTunneledComp, OMX_U32 nTunneledPort, OMX_TUNNELSETUPTYPE *pTunnelSetup)
Setup Tunnel with the port.
OMX_ERRORTYPE base_port_AllocateTunnelBuffer(omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex)
Allocate Buffers for tunneling use.
OMX_ERRORTYPE base_port_UseBuffer(omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE **ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, OMX_U32 nSizeBytes, OMX_U8 *pBuffer)
Called by the standard use buffer, it implements a base functionality.
OMX_ERRORTYPE base_port_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, omx_base_PortType **openmaxStandPort, OMX_U32 nPortIndex, OMX_BOOL isInput)
The base contructor for the generic OpenMAX ST port.
Definition: omx_base_port.c:55
OMX_ERRORTYPE base_port_AllocateBuffer(omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE **pBuffer, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, OMX_U32 nSizeBytes)
Called by the standard allocate buffer, it implements a base functionality.
OMX_ERRORTYPE base_port_Destructor(omx_base_PortType *openmaxStandPort)
The base destructor for the generic OpenMAX ST port.
OMX_ERRORTYPE base_port_EnablePort(omx_base_PortType *openmaxStandPort)
Enables the port.
#define DEFAULT_MIN_NUMBER_BUFFERS_PER_PORT
Definition: omx_base_port.c:38
#define PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(pPort)
Definition: omx_base_port.h:46
@ BUFFER_ASSIGNED
Definition: omx_base_port.h:76
@ HEADER_ALLOCATED
Definition: omx_base_port.h:78
@ BUFFER_FREE
Definition: omx_base_port.h:73
@ BUFFER_ALLOCATED
Definition: omx_base_port.h:74
#define TUNNEL_USE_BUFFER_RETRY_USLEEP_TIME
Definition: omx_base_port.h:34
@ PROPRIETARY_COMMUNICATION_ESTABLISHED
Definition: omx_base_port.h:92
@ TUNNEL_ESTABLISHED
Definition: omx_base_port.h:86
@ TUNNEL_IS_SUPPLIER
Definition: omx_base_port.h:89
#define PORT_IS_BUFFER_SUPPLIER(pPort)
Definition: omx_base_port.h:45
#define PORT_IS_TUNNELED(pPort)
Definition: omx_base_port.h:43
#define PORT_IS_BEING_DISABLED(pPort)
Definition: omx_base_port.h:40
#define PORT_IS_ENABLED(pPort)
Definition: omx_base_port.h:41
#define PORT_IS_DEEP_TUNNELED(pPort)
Definition: omx_base_port.h:44
#define PORT_IS_BEING_FLUSHED(pPort)
Definition: omx_base_port.h:39
#define TUNNEL_USE_BUFFER_RETRY
Definition: omx_base_port.h:33
#define DEB_LEV_PARAMS
#define DEB_LEV_FUNCTION_NAME
#define DEB_LEV_ERR
#define DEB_LEV_SIMPLE_SEQ
#define DEB_LEV_FULL_SEQ
#define DEBUG(n, fmt, args...)
OMX_ERRORTYPE err
int queue(queue_t *queue, void *data)
Definition: queue.c:103
void * dequeue(queue_t *queue)
Definition: queue.c:122
void queue_deinit(queue_t *queue)
Definition: queue.c:77
int queue_init(queue_t *queue)
Definition: queue.c:38
OMX_AUDIO_CODINGTYPE eEncoding
Definition: OMX_Audio.h:111
OMX_PTR pPlatformPrivate
Definition: OMX_Core.h:411
OMX_U32 nOutputPortIndex
Definition: OMX_Core.h:439
OMX_U32 nInputPortIndex
Definition: OMX_Core.h:441
OMX_ERRORTYPE(* EventHandler)(OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_PTR pAppData, OMX_IN OMX_EVENTTYPE eEvent, OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2, OMX_IN OMX_PTR pEventData)
Definition: OMX_Core.h:530
OMX_PTR pComponentPrivate
OMX_OTHER_FORMATTYPE eFormat
Definition: OMX_Other.h:318
OMX_BUFFERSUPPLIERTYPE eBufferSupplier
Definition: OMX_Core.h:619
union OMX_PARAM_PORTDEFINITIONTYPE::@0 format
OMX_PORTDOMAINTYPE eDomain
Definition: OMX_Component.h:77
OMX_AUDIO_PORTDEFINITIONTYPE audio
Definition: OMX_Component.h:79
OMX_OTHER_PORTDEFINITIONTYPE other
Definition: OMX_Component.h:82
OMX_VIDEO_PORTDEFINITIONTYPE video
Definition: OMX_Component.h:80
OMX_BUFFERSUPPLIERTYPE eSupplier
Definition: OMX_Core.h:638
OMX_U32 nTunnelFlags
Definition: OMX_Core.h:637
OMX_VIDEO_CODINGTYPE eCompressionFormat
Definition: OMX_Video.h:134
OMX_BOOL bIsEmptyOfBuffers
OMX_PARAM_PORTDEFINITIONTYPE sPortParam
OMX_U32 nNumBufferFlushed
OMX_ERRORTYPE(* BufferProcessedCallback)(OMX_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_BUFFERHEADERTYPE *pBuffer)
OMX_U32 nNumAssignedBuffers
OMX_BOOL bIsDestroying
OMX_BOOL bIsTransientToEnabled
OMX_BOOL bIsPortFlushed
OMX_ERRORTYPE(* Port_AllocateTunnelBuffer)(omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex)
pthread_mutex_t exitMutex
OMX_HANDLETYPE hTunneledComponent
BUFFER_STATUS_FLAG * bBufferStateAllocated
OMX_U32 nNumTunnelBuffer
OMX_COMPONENTTYPE * standCompContainer
OMX_BUFFERSUPPLIERTYPE eBufferSupplier
queue_t * pBufferQueue
OMX_BOOL bIsFullOfBuffers
OMX_BOOL bIsTransientToDisabled
OMX_BUFFERHEADERTYPE ** pInternalBufferStorage
OMX_ERRORTYPE(* Port_FreeTunnelBuffer)(omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex)
Definition: queue.h:43
int nelem
Definition: queue.h:46
unsigned int semval
Definition: tsemaphore.h:41
void tsem_deinit(tsem_t *tsem)
Definition: tsemaphore.c:57
void tsem_signal(tsem_t *tsem)
Definition: tsemaphore.c:141
void tsem_up(tsem_t *tsem)
Definition: tsemaphore.c:110
int tsem_init(tsem_t *tsem, unsigned int val)
Definition: tsemaphore.c:39
void tsem_down(tsem_t *tsem)
Definition: tsemaphore.c:97
void tsem_reset(tsem_t *tsem)
Definition: tsemaphore.c:121

Generated for OpenMAX Bellagio rel. 0.9.3 by  doxygen 1.5.1
SourceForge.net Logo