OpenMAX Bellagio 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
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;
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;
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_ERRORTYPE
Definition OMX_Core.h:127
@ OMX_ErrorInsufficientResources
Definition OMX_Core.h:131
@ OMX_ErrorNone
Definition OMX_Core.h:128
char * OMX_STRING
Definition OMX_Types.h:206
OMX_BOOL
Definition OMX_Types.h:189
@ OMX_TRUE
Definition OMX_Types.h:191
@ OMX_FALSE
Definition OMX_Types.h:190
#define OMX_BUFFERFLAG_EOS
Definition OMX_Core.h:299
#define OMX_BUFFERFLAG_STARTTIME
Definition OMX_Core.h:326
@ OMX_StateExecuting
Definition OMX_Core.h:105
@ 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_EventMark
Definition OMX_Core.h:483
@ OMX_EventBufferFlag
Definition OMX_Core.h:485
OMX_ERRORTYPE omx_base_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, OMX_STRING cComponentName)
The base constructor for the OpenMAX ST components.
OMX_ERRORTYPE omx_base_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp)
The base destructor for ST OpenMAX components.
#define OSCL_EXPORT_REF
@ OMX_TransStateLoadedToIdle
void * omx_base_filter_BufferMgmtFunction(void *param)
OMX_ERRORTYPE omx_base_filter_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, OMX_STRING cComponentName)
The base filter contructor for the OpenMAX ST components.
OMX_ERRORTYPE omx_base_filter_Destructor(OMX_COMPONENTTYPE *openmaxStandComp)
the base filter destructor for ST OpenMAX components
#define OMX_BASE_FILTER_INPUTPORT_INDEX
#define OMX_BASE_FILTER_OUTPUTPORT_INDEX
#define PORT_IS_BEING_FLUSHED(pPort)
#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
void * dequeue(queue_t *queue)
Definition queue.c:122
OMX_TICKS nTimeStamp
Definition OMX_Core.h:431
OMX_HANDLETYPE hMarkTargetComponent
Definition OMX_Core.h:417
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_HANDLETYPE hMarkTargetComponent
Definition OMX_Types.h:299
OMX_PTR pMarkData
Definition OMX_Types.h:302
OMX_ERRORTYPE(* ReturnBufferFunction)(omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE *pBuffer)
omx_base_PortType ** ports
OMX_PARAM_BELLAGIOTHREADS_ID * bellagioThreads
void(* BufferMgmtCallback)(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE *inputbuffer, OMX_BUFFERHEADERTYPE *outputbuffer)
OMX_TRANS_STATETYPE transientState
OMX_CALLBACKTYPE * callbacks
void *(* BufferMgmtFunction)(void *param)
int nelem
Definition queue.h:46
unsigned int semval
Definition tsemaphore.h:41
void tsem_up(tsem_t *tsem)
Definition tsemaphore.c:110
void tsem_down(tsem_t *tsem)
Definition tsemaphore.c:97
void tsem_wait(tsem_t *tsem)
Definition tsemaphore.c:131

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