OpenMAXBellagio  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
37 
38 #define DEFAULT_MIN_NUMBER_BUFFERS_PER_PORT 2
39 
55 OMX_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  }
201 DEBUG(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) {
396  return OMX_ErrorBadPortIndex;
397  }
398  if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
399  return OMX_ErrorBadPortIndex;
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) {
476  return OMX_ErrorBadPortIndex;
477  }
478  if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
479  return OMX_ErrorBadPortIndex;
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) {
558  return OMX_ErrorBadPortIndex;
559  }
560  if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
561  return OMX_ErrorBadPortIndex;
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__);
631  return OMX_ErrorBadPortIndex;
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);
635  return OMX_ErrorBadPortIndex;
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;
648  err = OMX_GetParameter(openmaxStandPort->hTunneledComponent, OMX_IndexParamPortDefinition, &sPortDef);
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;
664  err = OMX_SetParameter(openmaxStandPort->hTunneledComponent, OMX_IndexParamPortDefinition, &sPortDef);
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 
691  if((eError == OMX_ErrorIncorrectStateTransition) && numRetry<TUNNEL_USE_BUFFER_RETRY) {
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__);
752  return OMX_ErrorBadPortIndex;
753  }
754  if (! PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
755  DEBUG(DEB_LEV_ERR, "In %s: Port is not tunneled\n", __func__);
756  return OMX_ErrorBadPortIndex;
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);
785  if((eError == OMX_ErrorIncorrectStateTransition) && numRetry<TUNNEL_USE_BUFFER_RETRY) {
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);
836  return OMX_ErrorBadPortIndex;
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__);
841  return OMX_ErrorInvalidState;
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) {
871  return OMX_ErrorBadParameter;
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;
922  OMX_ERRORTYPE eError = OMX_ErrorNone;
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 
1002 OMX_ERRORTYPE base_port_ComponentTunnelRequest(omx_base_PortType* openmaxStandPort, OMX_HANDLETYPE hTunneledComp, OMX_U32 nTunneledPort, OMX_TUNNELSETUPTYPE* pTunnelSetup) {
1005  OMX_PARAM_BUFFERSUPPLIERTYPE pSupplier;
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;
1013  openmaxStandPort->eBufferSupplier=OMX_BufferSupplyUnspecified;
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) {
1033  if(param.format.audio.eEncoding == OMX_AUDIO_CodingMax) {
1035  }
1036  } else if(param.eDomain==OMX_PortDomainVideo) {
1039  }
1040  } else if(param.eDomain==OMX_PortDomainOther) {
1041  if(param.format.other.eFormat == OMX_OTHER_FormatMax) {
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) {
1127  if(param.format.audio.eEncoding == OMX_AUDIO_CodingMax) {
1129  }
1130  } else if(param.eDomain==OMX_PortDomainVideo) {
1133  }
1134  } else if(param.eDomain==OMX_PortDomainOther) {
1135  if(param.format.other.eFormat == OMX_OTHER_FormatMax) {
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_BOOL bIsFullOfBuffers
OMX_ERRORTYPE(* BufferProcessedCallback)(OMX_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_BUFFERHEADERTYPE *pBuffer)
OMX_ERRORTYPE base_port_ReturnBufferFunction(omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE *pBuffer)
Returns buffers when processed.
OMX_ERRORTYPE(* Port_AllocateTunnelBuffer)(omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex)
OMX_U32 nNumTunnelBuffer
OMX_HANDLETYPE hTunneledComponent
OMX_BOOL bIsTransientToDisabled
void * OMX_HANDLETYPE
Definition: OMX_Types.h:295
#define OMX_SetParameter( hComponent, nParamIndex, pComponentParameterStructure)
Definition: OMX_Core.h:825
OMX_OTHER_FORMATTYPE eFormat
Definition: OMX_Other.h:318
#define DEB_LEV_PARAMS
unsigned long OMX_U32
Definition: OMX_Types.h:145
OMX_BOOL bIsTransientToEnabled
OMX_U32 nNumAssignedBuffers
OMX_ERRORTYPE base_port_EnablePort(omx_base_PortType *openmaxStandPort)
Enables the port.
int nelem
Definition: queue.h:46
OMX_ERRORTYPE checkHeader(OMX_PTR header, OMX_U32 size)
Checks the header of a structure for consistency with size and spec version.
#define DEB_LEV_SIMPLE_SEQ
OMX_BOOL bIsEmptyOfBuffers
OMX_ERRORTYPE base_port_DisablePort(omx_base_PortType *openmaxStandPort)
Disables the port.
#define PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(pPort)
Definition: omx_base_port.h:46
void tsem_signal(tsem_t *tsem)
Definition: tsemaphore.c:141
#define PORT_IS_BEING_DISABLED(pPort)
Definition: omx_base_port.h:40
OMX_ERRORTYPE base_port_FlushProcessingBuffers(omx_base_PortType *openmaxStandPort)
Releases buffers under processing. This function must be implemented in the derived classes...
#define OMX_PORTTUNNELFLAG_READONLY
Definition: OMX_Core.h:627
#define DEBUG(n, fmt, args...)
OMX_ERRORTYPE base_port_Destructor(omx_base_PortType *openmaxStandPort)
The base destructor for the generic OpenMAX ST port.
#define PORT_IS_TUNNELED(pPort)
Definition: omx_base_port.h:43
BUFFER_STATUS_FLAG * bBufferStateAllocated
queue_t * pBufferQueue
union OMX_PARAM_PORTDEFINITIONTYPE::@0 format
void queue_deinit(queue_t *queue)
Definition: queue.c:77
#define OMX_UseBuffer( hComponent, ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, pBuffer)
Definition: OMX_Core.h:985
void * OMX_PTR
Definition: OMX_Types.h:199
OMX_BOOL
Definition: OMX_Types.h:189
#define TUNNEL_USE_BUFFER_RETRY_USLEEP_TIME
Definition: omx_base_port.h:34
#define DEB_LEV_ERR
#define TUNNEL_USE_BUFFER_RETRY
Definition: omx_base_port.h:33
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_VIDEO_PORTDEFINITIONTYPE video
Definition: OMX_Component.h:80
#define PORT_IS_BUFFER_SUPPLIER(pPort)
Definition: omx_base_port.h:45
void tsem_up(tsem_t *tsem)
Definition: tsemaphore.c:110
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.
int queue_init(queue_t *queue)
Definition: queue.c:38
void setHeader(OMX_PTR header, OMX_U32 size)
Simply fills the first two fields in any OMX structure with the size and the version.
unsigned int semval
Definition: tsemaphore.h:41
OMX_OTHER_PORTDEFINITIONTYPE other
Definition: OMX_Component.h:82
OMX_BOOL bIsDestroying
void tsem_down(tsem_t *tsem)
Definition: tsemaphore.c:97
#define OMX_FreeBuffer( hComponent, nPortIndex, pBuffer)
Definition: OMX_Core.h:1064
Definition: queue.h:43
OMX_VIDEO_CODINGTYPE eCompressionFormat
Definition: OMX_Video.h:134
OMX_U32 nInputPortIndex
Definition: OMX_Core.h:441
OMX_ERRORTYPE(* Port_FreeTunnelBuffer)(omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex)
#define OMX_GetParameter( hComponent, nParamIndex, pComponentParameterStructure)
Definition: OMX_Core.h:786
#define PORT_IS_DEEP_TUNNELED(pPort)
Definition: omx_base_port.h:44
#define DEFAULT_MIN_NUMBER_BUFFERS_PER_PORT
Definition: omx_base_port.c:38
int queue(queue_t *queue, void *data)
Definition: queue.c:103
#define DEFAULT_NUMBER_BUFFERS_PER_PORT
Definition: omx_base_port.c:36
OMX_U32 nNumBufferFlushed
void tsem_reset(tsem_t *tsem)
Definition: tsemaphore.c:121
OMX_AUDIO_CODINGTYPE eEncoding
Definition: OMX_Audio.h:111
unsigned char OMX_U8
Definition: OMX_Types.h:133
OMX_U32 nOutputPortIndex
Definition: OMX_Core.h:439
#define PORT_IS_ENABLED(pPort)
Definition: omx_base_port.h:41
OMX_ERRORTYPE err
OMX_BUFFERSUPPLIERTYPE eBufferSupplier
OMX_PORTDOMAINTYPE eDomain
Definition: OMX_Component.h:77
OMX_U32 nTunnelFlags
Definition: OMX_Core.h:637
#define DEB_LEV_FULL_SEQ
OMX_BUFFERHEADERTYPE ** pInternalBufferStorage
void tsem_deinit(tsem_t *tsem)
Definition: tsemaphore.c:57
OMX_PTR pPlatformPrivate
Definition: OMX_Core.h:411
OMX_ERRORTYPE base_port_SendBufferFunction(omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE *pBuffer)
the entry point for sending buffers to the port
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_PTR pComponentPrivate
#define DEB_LEV_FUNCTION_NAME
OMX_ERRORTYPE base_port_AllocateTunnelBuffer(omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex)
Allocate Buffers for tunneling use.
int tsem_init(tsem_t *tsem, unsigned int val)
Definition: tsemaphore.c:39
OMX_COMPONENTTYPE * standCompContainer
OMX_ERRORTYPE base_port_ComponentTunnelRequest(omx_base_PortType *openmaxStandPort, OMX_HANDLETYPE hTunneledComp, OMX_U32 nTunneledPort, OMX_TUNNELSETUPTYPE *pTunnelSetup)
Setup Tunnel with the port.
OMX_AUDIO_PORTDEFINITIONTYPE audio
Definition: OMX_Component.h:79
OMX_BUFFERSUPPLIERTYPE eSupplier
Definition: OMX_Core.h:638
#define PORT_IS_BEING_FLUSHED(pPort)
Definition: omx_base_port.h:39
void * dequeue(queue_t *queue)
Definition: queue.c:122
OMX_ERRORTYPE base_port_FreeBuffer(omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE *pBuffer)
Called by the standard function.
OMX_BUFFERSUPPLIERTYPE eBufferSupplier
Definition: OMX_Core.h:619
OMX_PARAM_PORTDEFINITIONTYPE sPortParam
OMX_BOOL bIsPortFlushed
OMX_ERRORTYPE base_port_FreeTunnelBuffer(omx_base_PortType *openmaxStandPort, OMX_U32 nPortIndex)
Free buffers used in tunnel.
OMX_ERRORTYPE
Definition: OMX_Core.h:126
pthread_mutex_t exitMutex

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