OpenMAXBellagio  0.9.3
omx_base_filter.c
Go to the documentation of this file.
1 
28 #include <unistd.h>
29 #if defined(__linux__)
30 #include <asm/unistd.h>
31 #endif
32 #include <omxcore.h>
33 
34 #include "omx_base_filter.h"
35 
38  omx_base_filter_PrivateType* omx_base_filter_Private;
39 
40  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s of component %p\n", __func__, openmaxStandComp);
41  if (openmaxStandComp->pComponentPrivate) {
42  omx_base_filter_Private = (omx_base_filter_PrivateType*)openmaxStandComp->pComponentPrivate;
43  } else {
44  omx_base_filter_Private = calloc(1,sizeof(omx_base_filter_PrivateType));
45  if (!omx_base_filter_Private) {
46  DEBUG(DEB_LEV_ERR, "Insufficient memory in %s\n", __func__);
48  }
49  openmaxStandComp->pComponentPrivate=omx_base_filter_Private;
50  }
51 
52  /* Call the base class constructor */
53  err = omx_base_component_Constructor(openmaxStandComp,cComponentName);
54  if (err != OMX_ErrorNone) {
55  DEBUG(DEB_LEV_ERR, "The base constructor failed in %s\n", __func__);
56  return err;
57  }
58  /* here we can override whatever defaults the base_component constructor set
59  * e.g. we can override the function pointers in the private struct */
60  omx_base_filter_Private = openmaxStandComp->pComponentPrivate;
61 
62  omx_base_filter_Private->BufferMgmtFunction = omx_base_filter_BufferMgmtFunction;
63 
64  DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s of component %p\n", __func__, openmaxStandComp);
65  return OMX_ErrorNone;
66 }
67 
70  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s of component %p\n", __func__, openmaxStandComp);
71  err = omx_base_component_Destructor(openmaxStandComp);
72  if (err != OMX_ErrorNone) {
73  DEBUG(DEB_LEV_ERR, "The base component destructor failed\n");
74  return err;
75  }
76  DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s of component %p\n", __func__, openmaxStandComp);
77  return OMX_ErrorNone;
78 }
79 
86  OMX_COMPONENTTYPE* openmaxStandComp = (OMX_COMPONENTTYPE*)param;
87  omx_base_filter_PrivateType* omx_base_filter_Private = (omx_base_filter_PrivateType*)openmaxStandComp->pComponentPrivate;
88  omx_base_PortType *pInPort=(omx_base_PortType *)omx_base_filter_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
89  omx_base_PortType *pOutPort=(omx_base_PortType *)omx_base_filter_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
90  tsem_t* pInputSem = pInPort->pBufferSem;
91  tsem_t* pOutputSem = pOutPort->pBufferSem;
92  queue_t* pInputQueue = pInPort->pBufferQueue;
93  queue_t* pOutputQueue = pOutPort->pBufferQueue;
94  OMX_BUFFERHEADERTYPE* pOutputBuffer=NULL;
95  OMX_BUFFERHEADERTYPE* pInputBuffer=NULL;
96  OMX_BOOL isInputBufferNeeded=OMX_TRUE,isOutputBufferNeeded=OMX_TRUE;
97  int inBufExchanged=0,outBufExchanged=0;
98 
99 #if defined(__linux__)
100  omx_base_filter_Private->bellagioThreads->nThreadBufferMngtID = (long int)syscall(__NR_gettid);
101  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s of component %p\n", __func__, openmaxStandComp);
102  DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s the thread ID is %i\n", __func__, (int)omx_base_filter_Private->bellagioThreads->nThreadBufferMngtID);
103 #endif
104 
105  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
106  /* checks if the component is in a state able to receive buffers */
107  while(omx_base_filter_Private->state == OMX_StateIdle || omx_base_filter_Private->state == OMX_StateExecuting || omx_base_filter_Private->state == OMX_StatePause ||
108  omx_base_filter_Private->transientState == OMX_TransStateLoadedToIdle){
109 
110  /*Wait till the ports are being flushed*/
111  pthread_mutex_lock(&omx_base_filter_Private->flush_mutex);
112  while( PORT_IS_BEING_FLUSHED(pInPort) ||
113  PORT_IS_BEING_FLUSHED(pOutPort)) {
114  pthread_mutex_unlock(&omx_base_filter_Private->flush_mutex);
115 
116  DEBUG(DEB_LEV_FULL_SEQ, "In %s 1 signaling flush all cond iE=%d,iF=%d,oE=%d,oF=%d iSemVal=%d,oSemval=%d\n",
117  __func__,inBufExchanged,isInputBufferNeeded,outBufExchanged,isOutputBufferNeeded,pInputSem->semval,pOutputSem->semval);
118 
119  if(isOutputBufferNeeded==OMX_FALSE && PORT_IS_BEING_FLUSHED(pOutPort)) {
120  pOutPort->ReturnBufferFunction(pOutPort,pOutputBuffer);
121  outBufExchanged--;
122  pOutputBuffer=NULL;
123  isOutputBufferNeeded=OMX_TRUE;
124  DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output buffer\n");
125  }
126 
127  if(isInputBufferNeeded==OMX_FALSE && PORT_IS_BEING_FLUSHED(pInPort)) {
128  pInPort->ReturnBufferFunction(pInPort,pInputBuffer);
129  inBufExchanged--;
130  pInputBuffer=NULL;
131  isInputBufferNeeded=OMX_TRUE;
132  DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning input buffer\n");
133  }
134 
135  DEBUG(DEB_LEV_FULL_SEQ, "In %s 2 signaling flush all cond iE=%d,iF=%d,oE=%d,oF=%d iSemVal=%d,oSemval=%d\n",
136  __func__,inBufExchanged,isInputBufferNeeded,outBufExchanged,isOutputBufferNeeded,pInputSem->semval,pOutputSem->semval);
137 
138  tsem_up(omx_base_filter_Private->flush_all_condition);
139  tsem_down(omx_base_filter_Private->flush_condition);
140  pthread_mutex_lock(&omx_base_filter_Private->flush_mutex);
141  }
142  pthread_mutex_unlock(&omx_base_filter_Private->flush_mutex);
143 
144  /*No buffer to process. So wait here*/
145  if((isInputBufferNeeded==OMX_TRUE && pInputSem->semval==0) &&
146  (omx_base_filter_Private->state != OMX_StateLoaded && omx_base_filter_Private->state != OMX_StateInvalid)) {
147  //Signaled from EmptyThisBuffer or FillThisBuffer or some thing else
148  DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next input/output buffer\n");
149  tsem_down(omx_base_filter_Private->bMgmtSem);
150 
151  }
152  if(omx_base_filter_Private->state == OMX_StateLoaded || omx_base_filter_Private->state == OMX_StateInvalid) {
153  DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
154  break;
155  }
156  if((isOutputBufferNeeded==OMX_TRUE && pOutputSem->semval==0) &&
157  (omx_base_filter_Private->state != OMX_StateLoaded && omx_base_filter_Private->state != OMX_StateInvalid) &&
158  !(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
159  //Signaled from EmptyThisBuffer or FillThisBuffer or some thing else
160  DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next input/output buffer\n");
161  tsem_down(omx_base_filter_Private->bMgmtSem);
162 
163  }
164  if(omx_base_filter_Private->state == OMX_StateLoaded || omx_base_filter_Private->state == OMX_StateInvalid) {
165  DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
166  break;
167  }
168 
169  DEBUG(DEB_LEV_FULL_SEQ, "Waiting for input buffer semval=%d in %s\n",pInputSem->semval, __func__);
170  if(pInputSem->semval>0 && isInputBufferNeeded==OMX_TRUE ) {
171  tsem_down(pInputSem);
172  if(pInputQueue->nelem>0){
173  inBufExchanged++;
174  isInputBufferNeeded=OMX_FALSE;
175  pInputBuffer = dequeue(pInputQueue);
176  if(pInputBuffer == NULL){
177  DEBUG(DEB_LEV_ERR, "Had NULL input buffer!!\n");
178  break;
179  }
180  }
181  }
182  /*When we have input buffer to process then get one output buffer*/
183  if(pOutputSem->semval>0 && isOutputBufferNeeded==OMX_TRUE) {
184  tsem_down(pOutputSem);
185  if(pOutputQueue->nelem>0){
186  outBufExchanged++;
187  isOutputBufferNeeded=OMX_FALSE;
188  pOutputBuffer = dequeue(pOutputQueue);
189  if(pOutputBuffer == NULL){
190  DEBUG(DEB_LEV_ERR, "Had NULL output buffer!! op is=%d,iq=%d\n",pOutputSem->semval,pOutputQueue->nelem);
191  break;
192  }
193  }
194  }
195 
196  if(isInputBufferNeeded==OMX_FALSE) {
197  if(pInputBuffer->hMarkTargetComponent != NULL){
198  if((OMX_COMPONENTTYPE*)pInputBuffer->hMarkTargetComponent ==(OMX_COMPONENTTYPE *)openmaxStandComp) {
199  /*Clear the mark and generate an event*/
200  (*(omx_base_filter_Private->callbacks->EventHandler))
201  (openmaxStandComp,
202  omx_base_filter_Private->callbackData,
203  OMX_EventMark, /* The command was completed */
204  1, /* The commands was a OMX_CommandStateSet */
205  0, /* The state has been changed in message->messageParam2 */
206  pInputBuffer->pMarkData);
207  } else {
208  /*If this is not the target component then pass the mark*/
209  omx_base_filter_Private->pMark.hMarkTargetComponent = pInputBuffer->hMarkTargetComponent;
210  omx_base_filter_Private->pMark.pMarkData = pInputBuffer->pMarkData;
211  }
212  pInputBuffer->hMarkTargetComponent = NULL;
213  }
214  }
215 
216  if(isInputBufferNeeded==OMX_FALSE && isOutputBufferNeeded==OMX_FALSE) {
217 
218  if(omx_base_filter_Private->pMark.hMarkTargetComponent != NULL){
219  pOutputBuffer->hMarkTargetComponent = omx_base_filter_Private->pMark.hMarkTargetComponent;
220  pOutputBuffer->pMarkData = omx_base_filter_Private->pMark.pMarkData;
221  omx_base_filter_Private->pMark.hMarkTargetComponent = NULL;
222  omx_base_filter_Private->pMark.pMarkData = NULL;
223  }
224 
225  pOutputBuffer->nTimeStamp = pInputBuffer->nTimeStamp;
226  if((pInputBuffer->nFlags & OMX_BUFFERFLAG_STARTTIME) == OMX_BUFFERFLAG_STARTTIME) {
227  DEBUG(DEB_LEV_FULL_SEQ, "Detected START TIME flag in the input buffer filled len=%d\n", (int)pInputBuffer->nFilledLen);
228  pOutputBuffer->nFlags = pInputBuffer->nFlags;
229  pInputBuffer->nFlags = 0;
230  }
231 
232  if(omx_base_filter_Private->state == OMX_StateExecuting) {
233  if (omx_base_filter_Private->BufferMgmtCallback && pInputBuffer->nFilledLen > 0) {
234  (*(omx_base_filter_Private->BufferMgmtCallback))(openmaxStandComp, pInputBuffer, pOutputBuffer);
235  } else {
236  /*It no buffer management call back the explicitly consume input buffer*/
237  pInputBuffer->nFilledLen = 0;
238  }
239  } else if(!(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
240  DEBUG(DEB_LEV_ERR, "In %s Received Buffer in non-Executing State(%x)\n", __func__, (int)omx_base_filter_Private->state);
241  } else {
242  pInputBuffer->nFilledLen = 0;
243  }
244 
245  if((pInputBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS && pInputBuffer->nFilledLen==0) {
246  DEBUG(DEB_LEV_FULL_SEQ, "Detected EOS flags in input buffer filled len=%d\n", (int)pInputBuffer->nFilledLen);
247  pOutputBuffer->nFlags=pInputBuffer->nFlags;
248  pInputBuffer->nFlags=0;
249  (*(omx_base_filter_Private->callbacks->EventHandler))
250  (openmaxStandComp,
251  omx_base_filter_Private->callbackData,
252  OMX_EventBufferFlag, /* The command was completed */
253  1, /* The commands was a OMX_CommandStateSet */
254  pOutputBuffer->nFlags, /* The state has been changed in message->messageParam2 */
255  NULL);
256  omx_base_filter_Private->bIsEOSReached = OMX_TRUE;
257  }
258  if(omx_base_filter_Private->state==OMX_StatePause && !(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
259  /*Waiting at paused state*/
260  tsem_wait(omx_base_filter_Private->bStateSem);
261  }
262 
263  /*If EOS and Input buffer Filled Len Zero then Return output buffer immediately*/
264  if((pOutputBuffer->nFilledLen != 0) || ((pOutputBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) || (omx_base_filter_Private->bIsEOSReached == OMX_TRUE)) {
265  pOutPort->ReturnBufferFunction(pOutPort,pOutputBuffer);
266  outBufExchanged--;
267  pOutputBuffer=NULL;
268  isOutputBufferNeeded=OMX_TRUE;
269  }
270  }
271 
272  if(omx_base_filter_Private->state==OMX_StatePause && !(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
273  /*Waiting at paused state*/
274  tsem_wait(omx_base_filter_Private->bStateSem);
275  }
276 
277  /*Input Buffer has been completely consumed. So, return input buffer*/
278  if((isInputBufferNeeded == OMX_FALSE) && (pInputBuffer->nFilledLen==0)) {
279  pInPort->ReturnBufferFunction(pInPort,pInputBuffer);
280  inBufExchanged--;
281  pInputBuffer=NULL;
282  isInputBufferNeeded=OMX_TRUE;
283  }
284  }
285  DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s of component %p\n", __func__, openmaxStandComp);
286  return NULL;
287 }
OMX_COMPONENTTYPE::pComponentPrivate
OMX_PTR pComponentPrivate
Definition: OMX_Component.h:326
DEB_LEV_FUNCTION_NAME
#define DEB_LEV_FUNCTION_NAME
Definition: omx_comp_debug_levels.h:59
tsem_up
void tsem_up(tsem_t *tsem)
Definition: tsemaphore.c:110
DEBUG
#define DEBUG(n, fmt, args...)
Definition: omx_comp_debug_levels.h:77
OMX_CALLBACKTYPE::EventHandler
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_base_filter_PrivateType
Definition: omx_base_filter.h:51
OMX_StatePause
Definition: OMX_Core.h:107
DEB_LEV_FULL_SEQ
#define DEB_LEV_FULL_SEQ
Definition: omx_comp_debug_levels.h:54
OMX_ERRORTYPE
OMX_ERRORTYPE
Definition: OMX_Core.h:126
OMX_MARKTYPE::hMarkTargetComponent
OMX_HANDLETYPE hMarkTargetComponent
Definition: OMX_Types.h:299
omx_base_filter_PrivateType::flush_condition
tsem_t * flush_condition
Definition: omx_base_filter.h:57
omx_base_filter_PrivateType::bellagioThreads
OMX_PARAM_BELLAGIOTHREADS_ID * bellagioThreads
Definition: omx_base_filter.h:57
omx_base_filter_Constructor
OMX_ERRORTYPE omx_base_filter_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, OMX_STRING cComponentName)
The base filter contructor for the OpenMAX ST components.
Definition: omx_base_filter.c:36
OMX_TRUE
Definition: OMX_Types.h:191
omx_base_filter_PrivateType::pMark
OMX_MARKTYPE pMark
Definition: omx_base_filter.h:57
OMX_BASE_FILTER_INPUTPORT_INDEX
#define OMX_BASE_FILTER_INPUTPORT_INDEX
Definition: omx_base_filter.h:39
OMX_TransStateLoadedToIdle
Definition: omx_base_component.h:90
omx_base_PortType::pBufferQueue
queue_t * pBufferQueue
Definition: omx_base_port.h:142
DEB_LEV_ERR
#define DEB_LEV_ERR
Definition: omx_comp_debug_levels.h:39
omx_base_filter_BufferMgmtFunction
void * omx_base_filter_BufferMgmtFunction(void *param)
Definition: omx_base_filter.c:85
omx_base_filter_PrivateType::callbackData
OMX_PTR callbackData
Definition: omx_base_filter.h:57
omx_base_filter_PrivateType::flush_all_condition
tsem_t * flush_all_condition
Definition: omx_base_filter.h:57
tsem_down
void tsem_down(tsem_t *tsem)
Definition: tsemaphore.c:97
omxcore.h
OMX_StateInvalid
Definition: OMX_Core.h:94
DEB_LEV_SIMPLE_SEQ
#define DEB_LEV_SIMPLE_SEQ
Definition: omx_comp_debug_levels.h:48
omx_base_filter_PrivateType::callbacks
OMX_CALLBACKTYPE * callbacks
Definition: omx_base_filter.h:57
omx_base_filter_PrivateType::ports
omx_base_PortType ** ports
Definition: omx_base_filter.h:57
tsem_wait
void tsem_wait(tsem_t *tsem)
Definition: tsemaphore.c:131
omx_base_filter_PrivateType::bStateSem
tsem_t * bStateSem
Definition: omx_base_filter.h:57
omx_base_filter_Destructor
OMX_ERRORTYPE omx_base_filter_Destructor(OMX_COMPONENTTYPE *openmaxStandComp)
the base filter destructor for ST OpenMAX components
Definition: omx_base_filter.c:68
OMX_BOOL
OMX_BOOL
Definition: OMX_Types.h:189
OMX_EventMark
Definition: OMX_Core.h:483
queue_t
Definition: queue.h:43
dequeue
void * dequeue(queue_t *queue)
Definition: queue.c:122
omx_base_filter_PrivateType::BufferMgmtFunction
void *(* BufferMgmtFunction)(void *param)
Definition: omx_base_filter.h:57
omx_base_PortType
Definition: omx_base_port.h:105
OMX_ErrorInsufficientResources
Definition: OMX_Core.h:131
OMX_COMPONENTTYPE
Definition: OMX_Component.h:307
OMX_EventBufferFlag
Definition: OMX_Core.h:485
omx_base_filter_PrivateType::state
OMX_STATETYPE state
Definition: omx_base_filter.h:57
tsem_t
Definition: tsemaphore.h:38
OMX_BUFFERFLAG_EOS
#define OMX_BUFFERFLAG_EOS
Definition: OMX_Core.h:299
OSCL_EXPORT_REF
#define OSCL_EXPORT_REF
Definition: omx_base_component.h:43
OMX_StateExecuting
Definition: OMX_Core.h:105
PORT_IS_BEING_FLUSHED
#define PORT_IS_BEING_FLUSHED(pPort)
Definition: omx_base_port.h:39
err
OMX_ERRORTYPE err
Definition: omxvolcontroltest.c:34
OMX_FALSE
Definition: OMX_Types.h:190
omx_base_component_Destructor
OMX_ERRORTYPE omx_base_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp)
The base destructor for ST OpenMAX components.
Definition: omx_base_component.c:271
OMX_STRING
char * OMX_STRING
Definition: OMX_Types.h:206
omx_base_component_Constructor
OMX_ERRORTYPE omx_base_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, OMX_STRING cComponentName)
The base constructor for the OpenMAX ST components.
Definition: omx_base_component.c:95
omx_base_filter_PrivateType::bMgmtSem
tsem_t * bMgmtSem
Definition: omx_base_filter.h:57
OMX_PARAM_BELLAGIOTHREADS_ID::nThreadBufferMngtID
long int nThreadBufferMngtID
Definition: extension_struct.h:37
omx_base_PortType::ReturnBufferFunction
OMX_ERRORTYPE(* ReturnBufferFunction)(omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE *pBuffer)
Definition: omx_base_port.h:142
OMX_BUFFERHEADERTYPE
Definition: OMX_Core.h:398
OMX_ErrorNone
Definition: OMX_Core.h:128
omx_base_filter.h
omx_base_PortType::pBufferSem
tsem_t * pBufferSem
Definition: omx_base_port.h:142
OMX_BUFFERFLAG_STARTTIME
#define OMX_BUFFERFLAG_STARTTIME
Definition: OMX_Core.h:326
omx_base_filter_PrivateType::bIsEOSReached
OMX_BOOL bIsEOSReached
Definition: omx_base_filter.h:57
omx_base_filter_PrivateType::flush_mutex
pthread_mutex_t flush_mutex
Definition: omx_base_filter.h:57
OMX_StateIdle
Definition: OMX_Core.h:102
omx_base_filter_PrivateType::transientState
OMX_TRANS_STATETYPE transientState
Definition: omx_base_filter.h:57
omx_base_filter_PrivateType::BufferMgmtCallback
void(* BufferMgmtCallback)(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE *inputbuffer, OMX_BUFFERHEADERTYPE *outputbuffer)
Definition: omx_base_filter.h:57
OMX_StateLoaded
Definition: OMX_Core.h:97
OMX_MARKTYPE::pMarkData
OMX_PTR pMarkData
Definition: OMX_Types.h:302
OMX_BASE_FILTER_OUTPUTPORT_INDEX
#define OMX_BASE_FILTER_OUTPUTPORT_INDEX
Definition: omx_base_filter.h:43

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