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

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