OpenMAX Bellagio 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
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;
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;
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_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_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2, 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