OpenMAX Bellagio 0.9.3
omx_video_scheduler_component.c
Go to the documentation of this file.
1
26#include <omxcore.h>
28
29#define DEFAULT_WIDTH 352
30#define DEFAULT_HEIGHT 288
31#define CLOCKPORT_INDEX 2
32
34#define DEFAULT_VIDEO_INPUT_BUF_SIZE DEFAULT_WIDTH*DEFAULT_HEIGHT*3/2
35
42 omx_video_scheduler_component_PrivateType* omx_video_scheduler_component_Private;
43 omx_base_video_PortType *inPort,*outPort;
44 OMX_U32 i;
45
46
48 if (!openmaxStandComp->pComponentPrivate) {
49 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, allocating component\n", __func__);
50 openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_video_scheduler_component_PrivateType));
51 if(openmaxStandComp->pComponentPrivate == NULL) {
53 }
54 } else {
55 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, Error Component %p Already Allocated\n", __func__, openmaxStandComp->pComponentPrivate);
56 }
57
58 omx_video_scheduler_component_Private = openmaxStandComp->pComponentPrivate;
59 omx_video_scheduler_component_Private->ports = NULL;
60
64 err = omx_base_filter_Constructor(openmaxStandComp, cComponentName);
65
66 omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainVideo].nStartPortNumber = 0;
67 omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts = 2;
68
69 omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainOther].nStartPortNumber = CLOCKPORT_INDEX;
70 omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts = 1;
71
73 if ((omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts
74 + omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts)
75 && !omx_video_scheduler_component_Private->ports) {
76 omx_video_scheduler_component_Private->ports = calloc((omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts
77 + omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts),
78 sizeof(omx_base_PortType *));
79 if (!omx_video_scheduler_component_Private->ports) {
81 }
82 for (i=0; i < omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts; i++) {
83 omx_video_scheduler_component_Private->ports[i] = calloc(1, sizeof(omx_base_video_PortType));
84 if (!omx_video_scheduler_component_Private->ports[i]) {
86 }
87 }
88 base_video_port_Constructor(openmaxStandComp, &omx_video_scheduler_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX], 0, OMX_TRUE);
89 base_video_port_Constructor(openmaxStandComp, &omx_video_scheduler_component_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX], 1, OMX_FALSE);
90
91 omx_video_scheduler_component_Private->ports[CLOCKPORT_INDEX] = calloc(1, sizeof(omx_base_clock_PortType));
92 if (!omx_video_scheduler_component_Private->ports[CLOCKPORT_INDEX]) {
94 }
95 base_clock_port_Constructor(openmaxStandComp, &omx_video_scheduler_component_Private->ports[CLOCKPORT_INDEX], 2, OMX_TRUE);
96 omx_video_scheduler_component_Private->ports[CLOCKPORT_INDEX]->sPortParam.bEnabled = OMX_TRUE;
97 }
98
99 inPort = (omx_base_video_PortType *) omx_video_scheduler_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
100 outPort= (omx_base_video_PortType *) omx_video_scheduler_component_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
101
104 //input port parameter settings
110
116
117 omx_video_scheduler_component_Private->destructor = omx_video_scheduler_component_Destructor;
118 omx_video_scheduler_component_Private->BufferMgmtCallback = omx_video_scheduler_component_BufferMgmtCallback;
119
123
124 /* resource management special section */
125 omx_video_scheduler_component_Private->nqualitylevels = VIDEOSCHED_QUALITY_LEVELS;
126 omx_video_scheduler_component_Private->currentQualityLevel = 1;
127 omx_video_scheduler_component_Private->multiResourceLevel = malloc(sizeof(multiResourceDescriptor *) * VIDEOSCHED_QUALITY_LEVELS);
128 for (i = 0; i<VIDEOSCHED_QUALITY_LEVELS; i++) {
129 omx_video_scheduler_component_Private->multiResourceLevel[i] = malloc(sizeof(multiResourceDescriptor));
130 omx_video_scheduler_component_Private->multiResourceLevel[i]->CPUResourceRequested = videoSchedQualityLevels[i * 2];
131 omx_video_scheduler_component_Private->multiResourceLevel[i]->MemoryResourceRequested = videoSchedQualityLevels[i * 2 + 1];
132 }
133
134 return err;
135}
136
140 omx_video_scheduler_component_PrivateType* omx_video_scheduler_component_Private = openmaxStandComp->pComponentPrivate;
141 OMX_U32 i;
142
143 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
144
145 /* frees port/s */
146 if (omx_video_scheduler_component_Private->ports) {
147 for(i=0; i < (omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts +
148 omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts); i++) {
149 if(omx_video_scheduler_component_Private->ports[i])
150 omx_video_scheduler_component_Private->ports[i]->PortDestructor(omx_video_scheduler_component_Private->ports[i]);
151 }
152 free(omx_video_scheduler_component_Private->ports);
153 omx_video_scheduler_component_Private->ports=NULL;
154 }
155
156 omx_base_filter_Destructor(openmaxStandComp);
157 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
158
159 return OMX_ErrorNone;
160}
161
162
169
171 int errQue;
172 OMX_U32 portIndex;
173 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
174 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
175 OMX_BOOL SendFrame;
176 omx_base_clock_PortType* pClockPort;
177#if NO_GST_OMX_PATCH
178 unsigned int i;
179#endif
180
181 portIndex = (openmaxStandPort->sPortParam.eDir == OMX_DirInput)?pBuffer->nInputPortIndex:pBuffer->nOutputPortIndex;
182 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s portIndex %lu\n", __func__, portIndex);
183
184 if (portIndex != openmaxStandPort->sPortParam.nPortIndex) {
185 DEBUG(DEB_LEV_ERR, "In %s: wrong port for this operation portIndex=%d port->portIndex=%d\n",
186 __func__, (int)portIndex, (int)openmaxStandPort->sPortParam.nPortIndex);
188 }
189
190 if(omx_base_component_Private->state == OMX_StateInvalid) {
191 DEBUG(DEB_LEV_ERR, "In %s: we are in OMX_StateInvalid\n", __func__);
193 }
194
195 if(omx_base_component_Private->state != OMX_StateExecuting &&
196 omx_base_component_Private->state != OMX_StatePause &&
197 omx_base_component_Private->state != OMX_StateIdle) {
198 DEBUG(DEB_LEV_ERR, "In %s: we are not in executing/paused/idle state, but in %d\n", __func__, omx_base_component_Private->state);
200 }
201 if (!PORT_IS_ENABLED(openmaxStandPort) || (PORT_IS_BEING_DISABLED(openmaxStandPort) && !PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) ||
202 (omx_base_component_Private->transientState == OMX_TransStateExecutingToIdle &&
203 (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)))) {
204 DEBUG(DEB_LEV_ERR, "In %s: Port %d is disabled comp = %s \n", __func__, (int)portIndex,omx_base_component_Private->name);
206 }
207
208 /* Temporarily disable this check for gst-openmax */
209#if NO_GST_OMX_PATCH
210 {
211 OMX_BOOL foundBuffer = OMX_FALSE;
212 if(pBuffer!=NULL && pBuffer->pBuffer!=NULL) {
213 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
214 if (pBuffer->pBuffer == openmaxStandPort->pInternalBufferStorage[i]->pBuffer) {
215 foundBuffer = OMX_TRUE;
216 break;
217 }
218 }
219 }
220 if (!foundBuffer) {
222 }
223 }
224#endif
225
226 if ((err = checkHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE))) != OMX_ErrorNone) {
227 DEBUG(DEB_LEV_ERR, "In %s: received wrong buffer header on input port\n", __func__);
228 return err;
229 }
230
231 pClockPort = (omx_base_clock_PortType*)omx_base_component_Private->ports[CLOCKPORT_INDEX];
232 if(PORT_IS_TUNNELED(pClockPort) && !PORT_IS_BEING_FLUSHED(openmaxStandPort) &&
233 (omx_base_component_Private->transientState != OMX_TransStateExecutingToIdle) &&
235 SendFrame = omx_video_scheduler_component_ClockPortHandleFunction((omx_video_scheduler_component_PrivateType*)omx_base_component_Private, pBuffer);
236 if(!SendFrame) pBuffer->nFilledLen=0;
237 }
238
239 /* And notify the buffer management thread we have a fresh new buffer to manage */
240 if(!PORT_IS_BEING_FLUSHED(openmaxStandPort) && !(PORT_IS_BEING_DISABLED(openmaxStandPort) && PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort))
241 && omx_base_component_Private->transientState != OMX_TransStateExecutingToIdle){
242 errQue = queue(openmaxStandPort->pBufferQueue, pBuffer);
243 if (errQue) {
244 /* /TODO the queue is full. This can be handled in a fine way with
245 * some retrials, or other checking. For the moment this is a critical error
246 * and simply causes the failure of this call
247 */
249 }
250 tsem_up(openmaxStandPort->pBufferSem);
251 DEBUG(DEB_LEV_FULL_SEQ, "In %s Signalling bMgmtSem Port Index=%d\n",__func__, (int)portIndex);
252 tsem_up(omx_base_component_Private->bMgmtSem);
253 }else if(PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)){
254 DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s received io:%d buffer\n", __func__,omx_base_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex);
255 errQue = queue(openmaxStandPort->pBufferQueue, pBuffer);
256 if (errQue) {
257 /* /TODO the queue is full. This can be handled in a fine way with
258 * some retrials, or other checking. For the moment this is a critical error
259 * and simply causes the failure of this call
260 */
262 }
263 tsem_up(openmaxStandPort->pBufferSem);
264 } else { // If port being flushed and not tunneled then return error
265 DEBUG(DEB_LEV_FULL_SEQ, "In %s \n", __func__);
267 }
268 return OMX_ErrorNone;
269}
270
271
273 omx_video_scheduler_component_PrivateType* omx_video_scheduler_component_Private,
274 OMX_BUFFERHEADERTYPE* pInputBuffer){
275 omx_base_clock_PortType *pClockPort;
276 OMX_HANDLETYPE hclkComponent;
277 OMX_BUFFERHEADERTYPE* clockBuffer;
278 OMX_TIME_MEDIATIMETYPE* pMediaTime;
279 OMX_TIME_CONFIG_TIMESTAMPTYPE sClientTimeStamp;
281 OMX_BOOL SendFrame;
282 omx_base_video_PortType *pInputPort;
283
284 pClockPort = (omx_base_clock_PortType*) omx_video_scheduler_component_Private->ports[CLOCKPORT_INDEX];
285 pInputPort = (omx_base_video_PortType *) omx_video_scheduler_component_Private->ports[0];
286 hclkComponent = pClockPort->hTunneledComponent;
287
288 SendFrame = OMX_TRUE;
289
290 DEBUG(DEB_LEV_FULL_SEQ, "In %s Clock Port is Tunneled. Sending Request\n", __func__);
291 /* if first time stamp is received then notify the clock component */
293 DEBUG(DEB_LEV_FULL_SEQ," In %s first time stamp = %llx \n", __func__,pInputBuffer->nTimeStamp);
294 pInputBuffer->nFlags = 0;
295 hclkComponent = pClockPort->hTunneledComponent;
296 setHeader(&sClientTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
297 sClientTimeStamp.nPortIndex = pClockPort->nTunneledPort;
298 sClientTimeStamp.nTimestamp = pInputBuffer->nTimeStamp;
299 err = OMX_SetConfig(hclkComponent, OMX_IndexConfigTimeClientStartTime, &sClientTimeStamp);
300 if(err!=OMX_ErrorNone) {
301 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
302 }
303 tsem_down(pClockPort->pBufferSem); /* wait for state change notification */
304
305 /* update the clock state and clock scale info into the fbdev private data */
306 if(pClockPort->pBufferQueue->nelem > 0) {
307 clockBuffer=dequeue(pClockPort->pBufferQueue);
308 pMediaTime = (OMX_TIME_MEDIATIMETYPE*)clockBuffer->pBuffer;
309 omx_video_scheduler_component_Private->eState = pMediaTime->eState;
310 omx_video_scheduler_component_Private->xScale = pMediaTime->xScale;
311 pClockPort->ReturnBufferFunction((omx_base_PortType*)pClockPort,clockBuffer);
312 }
313 }
314
315 /* do not send the data to sink and return back, if the clock is not running*/
316 if(!omx_video_scheduler_component_Private->eState==OMX_TIME_ClockStateRunning){
317 pInputBuffer->nFilledLen=0;
318 SendFrame = OMX_FALSE;
319 return SendFrame;
320 }
321
322 /* check for any scale change information from the clock component */
323 if(pClockPort->pBufferSem->semval>0) {
324 tsem_down(pClockPort->pBufferSem);
325 if(pClockPort->pBufferQueue->nelem > 0) {
326 clockBuffer = dequeue(pClockPort->pBufferQueue);
327 pMediaTime = (OMX_TIME_MEDIATIMETYPE*)clockBuffer->pBuffer;
329 /* On scale change update the media time base */
330 sClientTimeStamp.nPortIndex = pClockPort->nTunneledPort;
331 sClientTimeStamp.nTimestamp = pInputBuffer->nTimeStamp;
332 err = OMX_SetConfig(hclkComponent, OMX_IndexConfigTimeCurrentVideoReference, &sClientTimeStamp);
333 if(err!=OMX_ErrorNone) {
334 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
335 }
336 omx_video_scheduler_component_Private->frameDropFlag = OMX_TRUE;
337 omx_video_scheduler_component_Private->dropFrameCount = 0;
338 omx_video_scheduler_component_Private->xScale = pMediaTime->xScale;
339 }
340 pClockPort->ReturnBufferFunction((omx_base_PortType*)pClockPort,clockBuffer);
341 }
342 }
343
344 /* drop next seven frames on scale change
345 and rebase the clock time base */
346 if(omx_video_scheduler_component_Private->frameDropFlag && omx_video_scheduler_component_Private->dropFrameCount<7) { //TODO - second check cond can be removed verify
347 omx_video_scheduler_component_Private->dropFrameCount ++;
348 if(omx_video_scheduler_component_Private->dropFrameCount==7) {
349 /* rebase the clock time base */
350 setHeader(&sClientTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
351 sClientTimeStamp.nPortIndex = pClockPort->nTunneledPort;
352 sClientTimeStamp.nTimestamp = pInputBuffer->nTimeStamp;
353 err = OMX_SetConfig(hclkComponent, OMX_IndexConfigTimeCurrentVideoReference, &sClientTimeStamp);
354 if(err!=OMX_ErrorNone) {
355 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
356 }
357
358 omx_video_scheduler_component_Private->frameDropFlag = OMX_FALSE;
359 omx_video_scheduler_component_Private->dropFrameCount = 0;
360 SendFrame = OMX_TRUE;
361 }
362 SendFrame = OMX_FALSE;
363 }
364
365 /* frame is not to be dropped so send the request for the timestamp for the data delivery */
366 if(SendFrame){
367 if(!PORT_IS_BEING_FLUSHED(pInputPort) && !PORT_IS_BEING_FLUSHED(pClockPort) &&
368 omx_video_scheduler_component_Private->transientState != OMX_TransStateExecutingToIdle) {
370 pClockPort->sMediaTimeRequest.nMediaTimestamp = pInputBuffer->nTimeStamp;
371 pClockPort->sMediaTimeRequest.nOffset = 100; /*set the requested offset */
372 pClockPort->sMediaTimeRequest.nPortIndex = pClockPort->nTunneledPort;
373 pClockPort->sMediaTimeRequest.pClientPrivate = NULL; /* fill the appropriate value */
375 if(err!=OMX_ErrorNone) {
376 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
377 }
378 if(!PORT_IS_BEING_FLUSHED(pInputPort) && !PORT_IS_BEING_FLUSHED(pClockPort) &&
379 omx_video_scheduler_component_Private->transientState != OMX_TransStateExecutingToIdle) {
380 tsem_down(pClockPort->pBufferSem); /* wait for the request fullfillment */
381 if(pClockPort->pBufferQueue->nelem > 0) {
382 clockBuffer = dequeue(pClockPort->pBufferQueue);
383 pMediaTime = (OMX_TIME_MEDIATIMETYPE*)clockBuffer->pBuffer;
385 /* update the media time base */
386 setHeader(&sClientTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE)); // do not need to setHeader again do once at the top
387 sClientTimeStamp.nPortIndex = pClockPort->nTunneledPort;
388 sClientTimeStamp.nTimestamp = pInputBuffer->nTimeStamp;
389 err = OMX_SetConfig(hclkComponent, OMX_IndexConfigTimeCurrentVideoReference, &sClientTimeStamp);
390 if(err!=OMX_ErrorNone) {
391 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
392 }
393 omx_video_scheduler_component_Private->frameDropFlag = OMX_TRUE;
394 omx_video_scheduler_component_Private->dropFrameCount = 0;
395 omx_video_scheduler_component_Private->xScale = pMediaTime->xScale;
396 }
398 if((pMediaTime->nOffset)>0) {
399 SendFrame=OMX_TRUE;
400 }else {
401 SendFrame = OMX_FALSE;
402 }
403 }
404 pClockPort->ReturnBufferFunction((omx_base_PortType *)pClockPort,clockBuffer);
405 }
406 }
407 }
408 }
409 return(SendFrame);
410}
411
412
418 omx_base_component_PrivateType* omx_base_component_Private;
419 omx_video_scheduler_component_PrivateType* omx_video_scheduler_component_Private;
420 OMX_BUFFERHEADERTYPE* pBuffer;
421 omx_base_clock_PortType *pClockPort;
422 int errQue;
423
424 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
425 omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate;
426 omx_video_scheduler_component_Private = ( omx_video_scheduler_component_PrivateType*) omx_base_component_Private;
427
428 pClockPort = (omx_base_clock_PortType*) omx_video_scheduler_component_Private->ports[CLOCKPORT_INDEX];
429
430 if(openmaxStandPort->sPortParam.eDomain!=OMX_PortDomainOther) { /* clock buffers not used in the clients buffer managment function */
431 pthread_mutex_lock(&omx_base_component_Private->flush_mutex);
432 openmaxStandPort->bIsPortFlushed=OMX_TRUE;
433 /*Signal the buffer management thread of port flush,if it is waiting for buffers*/
434 if(omx_base_component_Private->bMgmtSem->semval==0) {
435 tsem_up(omx_base_component_Private->bMgmtSem);
436 }
437
438 if(omx_base_component_Private->state != OMX_StateExecuting ) {
439 /*signal at non-executing state*/
440 tsem_signal(omx_base_component_Private->bStateSem);
441 }
442 DEBUG(DEB_LEV_FULL_SEQ, "In %s waiting for flush all condition port index =%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);
443 /* Wait until flush is completed */
444 pthread_mutex_unlock(&omx_base_component_Private->flush_mutex);
445
446 /*Dummy signal to clock port*/
447 if(pClockPort->pBufferSem->semval == 0) {
448 tsem_up(pClockPort->pBufferSem);
449 tsem_reset(pClockPort->pBufferSem);
450 }
451 tsem_down(omx_base_component_Private->flush_all_condition);
452 }
453
454 tsem_reset(omx_base_component_Private->bMgmtSem);
455
456 /* Flush all the buffers not under processing */
457 while (openmaxStandPort->pBufferSem->semval > 0) {
458 DEBUG(DEB_LEV_FULL_SEQ, "In %s TFlag=%x Flusing Port=%d,Semval=%d Qelem=%d\n",
459 __func__,(int)openmaxStandPort->nTunnelFlags,(int)openmaxStandPort->sPortParam.nPortIndex,
460 (int)openmaxStandPort->pBufferSem->semval,(int)openmaxStandPort->pBufferQueue->nelem);
461
462 tsem_down(openmaxStandPort->pBufferSem);
463 pBuffer = dequeue(openmaxStandPort->pBufferQueue);
464 if (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
465 DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s is returning io:%d buffer\n",
466 __func__,omx_base_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex);
467 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
468 ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
469 } else {
470 ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
471 }
472 } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
473 errQue = queue(openmaxStandPort->pBufferQueue,pBuffer);
474 if (errQue) {
475 /* /TODO the queue is full. This can be handled in a fine way with
476 * some retrials, or other checking. For the moment this is a critical error
477 * and simply causes the failure of this call
478 */
480 }
481 } else {
482 (*(openmaxStandPort->BufferProcessedCallback))(
483 openmaxStandPort->standCompContainer,
484 omx_base_component_Private->callbackData,
485 pBuffer);
486 }
487 }
488 /*Port is tunneled and supplier and didn't received all it's buffer then wait for the buffers*/
489 if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
490 while(openmaxStandPort->pBufferQueue->nelem!= openmaxStandPort->nNumAssignedBuffers){
491 tsem_down(openmaxStandPort->pBufferSem);
492 DEBUG(DEB_LEV_PARAMS, "In %s Got a buffer qelem=%d\n",__func__,openmaxStandPort->pBufferQueue->nelem);
493 }
494 tsem_reset(openmaxStandPort->pBufferSem);
495 }
496
497 pthread_mutex_lock(&omx_base_component_Private->flush_mutex);
498 openmaxStandPort->bIsPortFlushed=OMX_FALSE;
499 pthread_mutex_unlock(&omx_base_component_Private->flush_mutex);
500
501 tsem_up(omx_base_component_Private->flush_condition);
502
503 DEBUG(DEB_LEV_FULL_SEQ, "Out %s Port Index=%d bIsPortFlushed=%d Component %s\n", __func__,
504 (int)openmaxStandPort->sPortParam.nPortIndex,(int)openmaxStandPort->bIsPortFlushed,omx_base_component_Private->name);
505
506 DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__,
507 (int)openmaxStandPort->nTunnelFlags,
508 (int)openmaxStandPort->pBufferQueue->nelem,
509 (int)openmaxStandPort->pBufferSem->semval,
510 (int)omx_base_component_Private->bMgmtSem->semval,
511 omx_base_component_Private->name);
512
513 DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port Index=%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);
514
515 return OMX_ErrorNone;
516}
517
521
522 omx_video_scheduler_component_PrivateType* omx_video_scheduler_component_Private = openmaxStandComp->pComponentPrivate;
523 omx_base_video_PortType *inPort = (omx_base_video_PortType *)omx_video_scheduler_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
524 omx_base_clock_PortType* pClockPort;
525 OMX_BOOL SendFrame;
526
527 pClockPort = (omx_base_clock_PortType*)omx_video_scheduler_component_Private->ports[CLOCKPORT_INDEX];
528 if(PORT_IS_TUNNELED(pClockPort) && !PORT_IS_BEING_FLUSHED(inPort) &&
529 (omx_video_scheduler_component_Private->transientState != OMX_TransStateExecutingToIdle) &&
530 ((pInputBuffer->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)){
531 SendFrame = omx_video_scheduler_component_ClockPortHandleFunction(omx_video_scheduler_component_Private, pInputBuffer);
532 if(!SendFrame) pInputBuffer->nFilledLen = 0;
533 }
534
535 if((pInputBuffer->pBuffer != pOutputBuffer->pBuffer) && (pInputBuffer->nFilledLen > 0)){
536 memcpy(pOutputBuffer->pBuffer,pInputBuffer->pBuffer,pInputBuffer->nFilledLen);
537 pOutputBuffer->nOffset = pInputBuffer->nOffset;
538 }
539 pOutputBuffer->nFilledLen = pInputBuffer->nFilledLen;
540 pInputBuffer->nFilledLen=0;
541}
542
543
544
546 OMX_HANDLETYPE hComponent,
547 OMX_INDEXTYPE nParamIndex,
548 OMX_PTR ComponentParameterStructure) {
549
552 OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;
553 OMX_OTHER_PARAM_PORTFORMATTYPE *pOtherPortFormat;
554 OMX_U32 portIndex;
555 OMX_PARAM_COMPONENTROLETYPE *pComponentRole;
556
557 /* Check which structure we are being fed and make control its header */
558 OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
559 omx_video_scheduler_component_PrivateType* omx_video_scheduler_component_Private = openmaxStandComp->pComponentPrivate;
561 omx_base_clock_PortType *pClockPort;
562
563 if (ComponentParameterStructure == NULL) {
565 }
566
567 DEBUG(DEB_LEV_SIMPLE_SEQ, " Setting parameter %i\n", nParamIndex);
568 switch(nParamIndex) {
570 pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE*) ComponentParameterStructure;
571 portIndex = pPortDef->nPortIndex;
572 err = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
573 if(err!=OMX_ErrorNone) {
574 DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err);
575 break;
576 }
577
578 if(portIndex > (omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts +
579 omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts)) {
581 }
582
583 if(portIndex < CLOCKPORT_INDEX) {
584 pPort = (omx_base_video_PortType *) omx_video_scheduler_component_Private->ports[portIndex];
586 // Copy stuff from OMX_VIDEO_PORTDEFINITIONTYPE structure
587 if(pPortDef->format.video.cMIMEType != NULL) {
588 strcpy(pPort->sPortParam.format.video.cMIMEType , pPortDef->format.video.cMIMEType);
589 }
595
596 // Figure out stride, slice height, min buffer size
597 pPort->sPortParam.format.video.nStride = pPortDef->format.video.nStride;
598 pPort->sPortParam.format.video.nSliceHeight = pPort->sPortParam.format.video.nFrameHeight; // No support for slices yet
599 // Read-only field by spec
600
602 } else {
603 pClockPort = (omx_base_clock_PortType *) omx_video_scheduler_component_Private->ports[portIndex];
604
605 pClockPort->sPortParam.nBufferCountActual = pPortDef->nBufferCountActual;
606 pClockPort->sPortParam.format.other.eFormat = pPortDef->format.other.eFormat;
607 }
608 break;
609
611 // FIXME: How do we handle the nIndex member?
612 pVideoPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
613 portIndex = pVideoPortFormat->nPortIndex;
614 err = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pVideoPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
615 if(err!=OMX_ErrorNone) {
616 DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err);
617 break;
618 }
619 pPort = (omx_base_video_PortType *) omx_video_scheduler_component_Private->ports[portIndex];
620 if(portIndex > 1) {
622 }
623 if (pVideoPortFormat->eCompressionFormat != OMX_VIDEO_CodingUnused) {
624 // No compression allowed
626 }
627
628 pPort->sVideoParam.xFramerate = pVideoPortFormat->xFramerate;
629 pPort->sVideoParam.eCompressionFormat = pVideoPortFormat->eCompressionFormat;
630 pPort->sVideoParam.eColorFormat = pVideoPortFormat->eColorFormat;
631 break;
633 pOtherPortFormat = (OMX_OTHER_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
634 portIndex = pOtherPortFormat->nPortIndex;
635 err = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pOtherPortFormat, sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE));
636 if(err!=OMX_ErrorNone) {
637 DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err);
638 break;
639 }
640 if(portIndex != CLOCKPORT_INDEX) {
642 }
643 pClockPort = (omx_base_clock_PortType *) omx_video_scheduler_component_Private->ports[portIndex];
644
645 pClockPort->sOtherParam.eFormat = pOtherPortFormat->eFormat;
646 break;
647
649 pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)ComponentParameterStructure;
650
651 if (omx_video_scheduler_component_Private->state != OMX_StateLoaded && omx_video_scheduler_component_Private->state != OMX_StateWaitForResources) {
652 DEBUG(DEB_LEV_ERR, "In %s Incorrect State=%x lineno=%d\n",__func__,omx_video_scheduler_component_Private->state,__LINE__);
654 }
655
656 if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_COMPONENTROLETYPE))) != OMX_ErrorNone) {
657 break;
658 }
659
660 if (strcmp( (char*) pComponentRole->cRole, VIDEO_SCHEDULER_COMP_ROLE)) {
662 }
663 break;
664
665 default: /*Call the base component function*/
666 return omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
667 }
668 return err;
669}
670
672 OMX_HANDLETYPE hComponent,
673 OMX_INDEXTYPE nParamIndex,
674 OMX_PTR ComponentParameterStructure) {
675
676 OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;
677 OMX_OTHER_PARAM_PORTFORMATTYPE *pOtherPortFormat;
679 OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
680 omx_video_scheduler_component_PrivateType* omx_video_scheduler_component_Private = openmaxStandComp->pComponentPrivate;
682 omx_base_clock_PortType *pClockPort = (omx_base_clock_PortType *) omx_video_scheduler_component_Private->ports[CLOCKPORT_INDEX];
683 OMX_PARAM_COMPONENTROLETYPE *pComponentRole;
684
685 if (ComponentParameterStructure == NULL) {
687 }
688 DEBUG(DEB_LEV_SIMPLE_SEQ, " Getting parameter %i\n", nParamIndex);
689 /* Check which structure we are being fed and fill its header */
690 switch(nParamIndex) {
692 if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) {
693 break;
694 }
695 memcpy(ComponentParameterStructure, &omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainVideo], sizeof(OMX_PORT_PARAM_TYPE));
696 break;
698 if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) {
699 break;
700 }
701 memcpy(ComponentParameterStructure, &omx_video_scheduler_component_Private->sPortTypesParam[OMX_PortDomainOther], sizeof(OMX_PORT_PARAM_TYPE));
702 break;
704 pVideoPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
705 pPort = (omx_base_video_PortType *) omx_video_scheduler_component_Private->ports[pVideoPortFormat->nPortIndex];
706 if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) {
707 break;
708 }
709 if (pVideoPortFormat->nPortIndex < CLOCKPORT_INDEX) {
710 memcpy(pVideoPortFormat, &pPort->sVideoParam, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
711 } else {
713 }
714 break;
716 pOtherPortFormat = (OMX_OTHER_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
717 if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) {
718 break;
719 }
720 if (pOtherPortFormat->nPortIndex == CLOCKPORT_INDEX) {
721 memcpy(pOtherPortFormat, &pClockPort->sOtherParam, sizeof(OMX_OTHER_PARAM_PORTFORMATTYPE));
722 } else {
724 }
725 break;
726
728 pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)ComponentParameterStructure;
729 if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_COMPONENTROLETYPE))) != OMX_ErrorNone) {
730 break;
731 }
732 strcpy( (char*) pComponentRole->cRole, VIDEO_SCHEDULER_COMP_ROLE);
733 break;
734
735 default: /*Call the base component function*/
736 return omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
737 }
738 return err;
739}
740
OMX_ERRORTYPE
Definition: OMX_Core.h:127
@ OMX_ErrorInvalidState
Definition: OMX_Core.h:162
@ OMX_ErrorUnsupportedSetting
Definition: OMX_Core.h:218
@ OMX_ErrorInsufficientResources
Definition: OMX_Core.h:131
@ OMX_ErrorBadPortIndex
Definition: OMX_Core.h:224
@ OMX_ErrorNone
Definition: OMX_Core.h:128
@ OMX_ErrorBadParameter
Definition: OMX_Core.h:147
@ OMX_ErrorIncorrectStateOperation
Definition: OMX_Core.h:215
OMX_INDEXTYPE
Definition: OMX_Index.h:60
@ OMX_IndexConfigTimeCurrentVideoReference
Definition: OMX_Index.h:234
@ OMX_IndexParamVideoInit
Definition: OMX_Index.h:66
@ OMX_IndexConfigTimeClientStartTime
Definition: OMX_Index.h:236
@ OMX_IndexParamStandardComponentRole
Definition: OMX_Index.h:85
@ OMX_IndexParamPortDefinition
Definition: OMX_Index.h:88
@ OMX_IndexParamOtherPortFormat
Definition: OMX_Index.h:221
@ OMX_IndexParamOtherInit
Definition: OMX_Index.h:67
@ OMX_IndexParamVideoPortFormat
Definition: OMX_Index.h:155
@ OMX_IndexConfigTimeMediaTimeRequest
Definition: OMX_Index.h:235
@ OMX_TIME_UpdateRequestFulfillment
Definition: OMX_Other.h:122
@ OMX_TIME_UpdateScaleChanged
Definition: OMX_Other.h:123
@ OMX_TIME_ClockStateRunning
Definition: OMX_Other.h:142
unsigned long OMX_U32
Definition: OMX_Types.h:145
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
void * OMX_PTR
Definition: OMX_Types.h:199
void * OMX_HANDLETYPE
Definition: OMX_Types.h:295
@ OMX_DirInput
Definition: OMX_Types.h:226
#define OMX_BUFFERFLAG_EOS
Definition: OMX_Core.h:299
#define OMX_BUFFERFLAG_STARTTIME
Definition: OMX_Core.h:326
#define OMX_SetConfig( hComponent, nConfigIndex, pComponentConfigStructure)
Definition: OMX_Core.h:897
@ OMX_PortDomainVideo
Definition: OMX_Component.h:52
@ OMX_PortDomainOther
Definition: OMX_Component.h:54
@ OMX_StateExecuting
Definition: OMX_Core.h:105
@ OMX_StateWaitForResources
Definition: OMX_Core.h:108
@ 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_COLOR_Format24bitRGB888
Definition: OMX_IVCommon.h:100
@ OMX_VIDEO_CodingUnused
Definition: OMX_Video.h:62
OMX_ERRORTYPE base_clock_port_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, omx_base_PortType **openmaxStandPort, OMX_U32 nPortIndex, OMX_BOOL isInput)
the base constructor for the generic OpenMAX ST Clock port
OMX_ERRORTYPE omx_base_component_SetParameter(OMX_HANDLETYPE hComponent, OMX_INDEXTYPE nParamIndex, OMX_PTR ComponentParameterStructure)
Part of the standard OpenMAX function.
OMX_ERRORTYPE omx_base_component_ParameterSanityCheck(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex, OMX_PTR pStructure, size_t size)
void setHeader(OMX_PTR header, OMX_U32 size)
Simply fills the first two fields in any OMX structure with the size and the version.
OMX_ERRORTYPE omx_base_component_GetParameter(OMX_HANDLETYPE hComponent, OMX_INDEXTYPE nParamIndex, OMX_PTR ComponentParameterStructure)
Part of the standard OpenMAX function.
OMX_ERRORTYPE checkHeader(OMX_PTR header, OMX_U32 size)
Checks the header of a structure for consistency with size and spec version.
@ OMX_TransStateExecutingToIdle
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_TUNNELED_N_BUFFER_SUPPLIER(pPort)
Definition: omx_base_port.h:46
#define PORT_IS_BUFFER_SUPPLIER(pPort)
Definition: omx_base_port.h:45
#define PORT_IS_TUNNELED(pPort)
Definition: omx_base_port.h:43
#define PORT_IS_BEING_DISABLED(pPort)
Definition: omx_base_port.h:40
#define PORT_IS_ENABLED(pPort)
Definition: omx_base_port.h:41
#define PORT_IS_BEING_FLUSHED(pPort)
Definition: omx_base_port.h:39
OMX_ERRORTYPE base_video_port_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, omx_base_PortType **openmaxStandPort, OMX_U32 nPortIndex, OMX_BOOL isInput)
The base contructor for the generic OpenMAX ST Video port.
#define DEB_LEV_PARAMS
#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 RM_RegisterComponent(char *name, int max_components)
#define CLOCKPORT_INDEX
#define DEFAULT_HEIGHT
void omx_video_scheduler_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE *pInputBuffer, OMX_BUFFERHEADERTYPE *pOutputBuffer)
OMX_BOOL omx_video_scheduler_component_ClockPortHandleFunction(omx_video_scheduler_component_PrivateType *omx_video_scheduler_component_Private, OMX_BUFFERHEADERTYPE *pInputBuffer)
OMX_ERRORTYPE omx_video_scheduler_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp)
OMX_ERRORTYPE omx_video_scheduler_component_GetParameter(OMX_HANDLETYPE hComponent, OMX_INDEXTYPE nParamIndex, OMX_PTR ComponentParameterStructure)
OMX_ERRORTYPE omx_video_scheduler_component_port_SendBufferFunction(omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE *pBuffer)
the entry point for sending buffers to the video scheduler ports
#define DEFAULT_WIDTH
OMX_ERRORTYPE omx_video_scheduler_component_port_FlushProcessingBuffers(omx_base_PortType *openmaxStandPort)
Releases buffers under processing. This function must be implemented in the derived classes,...
OMX_ERRORTYPE omx_video_scheduler_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, OMX_STRING cComponentName)
OMX_ERRORTYPE omx_video_scheduler_component_SetParameter(OMX_HANDLETYPE hComponent, OMX_INDEXTYPE nParamIndex, OMX_PTR ComponentParameterStructure)
#define DEFAULT_VIDEO_INPUT_BUF_SIZE
#define MAX_VIDEOSCHED_COMPONENTS
#define VIDEOSCHED_QUALITY_LEVELS
#define VIDEO_SCHEDULER_COMP_NAME
#define VIDEO_SCHEDULER_COMP_ROLE
OMX_ERRORTYPE err
int queue(queue_t *queue, void *data)
Definition: queue.c:103
void * dequeue(queue_t *queue)
Definition: queue.c:122
OMX_U32 nOutputPortIndex
Definition: OMX_Core.h:439
OMX_U32 nInputPortIndex
Definition: OMX_Core.h:441
OMX_TICKS nTimeStamp
Definition: OMX_Core.h:431
OMX_ERRORTYPE(* SetParameter)(OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_INDEXTYPE nIndex, OMX_IN OMX_PTR pComponentParameterStructure)
OMX_ERRORTYPE(* GetParameter)(OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_INDEXTYPE nParamIndex, OMX_INOUT OMX_PTR pComponentParameterStructure)
OMX_PTR pComponentPrivate
OMX_OTHER_FORMATTYPE eFormat
Definition: OMX_Other.h:329
OMX_OTHER_FORMATTYPE eFormat
Definition: OMX_Other.h:318
union OMX_PARAM_PORTDEFINITIONTYPE::@0 format
OMX_PORTDOMAINTYPE eDomain
Definition: OMX_Component.h:77
OMX_OTHER_PORTDEFINITIONTYPE other
Definition: OMX_Component.h:82
OMX_VIDEO_PORTDEFINITIONTYPE video
Definition: OMX_Component.h:80
OMX_TIME_CLOCKSTATE eState
Definition: OMX_Other.h:234
OMX_TIME_UPDATETYPE eUpdateType
Definition: OMX_Other.h:222
OMX_COLOR_FORMATTYPE eColorFormat
Definition: OMX_Video.h:161
OMX_VIDEO_CODINGTYPE eCompressionFormat
Definition: OMX_Video.h:160
OMX_COLOR_FORMATTYPE eColorFormat
Definition: OMX_Video.h:135
OMX_PARAM_PORTDEFINITIONTYPE sPortParam
OMX_ERRORTYPE(* BufferProcessedCallback)(OMX_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_BUFFERHEADERTYPE *pBuffer)
OMX_U32 nNumAssignedBuffers
OMX_BOOL bIsPortFlushed
OMX_HANDLETYPE hTunneledComponent
OMX_COMPONENTTYPE * standCompContainer
queue_t * pBufferQueue
OMX_BUFFERHEADERTYPE ** pInternalBufferStorage
OMX_ERRORTYPE(* ReturnBufferFunction)(omx_base_PortType *openmaxStandPort, OMX_BUFFERHEADERTYPE *pBuffer)
OMX_OTHER_PARAM_PORTFORMATTYPE sOtherParam
OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE sMediaTimeRequest
OMX_PARAM_PORTDEFINITIONTYPE sPortParam
OMX_HANDLETYPE hTunneledComponent
OMX_PARAM_PORTDEFINITIONTYPE sPortParam
OMX_VIDEO_PARAM_PORTFORMATTYPE sVideoParam
OMX_ERRORTYPE(* FlushProcessingBuffers)(omx_base_PortType *openmaxStandPort)
int nelem
Definition: queue.h:46
unsigned int semval
Definition: tsemaphore.h:41
void tsem_signal(tsem_t *tsem)
Definition: tsemaphore.c:141
void tsem_up(tsem_t *tsem)
Definition: tsemaphore.c:110
void tsem_down(tsem_t *tsem)
Definition: tsemaphore.c:97
void tsem_reset(tsem_t *tsem)
Definition: tsemaphore.c:121

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