/** This function is used to process the input buffer and provide one output buffer
  */
void omx_videoenc_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* pInputBuffer, OMX_BUFFERHEADERTYPE* pOutputBuffer) {

  omx_videoenc_component_PrivateType* omx_videoenc_component_Private = openmaxStandComp->pComponentPrivate;
  omx_base_video_PortType *inPort = (omx_base_video_PortType *)omx_videoenc_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];

  OMX_S32 nOutputFilled = 0;
  OMX_U8* outputCurrBuffer;
  OMX_S32 nLen = 0;
  int size;

  size= inPort->sPortParam.format.video.nFrameWidth*inPort->sPortParam.format.video.nFrameHeight;

  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
  /** Fill up the current input buffer when a new buffer has arrived */
  if(omx_videoenc_component_Private->isNewBuffer) {
    omx_videoenc_component_Private->isNewBuffer = 0;
    DEBUG(DEB_LEV_FULL_SEQ, "New Buffer FilledLen = %d\n", (int)pInputBuffer->nFilledLen);

    omx_videoenc_component_Private->picture->data[0] = pInputBuffer->pBuffer;
    omx_videoenc_component_Private->picture->data[1] = omx_videoenc_component_Private->picture->data[0] + size;
    omx_videoenc_component_Private->picture->data[2] = omx_videoenc_component_Private->picture->data[1] + size / 4;
    omx_videoenc_component_Private->picture->linesize[0] = inPort->sPortParam.format.video.nFrameWidth;
    omx_videoenc_component_Private->picture->linesize[1] = inPort->sPortParam.format.video.nFrameWidth / 2;
    omx_videoenc_component_Private->picture->linesize[2] = inPort->sPortParam.format.video.nFrameWidth / 2;
  }

  outputCurrBuffer = pOutputBuffer->pBuffer;
  pOutputBuffer->nFilledLen = 0;
  pOutputBuffer->nOffset = 0;

  while (!nOutputFilled) {
    if (omx_videoenc_component_Private->isFirstBuffer) {
      tsem_down(omx_videoenc_component_Private->avCodecSyncSem);
      omx_videoenc_component_Private->isFirstBuffer = 0;
    }
    omx_videoenc_component_Private->avCodecContext->frame_number++;

    nLen = avcodec_encode_video(omx_videoenc_component_Private->avCodecContext,
                                outputCurrBuffer,
                                pOutputBuffer->nAllocLen,
                                omx_videoenc_component_Private->picture);

    if (nLen < 0) {
      DEBUG(DEB_LEV_ERR, "----> A general error or simply frame not encoded?\n");
    }

    pInputBuffer->nFilledLen = 0;
      omx_videoenc_component_Private->isNewBuffer = 1;
    if ( nLen >= 0) {
      pOutputBuffer->nFilledLen = nLen;
    } 
    nOutputFilled = 1;
  }
  DEBUG(DEB_LEV_FULL_SEQ, "One output buffer %x nLen=%d is full returning in video encoder\n", 
            (int)pOutputBuffer->pBuffer, (int)pOutputBuffer->nFilledLen);
}
/** 
 * This function processes the input file and returns packet by packet as an output data
 * this packet is used in video decoder component for decoding
 */
void omx_videosrc_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* pOutputBuffer) {

  omx_videosrc_component_PrivateType* omx_videosrc_component_Private = openmaxStandComp->pComponentPrivate;
  struct v4l2_buffer buf;
  
  CLEAR(buf);
  
  DEBUG(DEB_LEV_FUNCTION_NAME,"In %s \n",__func__);

  if (omx_videosrc_component_Private->videoReady == OMX_FALSE) {
    if(omx_videosrc_component_Private->state == OMX_StateExecuting) {
      /*wait for video to be ready*/
      tsem_down(omx_videosrc_component_Private->videoSyncSem);
    } else {
      return;
    }
  }

  pOutputBuffer->nOffset = 0;
  pOutputBuffer->nFilledLen = 0;

  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  buf.memory = V4L2_MEMORY_MMAP;

  if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_DQBUF, &buf)) {
    switch (errno) {
    case EAGAIN:
	    return;
	  case EIO:
	    /* Could ignore EIO, see spec. */
	    /* fall through */

	  default:
      DEBUG(DEB_LEV_ERR,"In %s error VIDIOC_DQBUF\n",__func__);
	    return;
    }
  }

  assert(buf.index < n_buffers);

  if(omx_videosrc_component_Private->bOutBufferMemoryMapped == OMX_FALSE) { /* In case OMX_UseBuffer copy frame to buffer metadata */
    memcpy(pOutputBuffer->pBuffer,omx_videosrc_component_Private->buffers[buf.index].start,omx_videosrc_component_Private->iFrameSize);
  }

  pOutputBuffer->nFilledLen = omx_videosrc_component_Private->iFrameSize;

  DEBUG(DEB_LEV_FULL_SEQ,"Camera output buffer nFilledLen=%d buf.length=%d\n",(int)pOutputBuffer->nFilledLen,buf.length);

  if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_QBUF, &buf)) {
    DEBUG(DEB_LEV_ERR,"In %s error VIDIOC_DQBUF\n",__func__);
  }

  /** return the current output buffer */
  return;
}
/** @brief The OMX_Init standard function
 *
 * This function calls the init function of each component loader added. If there
 * is no component loaders present, the ST default component loader (static libraries)
 * is loaded as default component loader.
 *
 * @return OMX_ErrorNone
 */
OMX_ERRORTYPE OMX_Init() {
  int i = 0;
  OMX_ERRORTYPE err = OMX_ErrorNone, errLoader = OMX_ErrorInsufficientResources;

  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);

  /* Get a lock in case multiple thread are calling OMX_Init at the same time */
  tsem_down(&initSem);
  
  if(initialized == 0) {
    
    if (createComponentLoaders()) {
      tsem_up(&initSem);
      return OMX_ErrorInsufficientResources;
    }
    
    for (i = 0; i < bosa_loaders; i++) {
      err = loadersList[i]->BOSA_InitComponentLoader((struct BOSA_COMPONENTLOADER *) loadersList[i]);
      if (err != OMX_ErrorNone) {
	
	DEBUG(DEB_LEV_ERR, "Component loader %d constructor fails. Error= 0x%08x \n",i, err);
	
	/* The loader failed to initialize itself -> discarding it for the session */
	free((void *) loadersList[i]);
	loadersList[i] = 0;
      }
      
      // Returning OMX_ErrorNone if at least one loader has been able to initialize itself
      if (err == OMX_ErrorNone) {
	errLoader = OMX_ErrorNone;
      }
    }
  } else {
    /* In case core already initialized things are fine */
    errLoader = OMX_ErrorNone;
  }
  initialized ++;
  tsem_up(&initSem);
  
  DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
  return errLoader;
}
/** @brief The OMX_Deinit standard function
 *
 * In this function the Deinit function for each component loader is performed
 */
OMX_ERRORTYPE OMX_Deinit() {
  int i = 0;
  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
  tsem_down(&initSem);
  initialized --;
  if(initialized == 0) {
    for (i = 0; i < bosa_loaders; i++) {
      if(loadersList[i]) {
	loadersList[i]->BOSA_DeInitComponentLoader((struct BOSA_COMPONENTLOADER *) loadersList[i]);
	free((void *) loadersList[i]);
	loadersList[i] = 0;
      }
    }
    free(loadersList);
    loadersList = 0;
    bosa_loaders = 0;
  }
  tsem_up(&initSem);
  DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
  return OMX_ErrorNone;
}
OMX_BOOL omx_alsasink_component_ClockPortHandleFunction(omx_alsasink_component_PrivateType* omx_alsasink_component_Private, OMX_BUFFERHEADERTYPE* inputbuffer){
  omx_base_clock_PortType*            pClockPort;
  OMX_BUFFERHEADERTYPE*               clockBuffer;
  OMX_TIME_MEDIATIMETYPE*             pMediaTime;
  OMX_HANDLETYPE                      hclkComponent;
  OMX_TIME_CONFIG_TIMESTAMPTYPE       sClientTimeStamp;
  OMX_ERRORTYPE                       err;
  OMX_BOOL                            SendFrame=OMX_TRUE;
  omx_base_audio_PortType             *pAudioPort;

  int static                          count=0; //frame counter

  pClockPort    = (omx_base_clock_PortType*)omx_alsasink_component_Private->ports[OMX_BASE_SINK_CLOCKPORT_INDEX];
  pAudioPort    = (omx_base_audio_PortType *) omx_alsasink_component_Private->ports[OMX_BASE_SINK_INPUTPORT_INDEX];
  hclkComponent = pClockPort->hTunneledComponent;
  setHeader(&pClockPort->sMediaTimeRequest, sizeof(OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE));

  /* if  first time stamp is received then notify the clock component */
  if((inputbuffer->nFlags & OMX_BUFFERFLAG_STARTTIME) == OMX_BUFFERFLAG_STARTTIME) {
    DEBUG(DEB_LEV_FULL_SEQ,"In %s  first time stamp = %llx \n", __func__,inputbuffer->nTimeStamp);
    inputbuffer->nFlags = 0;
    hclkComponent = pClockPort->hTunneledComponent;
    setHeader(&sClientTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
    sClientTimeStamp.nPortIndex = pClockPort->nTunneledPort;
    sClientTimeStamp.nTimestamp = inputbuffer->nTimeStamp;
    err = OMX_SetConfig(hclkComponent, OMX_IndexConfigTimeClientStartTime, &sClientTimeStamp);
    if(err!=OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
    }

    if(!PORT_IS_BEING_FLUSHED(pAudioPort) && !PORT_IS_BEING_FLUSHED(pClockPort)) {
      tsem_down(pClockPort->pBufferSem); /* wait for state change notification from clock src*/

      /* update the clock state and clock scale info into the alsa sink private data */
      if(pClockPort->pBufferQueue->nelem > 0) {
        clockBuffer = dequeue(pClockPort->pBufferQueue);
        pMediaTime  = (OMX_TIME_MEDIATIMETYPE*)clockBuffer->pBuffer;
        omx_alsasink_component_Private->eState = pMediaTime->eState;
        omx_alsasink_component_Private->xScale = pMediaTime->xScale;
        pClockPort->ReturnBufferFunction((omx_base_PortType*)pClockPort,clockBuffer);
      }
    }
  }

  /* do not send the data to alsa and return back, if the clock is not running or the scale is anything but 1*/
  if(!(omx_alsasink_component_Private->eState==OMX_TIME_ClockStateRunning  && (omx_alsasink_component_Private->xScale>>16)==1)){
    inputbuffer->nFilledLen=0;
    //return;
    SendFrame = OMX_FALSE;
    return SendFrame;
  }

  /* check for any scale change information from the clock component */
  if(pClockPort->pBufferSem->semval>0){
    tsem_down(pClockPort->pBufferSem);
    if(pClockPort->pBufferQueue->nelem > 0) {
      clockBuffer = dequeue(pClockPort->pBufferQueue);
      pMediaTime  = (OMX_TIME_MEDIATIMETYPE*)clockBuffer->pBuffer;
      if(pMediaTime->eUpdateType==OMX_TIME_UpdateScaleChanged) {
       if(/*(omx_alsasink_component_Private->xScale>>16)==2 &&*/ (pMediaTime->xScale>>16)==1){ /* check with Q16 format only */
             /* rebase the clock time base when turning to normal play mode*/
          hclkComponent = pClockPort->hTunneledComponent;
          setHeader(&sClientTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
          sClientTimeStamp.nPortIndex = pClockPort->nTunneledPort;
          sClientTimeStamp.nTimestamp = inputbuffer->nTimeStamp;
          err = OMX_SetConfig(hclkComponent, OMX_IndexConfigTimeCurrentAudioReference, &sClientTimeStamp);
          if(err!=OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
          }
       }
       omx_alsasink_component_Private->xScale = pMediaTime->xScale;
      }
      pClockPort->ReturnBufferFunction((omx_base_PortType*)pClockPort,clockBuffer);
    }
/** This function is used to process the input buffer and provide one output buffer
  */
void omx_shvpudec_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp,
                                               OMX_BUFFERHEADERTYPE* pInputBuffer,
                                               OMX_BUFFERHEADERTYPE* pOutputBuffer)
{
  omx_shvpudec_component_PrivateType* vpudec = openmaxStandComp->pComponentPrivate;
  int ret = 0;
  OMX_U32 input_len=0, input_used=0;

  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);

#if 0
  /* For comparing input to output */
  memcpy (pOutputBuffer->pBuffer, pInputBuffer->pBuffer, pInputBuffer->nFilledLen);
  pOutputBuffer->nFilledLen = pInputBuffer->nFilledLen;

  pInputBuffer->nFilledLen = 0;
  goto buffer_mgmt_done;
#endif

  vpudec->pOutputBuffer = pOutputBuffer;
  pOutputBuffer->nFilledLen = 0;
  pOutputBuffer->nOffset = 0;

  DEBUG(DEB_LEV_FULL_SEQ, "Output buffer size %d\n", pOutputBuffer->nAllocLen);

  /* If there is some already cached output, copy it out */
  if (vpudec->outputCacheFilled > vpudec->outputCacheCopied) {
    OMX_U32 copy_len =
      MIN (vpudec->outputCacheFilled - vpudec->outputCacheCopied, pOutputBuffer->nAllocLen);

    DEBUG(DEB_LEV_FULL_SEQ, "Copying %d bytes from cache, %d remaining\n", copy_len,
          vpudec->outputCacheFilled - (vpudec->outputCacheCopied + copy_len));

    memcpy (pOutputBuffer->pBuffer, &vpudec->outputCache[vpudec->outputCacheCopied], copy_len);
    vpudec->outputCacheCopied += copy_len;
    pOutputBuffer->nFilledLen = copy_len;

    /* If we have exhausted the output cache, reset it */
    if (vpudec->outputCacheFilled == vpudec->outputCacheCopied) {
      DEBUG(DEB_LEV_FULL_SEQ, "Exhausted output cache, resetting\n");
      vpudec->outputCacheFilled = 0;
      vpudec->outputCacheCopied = 0;
    }

    /* If we have filled the output buffer, we are done */
    if (pOutputBuffer->nFilledLen == pOutputBuffer->nAllocLen) {
      DEBUG(DEB_LEV_FULL_SEQ, "Filled output buffer\n");
      goto buffer_mgmt_done;
    }
  }

  input_len = vpudec->inputCurrLength;

  input_used = MIN (pInputBuffer->nFilledLen, INPUT_BUF_LEN - input_len);

  /** Fill up the current input buffer when a new buffer has arrived */
  if(vpudec->isNewBuffer) {
    memcpy (&vpudec->inputCurrBuffer[input_len],
            pInputBuffer->pBuffer, input_used);
    input_len = input_used;
    vpudec->inputCurrLength += input_len;
    pInputBuffer->nFilledLen -= input_len;
    vpudec->isNewBuffer = 0;
  }

  if (vpudec->isFirstBuffer) {
  DEBUG(DEB_LEV_SIMPLE_SEQ, "  isFirstBuffer {\n");
    tsem_down(vpudec->avCodecSyncSem);
    vpudec->isFirstBuffer = 0;
  }

  DEBUG(DEB_LEV_SIMPLE_SEQ, " Setting decode callback ...\n");

  shcodecs_decoder_set_decoded_callback (vpudec->decoder, vpu_decoded, vpudec);

  DEBUG(DEB_LEV_SIMPLE_SEQ, " Calling decode...\n");

  ret = shcodecs_decode (vpudec->decoder,
                         vpudec->inputCurrBuffer, 
                         vpudec->inputCurrLength);

  DEBUG(DEB_LEV_SIMPLE_SEQ, " Returned from decode (returned %d) ...\n", ret);

  if (ret < 0) {
    DEBUG(DEB_LEV_ERR, "----> A general error or simply frame not decoded?\n");
  } else if (ret > 0) {
    vpudec->inputCurrLength -= ret;
    memmove (vpudec->inputCurrBuffer,
             &vpudec->inputCurrBuffer[ret],
             vpudec->inputCurrLength);
  }

  vpudec->isNewBuffer = 1;

buffer_mgmt_done:

  DEBUG(DEB_LEV_FULL_SEQ, "One output buffer %x nLen=%d is full returning in video decoder\n", 
            (int)pOutputBuffer->pBuffer, (int)pOutputBuffer->nFilledLen);
}
/**
 * This function processes the input file and returns packet by packet as an output data
 * this packet is used in audio/video decoder component for decoding
 */
void omx_parser3gp_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* pOutputBuffer) {
  omx_parser3gp_component_PrivateType* omx_parser3gp_component_Private = openmaxStandComp->pComponentPrivate;
  OMX_BUFFERHEADERTYPE*                temp_buffer;
  int                                  error;
  int                                  stream_index;
  AVRational                           bq = { 1, 1000000 };
  omx_base_clock_PortType              *pClockPort;
  OMX_TIME_MEDIATIMETYPE*              pMediaTime;
  OMX_BUFFERHEADERTYPE*                clockBuffer;
  OMX_S32                              Scale;

  temp_buffer = omx_parser3gp_component_Private->pTmpOutputBuffer;
  DEBUG(DEB_LEV_FUNCTION_NAME,"In %s \n",__func__);

  if (omx_parser3gp_component_Private->avformatReady == OMX_FALSE) {
    if(omx_parser3gp_component_Private->state == OMX_StateExecuting) {
      /*wait for avformat to be ready*/
      tsem_down(omx_parser3gp_component_Private->avformatSyncSem);
    } else {
      return;
    }
  }

  if(omx_parser3gp_component_Private->isFirstBufferAudio == OMX_TRUE && pOutputBuffer->nOutputPortIndex==AUDIO_PORT_INDEX  ) {
    omx_parser3gp_component_Private->isFirstBufferAudio = OMX_FALSE;

    if(omx_parser3gp_component_Private->avformatcontext->streams[AUDIO_STREAM]->codec->extradata_size > 0) {
      memcpy(pOutputBuffer->pBuffer,
             omx_parser3gp_component_Private->avformatcontext->streams[AUDIO_STREAM]->codec->extradata,
             omx_parser3gp_component_Private->avformatcontext->streams[AUDIO_STREAM]->codec->extradata_size);
      pOutputBuffer->nFilledLen = omx_parser3gp_component_Private->avformatcontext->streams[AUDIO_STREAM]->codec->extradata_size;
      pOutputBuffer->nFlags = pOutputBuffer->nFlags | OMX_BUFFERFLAG_CODECCONFIG;

      DEBUG(DEB_ALL_MESS, "In %s Sending Audio First Buffer Extra Data Size=%d\n",__func__,(int)pOutputBuffer->nFilledLen);

      return;
    }
  }

  if(omx_parser3gp_component_Private->isFirstBufferVideo == OMX_TRUE && pOutputBuffer->nOutputPortIndex==VIDEO_PORT_INDEX  ) {
    omx_parser3gp_component_Private->isFirstBufferVideo = OMX_FALSE;

    if(omx_parser3gp_component_Private->avformatcontext->streams[VIDEO_STREAM]->codec->extradata_size > 0) {
      memcpy(pOutputBuffer->pBuffer,
             omx_parser3gp_component_Private->avformatcontext->streams[VIDEO_STREAM]->codec->extradata,
             omx_parser3gp_component_Private->avformatcontext->streams[VIDEO_STREAM]->codec->extradata_size);
      pOutputBuffer->nFilledLen = omx_parser3gp_component_Private->avformatcontext->streams[VIDEO_STREAM]->codec->extradata_size;
      pOutputBuffer->nFlags = pOutputBuffer->nFlags | OMX_BUFFERFLAG_CODECCONFIG;

      DEBUG(DEB_ALL_MESS, "In %s Sending Video First Buffer Extra Data Size=%d\n",__func__,(int)pOutputBuffer->nFilledLen);

      return;
    }
  }

  pOutputBuffer->nFilledLen = 0;
  pOutputBuffer->nOffset = 0;

  /* check for any information from the clock component */
  pClockPort = (omx_base_clock_PortType*)omx_parser3gp_component_Private->ports[CLOCK_PORT_INDEX];
  if(pClockPort->pBufferSem->semval>0){
   tsem_down(pClockPort->pBufferSem);
   clockBuffer = dequeue(pClockPort->pBufferQueue);
   pMediaTime  = (OMX_TIME_MEDIATIMETYPE*)clockBuffer->pBuffer;
   omx_parser3gp_component_Private->xScale = pMediaTime->xScale;
   pClockPort->ReturnBufferFunction((omx_base_PortType*)pClockPort,clockBuffer);
  }

  /* read the stream */
  if(temp_buffer->nFilledLen==0) {  /* no data available in temporary buffer*/
     error = av_read_frame(omx_parser3gp_component_Private->avformatcontext, &omx_parser3gp_component_Private->pkt);
     if(error < 0) {
       DEBUG(DEB_LEV_FULL_SEQ,"In %s EOS - no more packet,state=%x\n",__func__, omx_parser3gp_component_Private->state);
       pOutputBuffer->nFlags = pOutputBuffer->nFlags | OMX_BUFFERFLAG_EOS;
     } else {
       stream_index = omx_parser3gp_component_Private->pkt.stream_index;
       Scale = omx_parser3gp_component_Private->xScale >> 16;
       if(Scale!=1  && Scale!=0 && stream_index==VIDEO_STREAM){  /* TODO - change to a switch statement to handle all cases */
         /* fast forward the stream if Scale>1 */
        if(Scale>1){
           error = av_seek_frame(omx_parser3gp_component_Private->avformatcontext, stream_index, omx_parser3gp_component_Private->pkt.pts+Scale ,0);
           if(error < 0) {
              DEBUG(DEB_LEV_ERR,"Error in seeking stream=%d\n",stream_index);
           }else DEBUG(DEB_LEV_SIMPLE_SEQ,"Success in seeking stream=%d\n",stream_index);
        }
        if(Scale<0){
          error = av_seek_frame(omx_parser3gp_component_Private->avformatcontext, stream_index, omx_parser3gp_component_Private->pkt.pts+Scale ,AVSEEK_FLAG_BACKWARD);
         if(error < 0) {
            DEBUG(DEB_LEV_ERR,"Error in seeking stream=%d\n",stream_index);
         }else DEBUG(DEB_LEV_SIMPLE_SEQ,"Success in seeking stream=%d\n",stream_index);
        }
       }
       if((stream_index==VIDEO_STREAM && pOutputBuffer->nOutputPortIndex==VIDEO_PORT_INDEX) ||
          (stream_index==AUDIO_STREAM && pOutputBuffer->nOutputPortIndex==AUDIO_PORT_INDEX)){
         /** copying the packetized data in the output buffer that will be decoded in the decoder component  */
         if(pOutputBuffer->nAllocLen >= omx_parser3gp_component_Private->pkt.size) {
           memcpy(pOutputBuffer->pBuffer, omx_parser3gp_component_Private->pkt.data, omx_parser3gp_component_Private->pkt.size);
           pOutputBuffer->nFilledLen = omx_parser3gp_component_Private->pkt.size;
           pOutputBuffer->nTimeStamp = av_rescale_q(omx_parser3gp_component_Private->pkt.pts,
                                                    omx_parser3gp_component_Private->avformatcontext->streams[stream_index]->time_base, bq);
           if(FirstTimeStampFlag[stream_index]==OMX_FALSE){
              pOutputBuffer->nFlags = pOutputBuffer->nFlags | OMX_BUFFERFLAG_STARTTIME;
              FirstTimeStampFlag[stream_index] = OMX_TRUE;
           }
         } else {
           DEBUG(DEB_LEV_ERR,"In %s Buffer Size=%d less than Pkt size=%d buffer=%x port_index=%d \n",__func__,
                              (int)pOutputBuffer->nAllocLen,(int)omx_parser3gp_component_Private->pkt.size,
                              (unsigned int)pOutputBuffer,(int)pOutputBuffer->nOutputPortIndex);
         }
       }else { /* the port type and the stream data do not match so keep the data in temporary buffer*/
         if(temp_buffer->nAllocLen >= omx_parser3gp_component_Private->pkt.size) {
           memcpy(temp_buffer->pBuffer, omx_parser3gp_component_Private->pkt.data, omx_parser3gp_component_Private->pkt.size);
           temp_buffer->nFilledLen = omx_parser3gp_component_Private->pkt.size;
           temp_buffer->nTimeStamp = av_rescale_q (omx_parser3gp_component_Private->pkt.pts,
                                                   omx_parser3gp_component_Private->avformatcontext->streams[stream_index]->time_base, bq);
           temp_buffer->nOutputPortIndex = omx_parser3gp_component_Private->pkt.stream_index; /* keep the stream_index in OutputPortIndex for identification */
           if(FirstTimeStampFlag[temp_buffer->nOutputPortIndex]==OMX_FALSE){
             temp_buffer->nFlags = temp_buffer->nFlags | OMX_BUFFERFLAG_STARTTIME;
             FirstTimeStampFlag[temp_buffer->nOutputPortIndex] = OMX_TRUE;
           }
         } else {
           DEBUG(DEB_LEV_ERR,"In %s Buffer Size=%d less than Pkt size=%d\n",__func__,
             (int)temp_buffer->nAllocLen,(int)omx_parser3gp_component_Private->pkt.size);
         }
       }
     }
   } else {  /* data available in temporary buffer */
OMX_ERRORTYPE audiodecEventHandler(
  OMX_OUT OMX_HANDLETYPE hComponent,
  OMX_OUT OMX_PTR pAppData,
  OMX_OUT OMX_EVENTTYPE eEvent,
  OMX_OUT OMX_U32 Data1,
  OMX_OUT OMX_U32 Data2,
  OMX_OUT OMX_PTR pEventData)
{
  OMX_ERRORTYPE err;
  OMX_PARAM_PORTDEFINITIONTYPE param;
  OMX_AUDIO_PARAM_PCMMODETYPE pcmParam;
  
  DEBUG(DEB_LEV_SIMPLE_SEQ, "Hi there, I am in the %s callback\n", __func__);
  if(eEvent == OMX_EventCmdComplete) {
    if (Data1 == OMX_CommandStateSet) {
      DEBUG(DEB_LEV_SIMPLE_SEQ, "Audio Decoder State changed in ");
      switch ((int)Data2) {
      case OMX_StateInvalid:
        DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateInvalid\n");
        break;
      case OMX_StateLoaded:
        DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateLoaded\n");
        break;
      case OMX_StateIdle:
        DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateIdle\n");
        break;
      case OMX_StateExecuting:
        DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateExecuting\n");
        break;
      case OMX_StatePause:
        DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StatePause\n");
        break;
      case OMX_StateWaitForResources:
        DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateWaitForResources\n");
        break;
      }
      tsem_up(appPriv->decoderEventSem);
    }
    else if (Data1 == OMX_CommandPortEnable){
      DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received Port Enable  Event\n",__func__);
      tsem_up(appPriv->decoderEventSem);
    } else if (Data1 == OMX_CommandPortDisable){
      DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received Port Disable Event\n",__func__);
      tsem_up(appPriv->decoderEventSem);
    } 
  } else if(eEvent == OMX_EventPortSettingsChanged) {
    DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received Port Settings Changed Event\n", __func__);
    if (Data2 == 1) {
      param.nPortIndex = 1;
      setHeader(&param, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
      err = OMX_GetParameter(appPriv->audiodechandle,OMX_IndexParamPortDefinition, &param);
      /*Get Port parameters*/
      pcmParam.nPortIndex=1;
      setHeader(&pcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
      err = OMX_GetParameter(appPriv->audiodechandle, OMX_IndexParamAudioPcm, &pcmParam);

      if (flagPlaybackOn && flagSetupTunnel) { /*Disable Volume Component and Audio Sink Port,Set Parameter in Tunneled Case*/

        DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Volume Component Port Disabling\n", __func__);

        err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandPortDisable, 1, NULL);
        if(err != OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"Volume Component port disable failed\n");
			    exit(1);
        }

        DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Audio Sink Port Disabling\n", __func__);
        err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandPortDisable, 0, NULL);
        if(err != OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"alas sink port disable failed\n");
			    exit(1);
        }

        /*Wait for Ports Disable Events*/
        tsem_down(appPriv->sinkEventSem);
        DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Audio Sink Port Disabled\n", __func__);
        tsem_down(appPriv->volumeEventSem);
        DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Volume Component Port Disabled\n", __func__);

        DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Audio Sink Setting Parameters\n", __func__);

        pcmParam.nPortIndex=0;
        err = OMX_SetParameter(appPriv->audiosinkhandle, OMX_IndexParamAudioPcm, &pcmParam);
        if(err!=OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetParameter 0 \n",err);
        }

        err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandPortEnable, 1, NULL);
        err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandPortEnable, 0, NULL);
        if(err != OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"audio sink port enable failed\n");
			    exit(1);
        }

        /*Wait for Ports Enable Events*/
        tsem_down(appPriv->volumeEventSem);
        tsem_down(appPriv->sinkEventSem);
        DEBUG(DEB_LEV_SIMPLE_SEQ,"audio sink port enabled\n");
      }
     
    } else if (Data2 == 0) {
      /*Get Port parameters*/
      param.nPortIndex = 0;
      setHeader(&param, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
      err = OMX_GetParameter(appPriv->audiodechandle,OMX_IndexParamPortDefinition, &param);
    }
  } else if(eEvent == OMX_EventBufferFlag) {
    DEBUG(DEFAULT_MESSAGES, "In %s OMX_BUFFERFLAG_EOS\n", __func__);
    if((int)Data2 == OMX_BUFFERFLAG_EOS) {
      bEOS=OMX_TRUE;
      //tsem_up(appPriv->eofSem);
    }
  } else {
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Param1 is %i\n", (int)Data1);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Param2 is %i\n", (int)Data2);
  }
  
  return OMX_ErrorNone;
}
/** @brief Releases buffers under processing.
 * This function must be implemented in the derived classes, for the
 * specific processing
 */
OMX_ERRORTYPE clocksrc_port_FlushProcessingBuffers(omx_base_PortType *openmaxStandPort) {
  omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private;
  OMX_BUFFERHEADERTYPE* pBuffer;
  int errQue;

  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
  omx_clocksrc_component_Private = (omx_clocksrc_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate;

  pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
  openmaxStandPort->bIsPortFlushed=OMX_TRUE;
  /*Signal the buffer management thread of port flush,if it is waiting for buffers*/
  if(omx_clocksrc_component_Private->bMgmtSem->semval==0) {
    tsem_up(omx_clocksrc_component_Private->bMgmtSem);
  }
  tsem_up(omx_clocksrc_component_Private->clockEventSem);
  tsem_up(omx_clocksrc_component_Private->clockEventCompleteSem);

  if(omx_clocksrc_component_Private->state==OMX_StatePause ) {
    /*Waiting at paused state*/
    tsem_signal(omx_clocksrc_component_Private->bStateSem);
  }
  DEBUG(DEB_LEV_FULL_SEQ, "In %s waiting for flush all condition port index =%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);
  /* Wait until flush is completed */
  pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
  tsem_down(omx_clocksrc_component_Private->flush_all_condition);

  tsem_reset(omx_clocksrc_component_Private->bMgmtSem);
  tsem_reset(omx_clocksrc_component_Private->clockEventSem);

  /* Flush all the buffers not under processing */
  while (openmaxStandPort->pBufferSem->semval > 0) {
    DEBUG(DEB_LEV_FULL_SEQ, "In %s TFlag=%x Flusing Port=%d,Semval=%d Qelem=%d\n",
    __func__,(int)openmaxStandPort->nTunnelFlags,(int)openmaxStandPort->sPortParam.nPortIndex,
    (int)openmaxStandPort->pBufferSem->semval,(int)openmaxStandPort->pBufferQueue->nelem);

    tsem_down(openmaxStandPort->pBufferSem);
    pBuffer = dequeue(openmaxStandPort->pBufferQueue);
    if (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
      DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s is returning io:%d buffer\n",
        __func__,omx_clocksrc_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex);
      if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
        ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
      } else {
        ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
      }
    } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
        errQue = queue(openmaxStandPort->pBufferQueue,pBuffer);
        if (errQue) {
      	  /* /TODO the queue is full. This can be handled in a fine way with
      	   * some retrials, or other checking. For the moment this is a critical error
      	   * and simply causes the failure of this call
      	   */
      	  return OMX_ErrorInsufficientResources;
        }
    } else {
      (*(openmaxStandPort->BufferProcessedCallback))(
        openmaxStandPort->standCompContainer,
        omx_clocksrc_component_Private->callbackData,
        pBuffer);
    }
  }
  /*Port is tunneled and supplier and didn't received all it's buffer then wait for the buffers*/
  if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
    while(openmaxStandPort->pBufferQueue->nelem!= openmaxStandPort->nNumAssignedBuffers){
      tsem_down(openmaxStandPort->pBufferSem);
      DEBUG(DEB_LEV_PARAMS, "In %s Got a buffer qelem=%d\n",__func__,openmaxStandPort->pBufferQueue->nelem);
    }
    tsem_reset(openmaxStandPort->pBufferSem);
  }

  pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
  openmaxStandPort->bIsPortFlushed=OMX_FALSE;
  pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);

  tsem_up(omx_clocksrc_component_Private->flush_condition);

  DEBUG(DEB_LEV_FULL_SEQ, "Out %s Port Index=%d bIsPortFlushed=%d Component %s\n", __func__,
    (int)openmaxStandPort->sPortParam.nPortIndex,(int)openmaxStandPort->bIsPortFlushed,omx_clocksrc_component_Private->name);

  DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__,
    (int)openmaxStandPort->nTunnelFlags,
    (int)openmaxStandPort->pBufferQueue->nelem,
    (int)openmaxStandPort->pBufferSem->semval,
    (int)omx_clocksrc_component_Private->bMgmtSem->semval,
    omx_clocksrc_component_Private->name);

  DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port Index=%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);

  return OMX_ErrorNone;
}
OMX_ERRORTYPE omx_clocksrc_component_SetConfig(
  OMX_HANDLETYPE hComponent,
  OMX_INDEXTYPE nIndex,
  OMX_PTR pComponentConfigStructure) {

  OMX_COMPONENTTYPE*                  omxComponent = (OMX_COMPONENTTYPE*)hComponent;
  omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private = (omx_clocksrc_component_PrivateType*)omxComponent->pComponentPrivate;
  OMX_TIME_CONFIG_CLOCKSTATETYPE*     clockstate;
  OMX_TIME_CONFIG_TIMESTAMPTYPE*      sRefTimeStamp;
  OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE* pRefClock;
  OMX_U32                             portIndex;
  omx_base_clock_PortType             *pPort;
  OMX_TIME_CONFIG_SCALETYPE           *pConfigScale;
  OMX_U32                             nMask;
  OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE* sMediaTimeRequest;
  int                                 i;
  struct timeval                      tv;
  struct timezone                     zv;
  OMX_TICKS                           walltime, mediatime, mediaTimediff, wallTimediff;
  OMX_S32                             Scale;
  unsigned int                        sleeptime;

  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);

  switch (nIndex) {
  case OMX_IndexConfigTimeClockState : {
    clockstate = (OMX_TIME_CONFIG_CLOCKSTATETYPE*) pComponentConfigStructure;
    switch (clockstate->eState) {
      case OMX_TIME_ClockStateRunning:
        if(omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateRunning) {
          DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received OMX_TIME_ClockStateRunning again\n",__func__);
        }
        DEBUG(DEB_LEV_SIMPLE_SEQ,"in  %s ...set to OMX_TIME_ClockStateRunning\n",__func__);
        memcpy(&omx_clocksrc_component_Private->sClockState, clockstate, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
        omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateClockStateChanged;
        /* update the state change in all port */
        for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
          pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i];
          pPort->sMediaTime.eUpdateType                      = OMX_TIME_UpdateClockStateChanged;
          pPort->sMediaTime.eState                           = OMX_TIME_ClockStateRunning;
          pPort->sMediaTime.xScale                           = omx_clocksrc_component_Private->sConfigScale.xScale;
        }
        /*Signal Buffer Management Thread*/
        tsem_up(omx_clocksrc_component_Private->clockEventSem);
        DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Clock Running Event for all ports\n");
        tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem);
      break;
      case OMX_TIME_ClockStateWaitingForStartTime:
        if(omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateRunning) {
          return OMX_ErrorIncorrectStateTransition;
        } else if(omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateWaitingForStartTime) {
          return OMX_ErrorSameState;
        }
        DEBUG(DEB_LEV_SIMPLE_SEQ," in  %s ...set to OMX_TIME_ClockStateWaitingForStartTime  mask sent=%d\n",__func__,(int)clockstate->nWaitMask);
        memcpy(&omx_clocksrc_component_Private->sClockState, clockstate, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
      break;
      case OMX_TIME_ClockStateStopped:
        DEBUG(DEB_LEV_SIMPLE_SEQ," in  %s ...set to OMX_TIME_ClockStateStopped\n",__func__);
        memcpy(&omx_clocksrc_component_Private->sClockState, clockstate, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
        omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateClockStateChanged;
        /* update the state change in all port */
        for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
          pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i];
          pPort->sMediaTime.eUpdateType                      = OMX_TIME_UpdateClockStateChanged;
          pPort->sMediaTime.eState                           = OMX_TIME_ClockStateStopped;
          pPort->sMediaTime.xScale                           = omx_clocksrc_component_Private->sConfigScale.xScale;
        }
        /*Signal Buffer Management Thread*/
        tsem_up(omx_clocksrc_component_Private->clockEventSem);
        DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Clock Stop Event for all ports\n");
        tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem);
      break;
      default:
      break;
    }
   }
    break;
  case OMX_IndexConfigTimeClientStartTime:
    sRefTimeStamp = (OMX_TIME_CONFIG_TIMESTAMPTYPE*) pComponentConfigStructure;
    portIndex = sRefTimeStamp->nPortIndex;
    if(portIndex > omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) {
     return OMX_ErrorBadPortIndex;
    }

    pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex];
    if(!PORT_IS_ENABLED(pPort)) {
     DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Port is disabled \n",__func__);
     return OMX_ErrorBadParameter;
    }
    memcpy(&pPort->sTimeStamp, sRefTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));

    /* update the nWaitMask to clear the flag for the client which has sent its start time */
    if(omx_clocksrc_component_Private->sClockState.nWaitMask) {
      DEBUG(DEB_LEV_SIMPLE_SEQ,"refTime set is =%x \n",(int)pPort->sTimeStamp.nTimestamp);
      nMask = ~(0x1 << portIndex);
      omx_clocksrc_component_Private->sClockState.nWaitMask = omx_clocksrc_component_Private->sClockState.nWaitMask & nMask;
      if(omx_clocksrc_component_Private->sMinStartTime.nTimestamp >= pPort->sTimeStamp.nTimestamp){
         omx_clocksrc_component_Private->sMinStartTime.nTimestamp = pPort->sTimeStamp.nTimestamp;
         omx_clocksrc_component_Private->sMinStartTime.nPortIndex = pPort->sTimeStamp.nPortIndex;
      }
    }
    if(!omx_clocksrc_component_Private->sClockState.nWaitMask &&
       omx_clocksrc_component_Private->sClockState.eState == OMX_TIME_ClockStateWaitingForStartTime) {
       omx_clocksrc_component_Private->sClockState.eState = OMX_TIME_ClockStateRunning;
      omx_clocksrc_component_Private->sClockState.nStartTime = omx_clocksrc_component_Private->sMinStartTime.nTimestamp;
      omx_clocksrc_component_Private->MediaTimeBase          = omx_clocksrc_component_Private->sMinStartTime.nTimestamp;
      gettimeofday(&tv,&zv);
      walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
      omx_clocksrc_component_Private->WallTimeBase          = walltime;
      DEBUG(DEB_LEV_SIMPLE_SEQ,"Mediatimebase=%llx walltimebase=%llx \n",omx_clocksrc_component_Private->MediaTimeBase,omx_clocksrc_component_Private->WallTimeBase);
      omx_clocksrc_component_Private->eUpdateType        = OMX_TIME_UpdateClockStateChanged;
      /* update the state change in all port */
      for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
        pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i];
        pPort->sMediaTime.eUpdateType                      = OMX_TIME_UpdateClockStateChanged;
        pPort->sMediaTime.eState                           = OMX_TIME_ClockStateRunning;
        pPort->sMediaTime.xScale                           = omx_clocksrc_component_Private->sConfigScale.xScale;
      }
      /*Signal Buffer Management Thread*/
      tsem_up(omx_clocksrc_component_Private->clockEventSem);
      DEBUG(DEB_LEV_SIMPLE_SEQ,"setting the state to running from %s \n",__func__);
      DEBUG(DEB_LEV_SIMPLE_SEQ,"Waiting for Clock Running Event for all ports in case OMX_IndexConfigTimeClientStartTime\n");
      tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem);
    }
    break;

  case OMX_IndexConfigTimeActiveRefClock :
     pRefClock = (OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE*) pComponentConfigStructure;
     memcpy(&omx_clocksrc_component_Private->sRefClock, pRefClock, sizeof(OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE));
  break;

  case OMX_IndexConfigTimeCurrentAudioReference:
    sRefTimeStamp = (OMX_TIME_CONFIG_TIMESTAMPTYPE*) pComponentConfigStructure;
    portIndex = sRefTimeStamp->nPortIndex;
    if(portIndex > omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) {
     return OMX_ErrorBadPortIndex;
    }
    pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex];
    memcpy(&pPort->sTimeStamp, sRefTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
    gettimeofday(&tv,&zv);
    walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
    omx_clocksrc_component_Private->WallTimeBase   = walltime;
    omx_clocksrc_component_Private->MediaTimeBase  = sRefTimeStamp->nTimestamp; /* set the mediatime base of the received time stamp*/
  break;

  case OMX_IndexConfigTimeCurrentVideoReference:
    sRefTimeStamp = (OMX_TIME_CONFIG_TIMESTAMPTYPE*) pComponentConfigStructure;
    portIndex = sRefTimeStamp->nPortIndex;
    if(portIndex > omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts) {
      return OMX_ErrorBadPortIndex;
    }
    pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex];
    memcpy(&pPort->sTimeStamp, sRefTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
    gettimeofday(&tv,&zv);
    walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
    omx_clocksrc_component_Private->WallTimeBase   = walltime;
    omx_clocksrc_component_Private->MediaTimeBase  = sRefTimeStamp->nTimestamp; /* set the mediatime base of the received time stamp*/
  break;

  case OMX_IndexConfigTimeScale:
    /* update the mediatime base and walltime base using the current scale value*/
    Scale = omx_clocksrc_component_Private->sConfigScale.xScale >> 16;  //* the scale currently in use, right shifted as Q16 format is used for the scale
    gettimeofday(&tv,&zv);
    walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
    mediatime = omx_clocksrc_component_Private->MediaTimeBase + Scale*(walltime - omx_clocksrc_component_Private->WallTimeBase);
    omx_clocksrc_component_Private->WallTimeBase   = walltime; // suitable start time to be used here
    omx_clocksrc_component_Private->MediaTimeBase  = mediatime;  // TODO - needs to be checked

    /* update the new scale value */
    pConfigScale = (OMX_TIME_CONFIG_SCALETYPE*) pComponentConfigStructure;
    memcpy( &omx_clocksrc_component_Private->sConfigScale,pConfigScale, sizeof(OMX_TIME_CONFIG_SCALETYPE));
    omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateScaleChanged;
    /* update the scale change in all ports */
    for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
      pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[i];
      pPort->sMediaTime.eUpdateType                      = OMX_TIME_UpdateScaleChanged;
      pPort->sMediaTime.eState                           = OMX_TIME_ClockStateRunning;
      pPort->sMediaTime.xScale                           = omx_clocksrc_component_Private->sConfigScale.xScale;
      pPort->sMediaTime.nMediaTimestamp                  = omx_clocksrc_component_Private->MediaTimeBase;
      pPort->sMediaTime.nWallTimeAtMediaTime             = omx_clocksrc_component_Private->WallTimeBase;
      }
    /*Signal Buffer Management Thread*/
    tsem_up(omx_clocksrc_component_Private->clockEventSem);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Scale Change Event for all ports\n");
    tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem);
  break;

  case OMX_IndexConfigTimeMediaTimeRequest:
    Scale = omx_clocksrc_component_Private->sConfigScale.xScale >> 16;

    if(omx_clocksrc_component_Private->sClockState.eState != OMX_TIME_ClockStateStopped && Scale != 0) {//TODO-  what happens if request comes in pause mode

      sMediaTimeRequest = (OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE*) pComponentConfigStructure;
      portIndex = sMediaTimeRequest->nPortIndex;
      pPort = (omx_base_clock_PortType*)omx_clocksrc_component_Private->ports[portIndex];
      memcpy(&pPort->sMediaTimeRequest, sMediaTimeRequest, sizeof(OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE));

      gettimeofday(&tv,&zv);
      walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
      mediatime = omx_clocksrc_component_Private->MediaTimeBase + Scale*(walltime - omx_clocksrc_component_Private->WallTimeBase);
      int thresh=2000;  // TODO - what is a good threshold to use
      mediaTimediff = (sMediaTimeRequest->nMediaTimestamp - (sMediaTimeRequest->nOffset*Scale)) - mediatime;
      DEBUG(DEB_LEV_SIMPLE_SEQ," pI=%d MTD=%lld MT=%lld RT=%lld offset=%lld, Scale=%d\n",
               (int)portIndex,mediaTimediff,mediatime,sMediaTimeRequest->nMediaTimestamp,sMediaTimeRequest->nOffset,(int)Scale);
      if((mediaTimediff<0 && Scale>0) || (mediaTimediff>0 && Scale<0)) { /* if mediatime has already elapsed then request can not be fullfilled */
        DEBUG(DEB_LEV_SIMPLE_SEQ," pI=%d RNF MTD<0 MB=%lld WB=%lld MT=%lld RT=%lld WT=%lld offset=%lld, Scale=%d\n",
                 (int)portIndex,omx_clocksrc_component_Private->MediaTimeBase,omx_clocksrc_component_Private->WallTimeBase,
                  mediatime,sMediaTimeRequest->nMediaTimestamp,walltime,sMediaTimeRequest->nOffset,(int)Scale);
        pPort->sMediaTime.eUpdateType          =  OMX_TIME_UpdateRequestFulfillment; // TODO : to be checked
        pPort->sMediaTime.nMediaTimestamp      = sMediaTimeRequest->nMediaTimestamp;
        pPort->sMediaTime.nOffset              = 0xFFFFFFFF;
       }else{
         wallTimediff  = mediaTimediff/Scale;
         if(mediaTimediff){
            if(wallTimediff>thresh) {
                sleeptime = (unsigned int) (wallTimediff-thresh);
                usleep(sleeptime);
                wallTimediff = thresh;  // ask : can I use this as the new walltimediff
                gettimeofday(&tv,&zv);
                walltime = ((OMX_TICKS)tv.tv_sec)*1000000 + ((OMX_TICKS)tv.tv_usec);
                mediatime = omx_clocksrc_component_Private->MediaTimeBase + Scale*(walltime - omx_clocksrc_component_Private->WallTimeBase);
            }
            //pPort->sMediaTime.nMediaTimestamp      = mediatime;
            pPort->sMediaTime.nMediaTimestamp      = sMediaTimeRequest->nMediaTimestamp;  ///????
            pPort->sMediaTime.nWallTimeAtMediaTime = walltime + wallTimediff;        //??????
            pPort->sMediaTime.nOffset              = wallTimediff;                   //????
            pPort->sMediaTime.xScale               = Scale;
            pPort->sMediaTime.eUpdateType          = OMX_TIME_UpdateRequestFulfillment;
            DEBUG(DEB_LEV_SIMPLE_SEQ,"pI=%d MB=%lld WB=%lld MT=%lld RT=%lld WT=%lld \n",(int)portIndex,
                omx_clocksrc_component_Private->MediaTimeBase,omx_clocksrc_component_Private->WallTimeBase, mediatime,sMediaTimeRequest->nMediaTimestamp,walltime);
         }
      }
      /*Signal Buffer Management Thread*/
      tsem_up(omx_clocksrc_component_Private->clockEventSem);
      DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for Scale Change Event for all ports\n");
      tsem_down(omx_clocksrc_component_Private->clockEventCompleteSem);
    } else {
       DEBUG(DEB_LEV_ERR,"In %s Clock State=%x Scale=%x Line=%d \n",
          __func__,(int)omx_clocksrc_component_Private->sClockState.eState,(int)Scale,__LINE__);
    }
  break;

  default:
    return OMX_ErrorBadParameter;
    break;
  }
  return OMX_ErrorNone;
}
OMX_BOOL omx_video_scheduler_component_ClockPortHandleFunction(
  omx_video_scheduler_component_PrivateType* omx_video_scheduler_component_Private,
  OMX_BUFFERHEADERTYPE* pInputBuffer){
  omx_base_clock_PortType               *pClockPort;
  OMX_HANDLETYPE                        hclkComponent;
  OMX_BUFFERHEADERTYPE*                 clockBuffer;
  OMX_TIME_MEDIATIMETYPE*               pMediaTime;
  OMX_TIME_CONFIG_TIMESTAMPTYPE         sClientTimeStamp;
  OMX_ERRORTYPE                         err;
  OMX_BOOL                              SendFrame;
  omx_base_video_PortType               *pInputPort;

  pClockPort    = (omx_base_clock_PortType*) omx_video_scheduler_component_Private->ports[CLOCKPORT_INDEX];
  pInputPort    = (omx_base_video_PortType *) omx_video_scheduler_component_Private->ports[0];
  hclkComponent = pClockPort->hTunneledComponent;

  SendFrame = OMX_TRUE;

  DEBUG(DEB_LEV_FULL_SEQ, "In %s Clock Port is Tunneled. Sending Request\n", __func__);
  /* if first time stamp is received then notify the clock component */
  if((pInputBuffer->nFlags & OMX_BUFFERFLAG_STARTTIME) == OMX_BUFFERFLAG_STARTTIME) {
    DEBUG(DEB_LEV_FULL_SEQ," In %s  first time stamp = %llx \n", __func__,pInputBuffer->nTimeStamp);
    pInputBuffer->nFlags = 0;
    hclkComponent = pClockPort->hTunneledComponent;
    setHeader(&sClientTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
    sClientTimeStamp.nPortIndex = pClockPort->nTunneledPort;
    sClientTimeStamp.nTimestamp = pInputBuffer->nTimeStamp;
    err = OMX_SetConfig(hclkComponent, OMX_IndexConfigTimeClientStartTime, &sClientTimeStamp);
    if(err!=OMX_ErrorNone) {
     DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
    }
    tsem_down(pClockPort->pBufferSem); /* wait for state change notification */

    /* update the clock state and clock scale info into the fbdev private data */
    if(pClockPort->pBufferQueue->nelem > 0) {
      clockBuffer=dequeue(pClockPort->pBufferQueue);
      pMediaTime  = (OMX_TIME_MEDIATIMETYPE*)clockBuffer->pBuffer;
      omx_video_scheduler_component_Private->eState      = pMediaTime->eState;
      omx_video_scheduler_component_Private->xScale      = pMediaTime->xScale;
      pClockPort->ReturnBufferFunction((omx_base_PortType*)pClockPort,clockBuffer);
    }
  }

  /* do not send the data to sink and return back, if the clock is not running*/
  if(!omx_video_scheduler_component_Private->eState==OMX_TIME_ClockStateRunning){
    pInputBuffer->nFilledLen=0;
    SendFrame = OMX_FALSE;
    return SendFrame;
  }

  /* check for any scale change information from the clock component */
  if(pClockPort->pBufferSem->semval>0) {
    tsem_down(pClockPort->pBufferSem);
    if(pClockPort->pBufferQueue->nelem > 0) {
      clockBuffer = dequeue(pClockPort->pBufferQueue);
      pMediaTime  = (OMX_TIME_MEDIATIMETYPE*)clockBuffer->pBuffer;
      if(pMediaTime->eUpdateType==OMX_TIME_UpdateScaleChanged) {
        /* On scale change update the media time base */
        sClientTimeStamp.nPortIndex = pClockPort->nTunneledPort;
        sClientTimeStamp.nTimestamp = pInputBuffer->nTimeStamp;
        err = OMX_SetConfig(hclkComponent, OMX_IndexConfigTimeCurrentVideoReference, &sClientTimeStamp);
        if(err!=OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
        }
        omx_video_scheduler_component_Private->frameDropFlag = OMX_TRUE;
        omx_video_scheduler_component_Private->dropFrameCount = 0;
        omx_video_scheduler_component_Private->xScale = pMediaTime->xScale;
      }
      pClockPort->ReturnBufferFunction((omx_base_PortType*)pClockPort,clockBuffer);
    }
  }

  /* drop next seven frames on scale change
     and rebase the clock time base */
  if(omx_video_scheduler_component_Private->frameDropFlag && omx_video_scheduler_component_Private->dropFrameCount<7) { //TODO - second check cond can be removed verify
     omx_video_scheduler_component_Private->dropFrameCount ++;
     if(omx_video_scheduler_component_Private->dropFrameCount==7) {
        /* rebase the clock time base */
        setHeader(&sClientTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
        sClientTimeStamp.nPortIndex = pClockPort->nTunneledPort;
        sClientTimeStamp.nTimestamp = pInputBuffer->nTimeStamp;
        err = OMX_SetConfig(hclkComponent, OMX_IndexConfigTimeCurrentVideoReference, &sClientTimeStamp);
        if(err!=OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
        }

        omx_video_scheduler_component_Private->frameDropFlag  = OMX_FALSE;
        omx_video_scheduler_component_Private->dropFrameCount = 0;
        SendFrame = OMX_TRUE;
     }
     SendFrame = OMX_FALSE;
  }

  /* frame is not to be dropped so send the request for the timestamp for the data delivery */
  if(SendFrame){
    if(!PORT_IS_BEING_FLUSHED(pInputPort) && !PORT_IS_BEING_FLUSHED(pClockPort) &&
        omx_video_scheduler_component_Private->transientState != OMX_TransStateExecutingToIdle) {
      setHeader(&pClockPort->sMediaTimeRequest, sizeof(OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE));
      pClockPort->sMediaTimeRequest.nMediaTimestamp = pInputBuffer->nTimeStamp;
      pClockPort->sMediaTimeRequest.nOffset         = 100; /*set the requested offset */
      pClockPort->sMediaTimeRequest.nPortIndex      = pClockPort->nTunneledPort;
      pClockPort->sMediaTimeRequest.pClientPrivate  = NULL; /* fill the appropriate value */
      err = OMX_SetConfig(hclkComponent, OMX_IndexConfigTimeMediaTimeRequest, &pClockPort->sMediaTimeRequest);
      if(err!=OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
      }
      if(!PORT_IS_BEING_FLUSHED(pInputPort) && !PORT_IS_BEING_FLUSHED(pClockPort) &&
          omx_video_scheduler_component_Private->transientState != OMX_TransStateExecutingToIdle) {
        tsem_down(pClockPort->pBufferSem); /* wait for the request fullfillment */
        if(pClockPort->pBufferQueue->nelem > 0) {
          clockBuffer = dequeue(pClockPort->pBufferQueue);
          pMediaTime  = (OMX_TIME_MEDIATIMETYPE*)clockBuffer->pBuffer;
          if(pMediaTime->eUpdateType==OMX_TIME_UpdateScaleChanged) {
           /* update the media time base */
            setHeader(&sClientTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE)); // do not need to setHeader again do once at the top
            sClientTimeStamp.nPortIndex = pClockPort->nTunneledPort;
            sClientTimeStamp.nTimestamp = pInputBuffer->nTimeStamp;
            err = OMX_SetConfig(hclkComponent, OMX_IndexConfigTimeCurrentVideoReference, &sClientTimeStamp);
            if(err!=OMX_ErrorNone) {
              DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig in func=%s \n",err,__func__);
            }
            omx_video_scheduler_component_Private->frameDropFlag  = OMX_TRUE;
            omx_video_scheduler_component_Private->dropFrameCount = 0;
            omx_video_scheduler_component_Private->xScale = pMediaTime->xScale;
          }
          if(pMediaTime->eUpdateType==OMX_TIME_UpdateRequestFulfillment){
            if((pMediaTime->nOffset)>0) {
              SendFrame=OMX_TRUE;
            }else {
              SendFrame = OMX_FALSE;
            }
          }
          pClockPort->ReturnBufferFunction((omx_base_PortType *)pClockPort,clockBuffer);
        }
      }
    }
  }
  return(SendFrame);
}
int main(int argc, char** argv) {

  OMX_PORT_PARAM_TYPE param;
  OMX_BUFFERHEADERTYPE *inBuffer1, *inBuffer2, *outBuffer1, *outBuffer2;
  int data_read1;
  int data_read2;
  OMX_PARAM_PORTDEFINITIONTYPE sPortDef;
  OMX_AUDIO_CONFIG_VOLUMETYPE sVolume;
  int gain=100;
  int argn_dec;

  /* Obtain file descriptor */
  if(argc < 2){
    display_help();
  } else {
    flagIsOutputExpected = 0;
    flagOutputReceived = 0;
    flagInputReceived = 0;
    flagIsGain = 0;

    argn_dec = 1;
    while (argn_dec<argc) {
      if (*(argv[argn_dec]) =='-') {
        if (flagIsOutputExpected) {
          display_help();
        }
        switch (*(argv[argn_dec]+1)) {
        case 'h':
          display_help();
          break;
        case 'o':
          flagIsOutputExpected = 1;
          break;
        case 'g':
          flagIsGain = 1;
          break;
        default:
          display_help();
        }
      } else {
        if (flagIsGain) {
          gain = (int)atoi(argv[argn_dec]);
          flagIsGain = 0;
          if(gain > 100) {
            DEBUG(DEFAULT_MESSAGES, "Gain should be between [0..100]\n");
            gain = 100; 
          }
        } else if (flagIsOutputExpected) {
          output_file = malloc(strlen(argv[argn_dec]) + 1);
          strcpy(output_file,argv[argn_dec]);
          flagIsOutputExpected = 0;
          flagOutputReceived = 1;
        } else {
          input_file = malloc(strlen(argv[argn_dec]) + 1);
          strcpy(input_file,argv[argn_dec]);
          flagInputReceived = 1;
        }
      }
      argn_dec++;
    }
    if (!flagInputReceived) {
      display_help();
    }
    DEBUG(DEFAULT_MESSAGES, "Input file %s", input_file);
    DEBUG(DEFAULT_MESSAGES, " to ");
    if (flagOutputReceived) {
      DEBUG(DEFAULT_MESSAGES, " %s\n", output_file);
    }
  }

 
  fd = open(input_file, O_RDONLY);
  if(fd < 0){
    perror("Error opening input file\n");
    exit(1);
  }

  if (flagOutputReceived) {
    outfile = fopen(output_file,"wb");
    if(outfile == NULL) {
      DEBUG(DEB_LEV_ERR, "Error at opening the output file");
      exit(1);
    } 
  }
   
  filesize = getFileSize(fd);
  /* Initialize application private data */
  appPriv = malloc(sizeof(appPrivateType));
  pthread_cond_init(&appPriv->condition, NULL);
  pthread_mutex_init(&appPriv->mutex, NULL);
  appPriv->eventSem = malloc(sizeof(tsem_t));
  tsem_init(appPriv->eventSem, 0);
  appPriv->eofSem = malloc(sizeof(tsem_t));
  tsem_init(appPriv->eofSem, 0);

  err = OMX_Init();
  if(err != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "OMX_Init() failed\n");
    exit(1);
  }
  /** Ask the core for a handle to the volume control component
    */
  err = OMX_GetHandle(&handle, "OMX.st.volume.component", NULL /*appPriv */, &callbacks);
  if(err != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "OMX_GetHandle failed\n");
    exit(1);
  }

  if((gain >= 0) && (gain <100)) {
    err = OMX_GetConfig(handle, OMX_IndexConfigAudioVolume, &sVolume);
    if(err!=OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"Error %08x In OMX_GetConfig 0 \n",err);
    }
    sVolume.sVolume.nValue = gain;
    DEBUG(DEFAULT_MESSAGES, "Setting Gain %d \n", gain);
    err = OMX_SetConfig(handle, OMX_IndexConfigAudioVolume, &sVolume);
    if(err!=OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig 0 \n",err);
    }
  }

  /** Set the number of ports for the parameter structure */
  param.nPorts = 2;
  setHeader(&param, sizeof(OMX_PORT_PARAM_TYPE));
  err = OMX_GetParameter(handle, OMX_IndexParamAudioInit, &param);
  if(err != OMX_ErrorNone){
    DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
    exit(1);
  }

  setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
  sPortDef.nPortIndex = 0;
  err = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);

  sPortDef.nBufferCountActual = 2;
  err = OMX_SetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
  if(err != OMX_ErrorNone){
    DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
    exit(1);
  }
  sPortDef.nPortIndex = 1;
  err = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);

  sPortDef.nBufferCountActual = 2;
  err = OMX_SetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
  if(err != OMX_ErrorNone){
    DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
    exit(1);
  }

  err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateIdle, NULL);

  inBuffer1 = inBuffer2 = outBuffer1 = outBuffer2 = NULL;
  err = OMX_AllocateBuffer(handle, &inBuffer1, 0, NULL, BUFFER_IN_SIZE);
  if (err != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer in 1%i\n", err);
    exit(1);
  }
  err = OMX_AllocateBuffer(handle, &inBuffer2, 0, NULL, BUFFER_IN_SIZE);
  if (err != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer in 2 %i\n", err);
    exit(1);
  }
  err = OMX_AllocateBuffer(handle, &outBuffer1, 1, NULL, BUFFER_IN_SIZE);
  if (err != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer out 1 %i\n", err);
    exit(1);
  }
  err = OMX_AllocateBuffer(handle, &outBuffer2, 1, NULL, BUFFER_IN_SIZE);
  if (err != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer out 2 %i\n", err);
    exit(1);
  }

  tsem_down(appPriv->eventSem);
  err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);

  /* Wait for commands to complete */
  tsem_down(appPriv->eventSem);

  DEBUG(DEB_LEV_PARAMS, "Had buffers at:\n0x%08x\n0x%08x\n0x%08x\n0x%08x\n", 
                (int)inBuffer1->pBuffer, (int)inBuffer2->pBuffer, (int)outBuffer1->pBuffer, (int)outBuffer2->pBuffer);
  DEBUG(DEB_LEV_PARAMS, "After switch to executing\n");

  data_read1 = read(fd, inBuffer1->pBuffer, BUFFER_IN_SIZE);
  inBuffer1->nFilledLen = data_read1;
  filesize -= data_read1;

  data_read2 = read(fd, inBuffer2->pBuffer, BUFFER_IN_SIZE);
  inBuffer2->nFilledLen = data_read2;
  filesize -= data_read2;

  DEBUG(DEB_LEV_PARAMS, "Empty first  buffer %x\n", (int)inBuffer1);
  err = OMX_EmptyThisBuffer(handle, inBuffer1);
  DEBUG(DEB_LEV_PARAMS, "Empty second buffer %x\n", (int)inBuffer2);
  err = OMX_EmptyThisBuffer(handle, inBuffer2);
  
  /** Schedule a couple of buffers to be filled on the output port
    * The callback itself will re-schedule them.
    */
  err = OMX_FillThisBuffer(handle, outBuffer1);
  err = OMX_FillThisBuffer(handle, outBuffer2);

  tsem_down(appPriv->eofSem);

  err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
  /* Wait for commands to complete */
  tsem_down(appPriv->eventSem);

  err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
  err = OMX_FreeBuffer(handle, 0, inBuffer1);
  err = OMX_FreeBuffer(handle, 0, inBuffer2);
  err = OMX_FreeBuffer(handle, 1, outBuffer1);
  err = OMX_FreeBuffer(handle, 1, outBuffer2);

  /* Wait for commands to complete */
  tsem_down(appPriv->eventSem);

  OMX_FreeHandle(handle);

  free(appPriv->eventSem);
  free(appPriv);

  if (flagOutputReceived) {
    if(fclose(outfile) != 0) {
      DEBUG(DEB_LEV_ERR,"Error in closing output file\n");
      exit(1);
    }
    free(output_file);
  }

  close(fd);
  free(input_file);

  return 0;
}
/** This is the central function for component processing. It
  * is executed in a separate thread, is synchronized with
  * semaphores at each port, those are released each time a new buffer
  * is available on the given port.
  */
void* omx_base_filter_BufferMgmtFunction (void* param) {
  OMX_COMPONENTTYPE* openmaxStandComp = (OMX_COMPONENTTYPE*)param;
  omx_base_filter_PrivateType* omx_base_filter_Private = (omx_base_filter_PrivateType*)openmaxStandComp->pComponentPrivate;
  omx_base_PortType *pInPort=(omx_base_PortType *)omx_base_filter_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
  omx_base_PortType *pOutPort=(omx_base_PortType *)omx_base_filter_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
  tsem_t* pInputSem = pInPort->pBufferSem;
  tsem_t* pOutputSem = pOutPort->pBufferSem;
  queue_t* pInputQueue = pInPort->pBufferQueue;
  queue_t* pOutputQueue = pOutPort->pBufferQueue;
  OMX_BUFFERHEADERTYPE* pOutputBuffer=NULL;
  OMX_BUFFERHEADERTYPE* pInputBuffer=NULL;
  OMX_BOOL isInputBufferNeeded=OMX_TRUE,isOutputBufferNeeded=OMX_TRUE;
  int inBufExchanged=0,outBufExchanged=0;

  omx_base_filter_Private->bellagioThreads->nThreadBufferMngtID = (long int)syscall(__NR_gettid);
  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s of component %p\n", __func__, openmaxStandComp);
  DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s the thread ID is %i\n", __func__, (int)omx_base_filter_Private->bellagioThreads->nThreadBufferMngtID);

  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
  /* checks if the component is in a state able to receive buffers */
  while(omx_base_filter_Private->state == OMX_StateIdle || omx_base_filter_Private->state == OMX_StateExecuting ||  omx_base_filter_Private->state == OMX_StatePause ||
    omx_base_filter_Private->transientState == OMX_TransStateLoadedToIdle){

    /*Wait till the ports are being flushed*/
    pthread_mutex_lock(&omx_base_filter_Private->flush_mutex);
    while( PORT_IS_BEING_FLUSHED(pInPort) ||
           PORT_IS_BEING_FLUSHED(pOutPort)) {
      pthread_mutex_unlock(&omx_base_filter_Private->flush_mutex);

      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",
        __func__,inBufExchanged,isInputBufferNeeded,outBufExchanged,isOutputBufferNeeded,pInputSem->semval,pOutputSem->semval);

      if(isOutputBufferNeeded==OMX_FALSE && PORT_IS_BEING_FLUSHED(pOutPort)) {
        pOutPort->ReturnBufferFunction(pOutPort,pOutputBuffer);
        outBufExchanged--;
        pOutputBuffer=NULL;
        isOutputBufferNeeded=OMX_TRUE;
        DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output buffer\n");
      }

      if(isInputBufferNeeded==OMX_FALSE && PORT_IS_BEING_FLUSHED(pInPort)) {
        pInPort->ReturnBufferFunction(pInPort,pInputBuffer);
        inBufExchanged--;
        pInputBuffer=NULL;
        isInputBufferNeeded=OMX_TRUE;
        DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning input buffer\n");
      }

      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",
        __func__,inBufExchanged,isInputBufferNeeded,outBufExchanged,isOutputBufferNeeded,pInputSem->semval,pOutputSem->semval);

      tsem_up(omx_base_filter_Private->flush_all_condition);
      tsem_down(omx_base_filter_Private->flush_condition);
      pthread_mutex_lock(&omx_base_filter_Private->flush_mutex);
    }
    pthread_mutex_unlock(&omx_base_filter_Private->flush_mutex);

    /*No buffer to process. So wait here*/
    if((isInputBufferNeeded==OMX_TRUE && pInputSem->semval==0) &&
      (omx_base_filter_Private->state != OMX_StateLoaded && omx_base_filter_Private->state != OMX_StateInvalid)) {
      //Signaled from EmptyThisBuffer or FillThisBuffer or some thing else
      DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next input/output buffer\n");
      tsem_down(omx_base_filter_Private->bMgmtSem);

    }
    if(omx_base_filter_Private->state == OMX_StateLoaded || omx_base_filter_Private->state == OMX_StateInvalid) {
      DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
      break;
    }
    if((isOutputBufferNeeded==OMX_TRUE && pOutputSem->semval==0) &&
      (omx_base_filter_Private->state != OMX_StateLoaded && omx_base_filter_Private->state != OMX_StateInvalid) &&
       !(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
      //Signaled from EmptyThisBuffer or FillThisBuffer or some thing else
      DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next input/output buffer\n");
      tsem_down(omx_base_filter_Private->bMgmtSem);

    }
    if(omx_base_filter_Private->state == OMX_StateLoaded || omx_base_filter_Private->state == OMX_StateInvalid) {
      DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
      break;
    }

    DEBUG(DEB_LEV_FULL_SEQ, "Waiting for input buffer semval=%d in %s\n",pInputSem->semval, __func__);
    if(pInputSem->semval>0 && isInputBufferNeeded==OMX_TRUE ) {
      tsem_down(pInputSem);
      if(pInputQueue->nelem>0){
        inBufExchanged++;
        isInputBufferNeeded=OMX_FALSE;
        pInputBuffer = dequeue(pInputQueue);
        if(pInputBuffer == NULL){
          DEBUG(DEB_LEV_ERR, "Had NULL input buffer!!\n");
          break;
        }
      }
    }
    /*When we have input buffer to process then get one output buffer*/
    if(pOutputSem->semval>0 && isOutputBufferNeeded==OMX_TRUE) {
      tsem_down(pOutputSem);
      if(pOutputQueue->nelem>0){
        outBufExchanged++;
        isOutputBufferNeeded=OMX_FALSE;
        pOutputBuffer = dequeue(pOutputQueue);
        if(pOutputBuffer == NULL){
          DEBUG(DEB_LEV_ERR, "Had NULL output buffer!! op is=%d,iq=%d\n",pOutputSem->semval,pOutputQueue->nelem);
          break;
        }
      }
    }

    if(isInputBufferNeeded==OMX_FALSE) {
      if(pInputBuffer->hMarkTargetComponent != NULL){
        if((OMX_COMPONENTTYPE*)pInputBuffer->hMarkTargetComponent ==(OMX_COMPONENTTYPE *)openmaxStandComp) {
          /*Clear the mark and generate an event*/
          (*(omx_base_filter_Private->callbacks->EventHandler))
            (openmaxStandComp,
            omx_base_filter_Private->callbackData,
            OMX_EventMark, /* The command was completed */
            1, /* The commands was a OMX_CommandStateSet */
            0, /* The state has been changed in message->messageParam2 */
            pInputBuffer->pMarkData);
        } else {
          /*If this is not the target component then pass the mark*/
          omx_base_filter_Private->pMark.hMarkTargetComponent = pInputBuffer->hMarkTargetComponent;
          omx_base_filter_Private->pMark.pMarkData            = pInputBuffer->pMarkData;
        }
        pInputBuffer->hMarkTargetComponent = NULL;
      }
    }

    if(isInputBufferNeeded==OMX_FALSE && isOutputBufferNeeded==OMX_FALSE) {

      if(omx_base_filter_Private->pMark.hMarkTargetComponent != NULL){
        pOutputBuffer->hMarkTargetComponent = omx_base_filter_Private->pMark.hMarkTargetComponent;
        pOutputBuffer->pMarkData            = omx_base_filter_Private->pMark.pMarkData;
        omx_base_filter_Private->pMark.hMarkTargetComponent = NULL;
        omx_base_filter_Private->pMark.pMarkData            = NULL;
      }

      pOutputBuffer->nTimeStamp = pInputBuffer->nTimeStamp;
      if((pInputBuffer->nFlags & OMX_BUFFERFLAG_STARTTIME) == OMX_BUFFERFLAG_STARTTIME) {
         DEBUG(DEB_LEV_FULL_SEQ, "Detected  START TIME flag in the input buffer filled len=%d\n", (int)pInputBuffer->nFilledLen);
         pOutputBuffer->nFlags = pInputBuffer->nFlags;
         pInputBuffer->nFlags = 0;
      }

      if(omx_base_filter_Private->state == OMX_StateExecuting)  {
        if (omx_base_filter_Private->BufferMgmtCallback && pInputBuffer->nFilledLen > 0) {
          (*(omx_base_filter_Private->BufferMgmtCallback))(openmaxStandComp, pInputBuffer, pOutputBuffer);
        } else {
          /*It no buffer management call back the explicitly consume input buffer*/
          pInputBuffer->nFilledLen = 0;
        }
      } else if(!(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
        DEBUG(DEB_LEV_ERR, "In %s Received Buffer in non-Executing State(%x)\n", __func__, (int)omx_base_filter_Private->state);
      } else {
          pInputBuffer->nFilledLen = 0;
      }

      if((pInputBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS && pInputBuffer->nFilledLen==0) {
        DEBUG(DEB_LEV_FULL_SEQ, "Detected EOS flags in input buffer filled len=%d\n", (int)pInputBuffer->nFilledLen);
        pOutputBuffer->nFlags=pInputBuffer->nFlags;
        pInputBuffer->nFlags=0;
        (*(omx_base_filter_Private->callbacks->EventHandler))
          (openmaxStandComp,
          omx_base_filter_Private->callbackData,
          OMX_EventBufferFlag, /* The command was completed */
          1, /* The commands was a OMX_CommandStateSet */
          pOutputBuffer->nFlags, /* The state has been changed in message->messageParam2 */
          NULL);
        omx_base_filter_Private->bIsEOSReached = OMX_TRUE;
      }
      if(omx_base_filter_Private->state==OMX_StatePause && !(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
        /*Waiting at paused state*/
        tsem_wait(omx_base_filter_Private->bStateSem);
      }

      /*If EOS and Input buffer Filled Len Zero then Return output buffer immediately*/
      if((pOutputBuffer->nFilledLen != 0) || ((pOutputBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) || (omx_base_filter_Private->bIsEOSReached == OMX_TRUE)) {
        pOutPort->ReturnBufferFunction(pOutPort,pOutputBuffer);
        outBufExchanged--;
        pOutputBuffer=NULL;
        isOutputBufferNeeded=OMX_TRUE;
      }
    }

    if(omx_base_filter_Private->state==OMX_StatePause && !(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
      /*Waiting at paused state*/
      tsem_wait(omx_base_filter_Private->bStateSem);
    }

    /*Input Buffer has been completely consumed. So, return input buffer*/
    if((isInputBufferNeeded == OMX_FALSE) && (pInputBuffer->nFilledLen==0)) {
      pInPort->ReturnBufferFunction(pInPort,pInputBuffer);
      inBufExchanged--;
      pInputBuffer=NULL;
      isInputBufferNeeded=OMX_TRUE;
    }
  }
  DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s of component %p\n", __func__, openmaxStandComp);
  return NULL;
}
int main(int argc, char** argv) {
  OMX_ERRORTYPE err = OMX_ErrorNone;
  OMX_BOOL bOmxInitialized = OMX_FALSE;
  OMX_PARAM_PORTDEFINITIONTYPE sOmxPortDefinition;
  OMX_CONFIG_BOOLEANTYPE sOmxCapturing;
  OMX_CONFIG_BOOLEANTYPE sOmxAutoPause;
  OMX_STATETYPE sOmxState;
  OMX_U32 nBufferCount;
  OMX_U32 nBufferSize;
  OMX_U32 nPortIndex;
  OMX_U32 i;
  unsigned int nPreviewTime = 5;/* By default, running for 5 sec for preview */
  unsigned int nCaptureTime = 5;/* By default, running for 5 sec for video capture */
  char *cCaptureFileName = g_DefaultCaptureFileName;
  char *cThumbnailFileName = g_DefaultThumbnailFileName;
  OMX_BOOL bCameraStillImageMode = OMX_FALSE; /* By default, the camera is running in video capture mode */
  OMX_BOOL bCameraAutoPause = OMX_FALSE; /* By default, the camera is not running in autopause mode */
  unsigned int nMaxRunCount = 1;/* By default, running once */
  unsigned int nRunCount = 0;

  /* Parse arguments */
  for ( i = 1; i < argc && argv[i][0] == '-'; i++) {
    switch (argv[i][1]) {
      case 'i':
        bCameraStillImageMode = OMX_TRUE;
        break;

      case 'p':
        bCameraAutoPause = OMX_TRUE;
        break;

      case 't':
        i++;
        if (i>=argc ||argv[i][0] == '-') {
          DEBUG(DEB_LEV_ERR, "preview_time expected!\n");
          display_help(argv[0]);
          exit(-1);
        }
        nPreviewTime = (unsigned int)atoi(argv[i]);
        break;

      case 's':
        i++;
        if (i>=argc ||argv[i][0] == '-') {
          DEBUG(DEB_LEV_ERR, "capture_time expected!\n");
          display_help(argv[0]);
          exit(-1);
        }
        nCaptureTime = (unsigned int)atoi(argv[i]);
        break;

      case 'c':
        i++;
        if (i>=argc ||argv[i][0] == '-') {
          DEBUG(DEB_LEV_ERR, "capture_file expected!\n");
          display_help(argv[0]);
          exit(-1);
        }
        cCaptureFileName = argv[i];
        break;

      case 'm':
        i++;
        if (i>=argc ||argv[i][0] == '-') {
          DEBUG(DEB_LEV_ERR, "thumbnail_file expected!\n");
          display_help(argv[0]);
          exit(-1);
        }
        cThumbnailFileName = argv[i];
        break;

      case 'n':
        i++;
        if (i>=argc ||argv[i][0] == '-') {
          DEBUG(DEB_LEV_ERR, "run_count expected!\n");
          display_help(argv[0]);
          exit(-1);
        }
        nMaxRunCount = (unsigned int)atoi(argv[i]);
        break;

      case 'h':
        display_help(argv[0]);
        exit(0);
        break;

      default:
        DEBUG(DEB_LEV_ERR, "Unrecognized option -%c!\n", argv[i][1]);
        display_help(argv[0]);
        exit(-1);
      }
   }


  /* Init the Omx core */
  DEBUG(DEB_LEV_SIMPLE_SEQ, "Init the OMX core\n");
  if ((err = OMX_Init()) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "The OpenMAX core can not be initialized. Exiting...\n");
    goto EXIT;
  }
  bOmxInitialized =  OMX_TRUE;

  /* Initialize application private data */
  appPriv = malloc(sizeof(appPrivateType));
  if (appPriv == NULL) {
    DEBUG(DEB_LEV_ERR, "Allocate app private data failed!Exiting...\n");
    err = OMX_ErrorInsufficientResources;
    goto EXIT;
  }
  memset(appPriv, 0, sizeof(appPrivateType));

  memset(&sCameraPortBufferList, 0, NUM_CAMERAPORTS*sizeof(OMX_PORTBUFFERCTXT));

  /* Open output file for camera capture and thumbnail port */
  fCapture=fopen(cCaptureFileName, "wb");
  fThumbnail=fopen(cThumbnailFileName, "wb");


  /* Getting camera component handle */
  if ((err = OMX_GetHandle(&appPriv->camerahandle, "OMX.st.v4l.camera_source", appPriv, &camera_source_callbacks)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Getting camera component handle failed!Exiting...\n");
    goto EXIT;
  }

  /* Getting fbsink component handle */
  if ((err = OMX_GetHandle(&appPriv->colorconvhandle, "OMX.st.video_colorconv.ffmpeg", appPriv, &colorconv_callbacks)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Getting color conv component handle failed!Exiting...\n");
    goto EXIT;
  }

  /* Getting fbsink component handle */
  if ((err = OMX_GetHandle(&appPriv->fbsinkhandle, "OMX.st.fbdev.fbdev_sink", appPriv, &fbsink_callbacks)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Getting fbsink component handle failed!Exiting...\n");
    goto EXIT;
  }

  /* Setting parameters for camera component */
  if ((err = setCameraParameters(bCameraStillImageMode)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Set camera parameters failed! Use default settings...\n");
    /* Do not exit! */
  }

  /* Setting parameters for color converter component */
  if ((err = setColorConvParameters()) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Set fbsink parameters failed! Use default settings...\n");
    /* Do not exit! */
  }


  /* Setting parameters for fbsink component */
  if ((err = setFbsinkParameters()) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Set fbsink parameters failed! Use default settings...\n");
    /* Do not exit! */
  }

  /* Allocate and init semaphores */
  appPriv->cameraSourceEventSem = malloc(sizeof(tsem_t));
  if (appPriv->cameraSourceEventSem == NULL) {
    DEBUG(DEB_LEV_ERR, "Allocate camera event semaphore failed!Exiting...\n");
    err = OMX_ErrorInsufficientResources;
    goto EXIT;
  }
  tsem_init(appPriv->cameraSourceEventSem, 0);

  appPriv->fbsinkEventSem = malloc(sizeof(tsem_t));
  if (appPriv->fbsinkEventSem == NULL) {
    DEBUG(DEB_LEV_ERR, "Allocate fbsink event semaphore failed!Exiting...\n");
    err = OMX_ErrorInsufficientResources;
    goto EXIT;
  }
  tsem_init(appPriv->fbsinkEventSem, 0);

  appPriv->colorconvEventSem = malloc(sizeof(tsem_t));
  if (appPriv->colorconvEventSem == NULL) {
    DEBUG(DEB_LEV_ERR, "Allocate colorconv event semaphore failed!Exiting...\n");
    err = OMX_ErrorInsufficientResources;
    goto EXIT;
  }
  tsem_init(appPriv->colorconvEventSem, 0);

  /* Setup tunnel between camera preview port, color converter and fbsink */
  if ((err = OMX_SetupTunnel(appPriv->camerahandle, OMX_CAMPORT_INDEX_VF, appPriv->colorconvhandle, 0)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Setup tunnel between camera preview port and color converter failed!Exiting...\n");
    goto EXIT;
  }
  if ((err = OMX_SetupTunnel(appPriv->colorconvhandle, 1, appPriv->fbsinkhandle, 0)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Setup tunnel between color conv port and fbsink failed!Exiting...\n");
    goto EXIT;
  }

RUN_AGAIN:

  /* Transition camera component Loaded-->Idle */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Loaded-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition color conv component Loaded-->Idle */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Color Conv Loaded-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Loaded-->Idle */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Loaded-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Allocate port buffers for camera component */
  for (nPortIndex = OMX_CAMPORT_INDEX_CP; nPortIndex <= OMX_CAMPORT_INDEX_CP_T; nPortIndex++) {
    setHeader(&sOmxPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
    sOmxPortDefinition.nPortIndex = nPortIndex;
    if ((err = OMX_GetParameter(appPriv->camerahandle, OMX_IndexParamPortDefinition, &sOmxPortDefinition)) != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "OMX_GetParameter for camera on OMX_IndexParamPortDefinition index failed!Exiting...\n");
      goto EXIT;
    }
    nBufferCount = sOmxPortDefinition.nBufferCountActual;
    nBufferSize = sOmxPortDefinition.nBufferSize;
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Camera port[%ld] needs %ld buffers each of which is %ld bytes\n", nPortIndex, nBufferCount, nBufferSize);

    for (i = 0; i < nBufferCount; i++) {
      if ((err = OMX_AllocateBuffer(appPriv->camerahandle, &sCameraPortBufferList[nPortIndex].pBufHeaderList[i], nPortIndex, NULL, nBufferSize)) != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR, "Allocate port buffer for camera failed!Exiting...\n");
        goto EXIT;
      }
      sCameraPortBufferList[nPortIndex].nBufferCountActual++;
    }
  }

  /* Wait camera (Loaded-->Idle) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait fbsink (Loaded-->Idle) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Loaded-->Idle) to complete */
  tsem_down(appPriv->fbsinkEventSem);



  /* Transition camera component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition color conv component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Colorconv Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Wait camera (Idle-->Exec) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait color conv (Idle-->Exec) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Idle-->Exec) to complete */
  tsem_down(appPriv->fbsinkEventSem);


  fprintf(stdout, "Start preview, for %d sec...\n", nPreviewTime);
  sleep(nPreviewTime);

  /* Fill buffers to camera capture port */
  for (i = 0; i < sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].nBufferCountActual; i++) {
    sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]->nFilledLen = 0;
    sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]->nOffset = 0;
    if ((err = OMX_FillThisBuffer(appPriv->camerahandle, sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i])) != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Fill buffer to camera capture port failed!Exiting...\n");
      goto EXIT;
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Fill buffer[%ld] (0x%lX) to camera capture port\n", __func__, i, (OMX_U32)sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]);
  }

  /* Fill buffers to camera thumbnail port */
  for (i = 0; i < sCameraPortBufferList[OMX_CAMPORT_INDEX_CP_T].nBufferCountActual; i++) {
    sCameraPortBufferList[OMX_CAMPORT_INDEX_CP_T].pBufHeaderList[i]->nFilledLen = 0;
    sCameraPortBufferList[OMX_CAMPORT_INDEX_CP_T].pBufHeaderList[i]->nOffset = 0;
    if ((err = OMX_FillThisBuffer(appPriv->camerahandle, sCameraPortBufferList[OMX_CAMPORT_INDEX_CP_T].pBufHeaderList[i])) != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Fill buffer to camera capture port failed!Exiting...\n");
      goto EXIT;
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Fill buffer[%ld] (0x%lX) to camera capture port\n", __func__, i, (OMX_U32)sCameraPortBufferList[OMX_CAMPORT_INDEX_CP_T].pBufHeaderList[i]);
  }

  /* Set up autopause mode */
  setHeader(&sOmxAutoPause, sizeof(OMX_CONFIG_BOOLEANTYPE));
  sOmxAutoPause.bEnabled = bCameraAutoPause;
  if ((err = OMX_SetConfig(appPriv->camerahandle, OMX_IndexAutoPauseAfterCapture, &sOmxAutoPause)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Set autopause mode failed!Use default settings...\n");
    /* Do not exit */
  }

  /*  Start capturing */
  setHeader(&sOmxCapturing, sizeof(OMX_CONFIG_BOOLEANTYPE));
  sOmxCapturing.bEnabled = OMX_TRUE;
  if ((err = OMX_SetConfig(appPriv->camerahandle, OMX_IndexConfigCapturing, &sOmxCapturing)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Start capturing failed!Exiting...\n");
    goto EXIT;
  }

  fprintf(stdout, "Start capturing, for %d sec...\n", nCaptureTime);
  sleep(nCaptureTime);

  /*  Stop capturing */
  if (!bCameraStillImageMode) {
    setHeader(&sOmxCapturing, sizeof(OMX_CONFIG_BOOLEANTYPE));
    sOmxCapturing.bEnabled = OMX_FALSE;
    if ((err = OMX_SetConfig(appPriv->camerahandle, OMX_IndexConfigCapturing, &sOmxCapturing)) != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Stop capturing failed!Exiting...\n");
      goto EXIT;
    }
    fprintf(stdout, "Stop capturing...\n");
  }

  /* If in autopause mode, stay for a while before exit */
  if (bCameraAutoPause) {
    fprintf(stdout, "Now the camera is in autopause mode, wait for %d sec before out of this mode...\n", 5);
    sleep(5);
    /* Stop autopause mode */
    if ((err = OMX_GetState(appPriv->camerahandle,&sOmxState)) != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Get camera state failed!Exiting...\n");
      goto EXIT;
    }
    if (sOmxState == OMX_StatePause) {
      if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet,
                                                      OMX_StateExecuting, 0 )) != OMX_ErrorNone ) {
        DEBUG(DEB_LEV_ERR, "Pause-->Exec failed!Exiting...\n");
        goto EXIT;
      }
      /* Wait camera (Pause-->Exec) to complete */
      tsem_down(appPriv->cameraSourceEventSem);
      fprintf(stdout, "Now the camera is out of autopause mode, wait for %d sec before exit...\n", 5);
      sleep(5);
    }
    else {
      DEBUG(DEB_LEV_ERR, "The camera is not in Pause state in autopause mode, ignore...\n");
    }
  }

  /* Transition camera component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition colorconv component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Color conv Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Wait camera (Exec-->Idle) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait color conv (Exec-->Idle) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Exec-->Idle) to complete */
  tsem_down(appPriv->fbsinkEventSem);


  /* Transition camera component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition color conv component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Colorconv Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Wait camera (Idle-->Exec) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait color conv (Exec-->Idle) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Idle-->Exec) to complete */
  tsem_down(appPriv->fbsinkEventSem);

  fprintf(stdout, "Continue to preview, for %d sec...\n", nPreviewTime);
  sleep(nPreviewTime);

  /* Transition camera component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition color conv component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Color conv Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }


  /* Wait camera (Exec-->Idle) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait color conv (Exec-->Idle) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Exec-->Idle) to complete */
  tsem_down(appPriv->fbsinkEventSem);


  /* Transition camera component Idle-->Loaded */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Idle-->Loaded failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition color conv component Idle-->Loaded */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Color conv Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Idle-->Loaded */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Idle-->Loaded failed!Exiting...\n");
    goto EXIT;
  }

  /* Free bufers for each non-tunneled port of camera component */
  for (nPortIndex = OMX_CAMPORT_INDEX_CP; nPortIndex <= OMX_CAMPORT_INDEX_CP_T; nPortIndex++) {
    for (i = 0; i < sCameraPortBufferList[nPortIndex].nBufferCountActual; i++) {
      if (sCameraPortBufferList[nPortIndex].pBufHeaderList[i] != NULL) {
        OMX_FreeBuffer(appPriv->camerahandle, nPortIndex, sCameraPortBufferList[nPortIndex].pBufHeaderList[i]);
      }
    }
    sCameraPortBufferList[nPortIndex].nBufferCountActual = 0;
  }

  /* Wait camera (Idle-->Loaded) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait color conv (Exec-->Idle) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Idle-->Loaded) to complete */
  tsem_down(appPriv->fbsinkEventSem);

  nRunCount++;
  if (nRunCount < nMaxRunCount) {
    goto RUN_AGAIN;
  }

  fprintf(stdout, "The captured videos are saved in file \"%s\"\n", cCaptureFileName);
  fprintf(stdout, "The thumbnail image is saved in file \"%s\"\n", cThumbnailFileName);

EXIT:
  if (fCapture != NULL) {
    fclose(fCapture);
  }
  if (fThumbnail != NULL) {
    fclose(fThumbnail);
  }

  /* Free app private data */
  if (appPriv != NULL) {
    /* Free semaphores */
    if (appPriv->cameraSourceEventSem != NULL) {
      tsem_deinit(appPriv->cameraSourceEventSem);
      free(appPriv->cameraSourceEventSem);
    }

    if (appPriv->colorconvEventSem != NULL) {
      tsem_deinit(appPriv->colorconvEventSem);
      free(appPriv->colorconvEventSem);
    }

    if (appPriv->fbsinkEventSem != NULL) {
      tsem_deinit(appPriv->fbsinkEventSem);
      free(appPriv->fbsinkEventSem);
    }

    /* Free camera component handle */
    if (appPriv->camerahandle != NULL) {
      OMX_FreeHandle(appPriv->camerahandle);
    }
    /* Free Color conv component handle */
    if (appPriv->colorconvhandle != NULL) {
      OMX_FreeHandle(appPriv->colorconvhandle);
    }

    /* Free fbsink component handle */
    if (appPriv->fbsinkhandle != NULL) {
      OMX_FreeHandle(appPriv->fbsinkhandle);
    }

    free(appPriv);
  }

  /* Deinit the Omx core */
  if (bOmxInitialized) {
    OMX_Deinit();
  }

  return (int) err;
}
int main(int argc, char** argv) {

  OMX_ERRORTYPE err;
  int argn_dec;
  OMX_STRING full_component_name;

  if(argc < 2){
    display_help();
  } else {
    flagIsOutputExpected = 0;
    argn_dec = 1;
    while (argn_dec < argc) {
      if (*(argv[argn_dec]) == '-') {
        if (flagIsOutputExpected) {
          display_help();
        }
        switch (*(argv[argn_dec] + 1)) {
          case 'h' :
            display_help();
            break;
          case 'o':
            flagIsOutputExpected = 1;
            break;
          default:
            display_help();
        }
      } else {
        if (flagIsOutputExpected) {
          if(strstr(argv[argn_dec], ".yuv") == NULL && strstr(argv[argn_dec], ".rgb") == NULL) {
            output_file = malloc(strlen(argv[argn_dec]) * sizeof(char) + 5);
            strcpy(output_file,argv[argn_dec]);
            strcat(output_file, ".rgb");
          } else {
            output_file = malloc(strlen(argv[argn_dec]) * sizeof(char) + 1);
            strcpy(output_file,argv[argn_dec]);
          }
          flagIsOutputExpected = 0;
        }
      }
      argn_dec++;
    }
  }

  if(output_file==NULL) {
    output_file = malloc(30);
    strcpy(output_file,"default_camera_out.rgb");
  }

  outfile = fopen(output_file, "wb");
  if(outfile == NULL) {
    DEBUG(DEB_LEV_ERR, "Error in opening output file %s\n", output_file);
    exit(1);
  }

  /** setting input picture width to a default value (vga format) for allocation of video videosrc buffers */
  out_width = 176;
  out_height = 144;

  /* Initialize application private data */
  appPriv = malloc(sizeof(appPrivateType));
  appPriv->videosrcEventSem = malloc(sizeof(tsem_t));
  appPriv->eofSem = malloc(sizeof(tsem_t));
  tsem_init(appPriv->videosrcEventSem, 0);
  tsem_init(appPriv->eofSem, 0);

  DEBUG(DEB_LEV_SIMPLE_SEQ, "Init the Omx core\n");
  err = OMX_Init();
  if (err != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "The OpenMAX core can not be initialized. Exiting...\n");
    exit(1);
  } else {
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Omx core is initialized \n");
  }

  test_OpenClose(COMPONENT_NAME);
  DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");


  full_component_name = (OMX_STRING) malloc(sizeof(char*) * OMX_MAX_STRINGNAME_SIZE);
  strcpy(full_component_name, COMPONENT_NAME);


  DEBUG(DEFAULT_MESSAGES, "The component selected for capturing is %s\n", full_component_name);

  /** getting video videosrc handle */
  err = OMX_GetHandle(&appPriv->videosrchandle, full_component_name, NULL, &videosrccallbacks);
  if(err != OMX_ErrorNone){
    DEBUG(DEB_LEV_ERR, "No video videosrc component found. Exiting...\n");
    exit(1);
  } else {
    DEBUG(DEFAULT_MESSAGES, "Found The component for capturing is %s\n", full_component_name);
  }

  /** output buffer size calculation based on input dimension speculation */
  buffer_out_size = out_width * out_height * 3; //yuv420 format -- bpp = 12
  DEBUG(DEB_LEV_SIMPLE_SEQ, "\n buffer_out_size : %d \n", (int)buffer_out_size);

  /** sending command to video videosrc component to go to idle state */
  err = OMX_SendCommand(appPriv->videosrchandle, OMX_CommandStateSet, OMX_StateIdle, NULL);

  pOutBuffer1 = pOutBuffer2 = NULL;
  err = OMX_AllocateBuffer(appPriv->videosrchandle, &pOutBuffer1, 0, NULL, buffer_out_size);
  err = OMX_AllocateBuffer(appPriv->videosrchandle, &pOutBuffer2, 0, NULL, buffer_out_size);


  DEBUG(DEB_LEV_SIMPLE_SEQ, "Before locking on idle wait semaphore\n");
  tsem_down(appPriv->videosrcEventSem);
  DEBUG(DEB_LEV_SIMPLE_SEQ, "videosrc Sem free\n");

  /** sending command to video videosrc component to go to executing state */
  err = OMX_SendCommand(appPriv->videosrchandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
  tsem_down(appPriv->videosrcEventSem);

  err = OMX_FillThisBuffer(appPriv->videosrchandle, pOutBuffer1);
  err = OMX_FillThisBuffer(appPriv->videosrchandle, pOutBuffer2);

  DEBUG(DEFAULT_MESSAGES,"Waiting for  EOS\n");

  /*Capture video for 10 seconds*/
  sleep(10);
  bEOS = OMX_TRUE;
  DEBUG(DEFAULT_MESSAGES,"Set  EOS\n");
  sleep(1);
  //tsem_down(appPriv->eofSem);

  DEBUG(DEFAULT_MESSAGES, "The execution of the video capturing process is terminated\n");

  /** state change of all components from executing to idle */
  err = OMX_SendCommand(appPriv->videosrchandle, OMX_CommandStateSet, OMX_StateIdle, NULL);

  tsem_down(appPriv->videosrcEventSem);


  DEBUG(DEFAULT_MESSAGES, "All video components Transitioned to Idle\n");

  /** sending command to all components to go to loaded state */
  err = OMX_SendCommand(appPriv->videosrchandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);


  /** freeing buffers of video videosrc input ports */
  DEBUG(DEB_LEV_PARAMS, "Free Video dec output ports\n");
  err = OMX_FreeBuffer(appPriv->videosrchandle, 0, pOutBuffer1);
  err = OMX_FreeBuffer(appPriv->videosrchandle, 0, pOutBuffer2);

  tsem_down(appPriv->videosrcEventSem);
  DEBUG(DEB_LEV_SIMPLE_SEQ, "All components released\n");

  OMX_FreeHandle(appPriv->videosrchandle);

  DEBUG(DEB_LEV_SIMPLE_SEQ, "video dec freed\n");

  OMX_Deinit();

  DEBUG(DEFAULT_MESSAGES, "All components freed. Closing...\n");
  free(appPriv->videosrcEventSem);

  free(appPriv->eofSem);
  free(appPriv);

  /** closing the output file */
  fclose(outfile);

  return 0;
}
void* omx_base_source_twoport_BufferMgmtFunction (void* param) {
  OMX_COMPONENTTYPE* openmaxStandComp = (OMX_COMPONENTTYPE*)param;
  omx_base_component_PrivateType* omx_base_component_Private=(omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
  omx_base_source_PrivateType* omx_base_source_Private = (omx_base_source_PrivateType*)omx_base_component_Private;
  omx_base_PortType *pOutPort[2];
  tsem_t* pOutputSem[2];
  queue_t* pOutputQueue[2];
  OMX_BUFFERHEADERTYPE* pOutputBuffer[2];
  OMX_COMPONENTTYPE* target_component;
  OMX_BOOL isOutputBufferNeeded[2];
  int i,outBufExchanged[2];

  pOutPort[0]=(omx_base_PortType *)omx_base_source_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX];
  pOutPort[1]=(omx_base_PortType *)omx_base_source_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX_1];
  pOutputSem[0] = pOutPort[0]->pBufferSem;
  pOutputSem[1] = pOutPort[1]->pBufferSem;
  pOutputQueue[0] = pOutPort[0]->pBufferQueue;
  pOutputQueue[1] = pOutPort[1]->pBufferQueue;
  pOutputBuffer[1]= pOutputBuffer[0]=NULL;
  isOutputBufferNeeded[0]=isOutputBufferNeeded[1]=OMX_TRUE;
  outBufExchanged[0]=outBufExchanged[1]=0;

  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
  while(omx_base_source_Private->state == OMX_StateIdle || omx_base_source_Private->state == OMX_StateExecuting ||  omx_base_source_Private->state == OMX_StatePause ||
    omx_base_source_Private->transientState == OMX_TransStateLoadedToIdle){

    /*Wait till the ports are being flushed*/
    pthread_mutex_lock(&omx_base_source_Private->flush_mutex);
    while( PORT_IS_BEING_FLUSHED(pOutPort[0]) ||
           PORT_IS_BEING_FLUSHED(pOutPort[1])) {
      pthread_mutex_unlock(&omx_base_source_Private->flush_mutex);

      DEBUG(DEB_LEV_FULL_SEQ, "In %s 1 signalling flush all cond iE=%d,iF=%d,oE=%d,oF=%d iSemVal=%d,oSemval=%d\n",
        __func__,outBufExchanged[0],isOutputBufferNeeded[0],outBufExchanged[1],isOutputBufferNeeded[1],pOutputSem[0]->semval,pOutputSem[1]->semval);

      if(isOutputBufferNeeded[1]==OMX_FALSE && PORT_IS_BEING_FLUSHED(pOutPort[1])) {
        pOutPort[1]->ReturnBufferFunction(pOutPort[1],pOutputBuffer[1]);
        outBufExchanged[1]--;
        pOutputBuffer[1]=NULL;
        isOutputBufferNeeded[1]=OMX_TRUE;
        DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output 1 buffer\n");
      }

      if(isOutputBufferNeeded[0]==OMX_FALSE && PORT_IS_BEING_FLUSHED(pOutPort[0])) {
        pOutPort[0]->ReturnBufferFunction(pOutPort[0],pOutputBuffer[0]);
        outBufExchanged[0]--;
        pOutputBuffer[0]=NULL;
        isOutputBufferNeeded[0]=OMX_TRUE;
        DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output 0 buffer\n");
      }

      DEBUG(DEB_LEV_FULL_SEQ, "In %s 2 signalling flush all cond iE=%d,iF=%d,oE=%d,oF=%d iSemVal=%d,oSemval=%d\n",
        __func__,outBufExchanged[0],isOutputBufferNeeded[0],outBufExchanged[1],isOutputBufferNeeded[1],pOutputSem[0]->semval,pOutputSem[1]->semval);

      tsem_up(omx_base_source_Private->flush_all_condition);
      tsem_down(omx_base_source_Private->flush_condition);
      pthread_mutex_lock(&omx_base_source_Private->flush_mutex);
    }
    pthread_mutex_unlock(&omx_base_source_Private->flush_mutex);

    /*No buffer to process. So wait here*/
    if((isOutputBufferNeeded[0]==OMX_TRUE && pOutputSem[0]->semval==0) &&
      (omx_base_source_Private->state != OMX_StateLoaded && omx_base_source_Private->state != OMX_StateInvalid)) {
      //Signalled from EmptyThisBuffer or FillThisBuffer or some thing else
      DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next output buffer 0\n");
      tsem_down(omx_base_source_Private->bMgmtSem);

    }
    if(omx_base_source_Private->state == OMX_StateLoaded || omx_base_source_Private->state == OMX_StateInvalid) {
      DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
      break;
    }
    if((isOutputBufferNeeded[1]==OMX_TRUE && pOutputSem[1]->semval==0) &&
      (omx_base_source_Private->state != OMX_StateLoaded && omx_base_source_Private->state != OMX_StateInvalid) &&
       !(PORT_IS_BEING_FLUSHED(pOutPort[0]) || PORT_IS_BEING_FLUSHED(pOutPort[1]))) {
      //Signalled from EmptyThisBuffer or FillThisBuffer or some thing else
      DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next output buffer 1\n");
      tsem_down(omx_base_source_Private->bMgmtSem);

    }
    if(omx_base_source_Private->state == OMX_StateLoaded || omx_base_source_Private->state == OMX_StateInvalid) {
      DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
      break;
    }

    DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for output buffer 0 semval=%d \n",pOutputSem[0]->semval);
    if(pOutputSem[0]->semval>0 && isOutputBufferNeeded[0]==OMX_TRUE ) {
      tsem_down(pOutputSem[0]);
      if(pOutputQueue[0]->nelem>0){
        outBufExchanged[0]++;
        isOutputBufferNeeded[0]=OMX_FALSE;
        pOutputBuffer[0] = dequeue(pOutputQueue[0]);
        if(pOutputBuffer[0] == NULL){
          DEBUG(DEB_LEV_ERR, "Had NULL output buffer!!\n");
          break;
        }
      }
    }
    /*When we have input buffer to process then get one output buffer*/
    if(pOutputSem[1]->semval>0 && isOutputBufferNeeded[1]==OMX_TRUE) {
      tsem_down(pOutputSem[1]);
      if(pOutputQueue[1]->nelem>0){
        outBufExchanged[1]++;
        isOutputBufferNeeded[1]=OMX_FALSE;
        pOutputBuffer[1] = dequeue(pOutputQueue[1]);
        if(pOutputBuffer[1] == NULL){
          DEBUG(DEB_LEV_ERR, "Had NULL output buffer!! op is=%d,iq=%d\n",pOutputSem[1]->semval,pOutputQueue[1]->nelem);
          break;
        }
      }
    }

    for(i=0;i < (omx_base_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts  +
                 omx_base_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts +
                 omx_base_component_Private->sPortTypesParam[OMX_PortDomainImage].nPorts +
                 omx_base_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts -1);i++) {

      if(omx_base_source_Private->ports[i]->sPortParam.eDomain!=OMX_PortDomainOther){ /* clock ports are not to be processed */
        /*Process Output buffer of Port i */
        if(isOutputBufferNeeded[i]==OMX_FALSE) {

          /*Pass the Mark to all outgoing buffers*/
          if(omx_base_source_Private->pMark.hMarkTargetComponent != NULL){
            pOutputBuffer[i]->hMarkTargetComponent = omx_base_source_Private->pMark.hMarkTargetComponent;
            pOutputBuffer[i]->pMarkData            = omx_base_source_Private->pMark.pMarkData;
          }

          target_component=(OMX_COMPONENTTYPE*)pOutputBuffer[i]->hMarkTargetComponent;
          if(target_component==(OMX_COMPONENTTYPE *)openmaxStandComp) {
            /*Clear the mark and generate an event*/
            (*(omx_base_source_Private->callbacks->EventHandler))
              (openmaxStandComp,
              omx_base_source_Private->callbackData,
              OMX_EventMark, /* The command was completed */
              1, /* The commands was a OMX_CommandStateSet */
              i, /* The state has been changed in message->messageParam2 */
              pOutputBuffer[i]->pMarkData);
          } else if(pOutputBuffer[i]->hMarkTargetComponent!=NULL){
            /*If this is not the target component then pass the mark*/
            DEBUG(DEB_LEV_FULL_SEQ, "Pass Mark. This is a Source!!\n");
          }

          if(omx_base_source_Private->state == OMX_StateExecuting)  {
            if (omx_base_source_Private->BufferMgmtCallback && pOutputBuffer[i]->nFilledLen == 0) {
              (*(omx_base_source_Private->BufferMgmtCallback))(openmaxStandComp, pOutputBuffer[i]);
            } else {
              /*If no buffer management call back then don't produce any output buffer*/
              pOutputBuffer[i]->nFilledLen = 0;
            }
          } else {
            DEBUG(DEB_LEV_ERR, "In %s Received Buffer in non-Executing State(%x)\n", __func__, (int)omx_base_source_Private->state);
          }

          if((pOutputBuffer[i]->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS && pOutputBuffer[i]->nFilledLen==0) {
            DEBUG(DEB_LEV_FULL_SEQ, "Detected EOS flags in input buffer filled len=%d\n", (int)pOutputBuffer[i]->nFilledLen);
            (*(omx_base_source_Private->callbacks->EventHandler))
              (openmaxStandComp,
              omx_base_source_Private->callbackData,
              OMX_EventBufferFlag, /* The command was completed */
              i, /* The commands was a OMX_CommandStateSet */
              pOutputBuffer[i]->nFlags, /* The state has been changed in message->messageParam2 */
              NULL);
          }
          if(omx_base_source_Private->state==OMX_StatePause && !(PORT_IS_BEING_FLUSHED(pOutPort[0]) || PORT_IS_BEING_FLUSHED(pOutPort[1]))) {
            /*Waiting at paused state*/
            tsem_wait(omx_base_component_Private->bStateSem);
          }

           /*Output Buffer has been produced or EOS. So, return output buffer and get new buffer*/
          if(pOutputBuffer[i]->nFilledLen!=0 || (pOutputBuffer[i]->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS){
            pOutPort[i]->ReturnBufferFunction(pOutPort[i],pOutputBuffer[i]);
            outBufExchanged[i]--;
            pOutputBuffer[i]=NULL;
            isOutputBufferNeeded[i]=OMX_TRUE;
          }
        }
      }
    }

    /*Clear the Mark*/
    if(omx_base_source_Private->pMark.hMarkTargetComponent != NULL){
      omx_base_source_Private->pMark.hMarkTargetComponent = NULL;
      omx_base_source_Private->pMark.pMarkData            = NULL;
    }
  }
  DEBUG(DEB_LEV_SIMPLE_SEQ,"Exiting Buffer Management Thread\n");
  return NULL;
}
/** This is the central function for component processing. It
  * is executed in a separate thread, is synchronized with
  * semaphores at each port, those are released each time a new buffer
  * is available on the given port.
  */
void* omx_base_source_BufferMgmtFunction (void* param) {

  OMX_COMPONENTTYPE* openmaxStandComp = (OMX_COMPONENTTYPE*)param;
  omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
  omx_base_source_PrivateType* omx_base_source_Private = (omx_base_source_PrivateType*)omx_base_component_Private;
  omx_base_PortType *pOutPort = (omx_base_PortType *)omx_base_source_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX];
  tsem_t* pOutputSem = pOutPort->pBufferSem;
  queue_t* pOutputQueue = pOutPort->pBufferQueue;
  OMX_BUFFERHEADERTYPE* pOutputBuffer = NULL;
  OMX_COMPONENTTYPE* target_component;
  OMX_BOOL isOutputBufferNeeded = OMX_TRUE;
  int outBufExchanged = 0;

  omx_base_source_Private->bellagioThreads->nThreadBufferMngtID = (long int)syscall(__NR_gettid);
  DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s the thread ID is %i\n", __func__, (int)omx_base_source_Private->bellagioThreads->nThreadBufferMngtID);

  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s \n", __func__);
  while(omx_base_component_Private->state == OMX_StateIdle || omx_base_component_Private->state == OMX_StateExecuting ||
    omx_base_component_Private->state == OMX_StatePause || omx_base_component_Private->transientState == OMX_TransStateLoadedToIdle){

    /*Wait till the ports are being flushed*/
    pthread_mutex_lock(&omx_base_source_Private->flush_mutex);
    while( PORT_IS_BEING_FLUSHED(pOutPort)) {
      pthread_mutex_unlock(&omx_base_source_Private->flush_mutex);

      if(isOutputBufferNeeded == OMX_FALSE) {
        pOutPort->ReturnBufferFunction(pOutPort, pOutputBuffer);
        outBufExchanged--;
        pOutputBuffer = NULL;
        isOutputBufferNeeded = OMX_TRUE;
        DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output buffer\n");
      }
      DEBUG(DEB_LEV_FULL_SEQ, "In %s signalling flush all condition \n", __func__);

      tsem_up(omx_base_source_Private->flush_all_condition);
      tsem_down(omx_base_source_Private->flush_condition);
      pthread_mutex_lock(&omx_base_source_Private->flush_mutex);
    }
    pthread_mutex_unlock(&omx_base_source_Private->flush_mutex);

    /*No buffer to process. So wait here*/
    if((isOutputBufferNeeded==OMX_TRUE && pOutputSem->semval==0) &&
      (omx_base_source_Private->state != OMX_StateLoaded && omx_base_source_Private->state != OMX_StateInvalid)) {
      DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for output buffer \n");
      tsem_down(omx_base_source_Private->bMgmtSem);
    }

    if(omx_base_source_Private->state == OMX_StateLoaded || omx_base_source_Private->state == OMX_StateInvalid) {
      DEBUG(DEB_LEV_FULL_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
      break;
    }

    DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for output buffer semval=%d \n",pOutputSem->semval);
    if(pOutputSem->semval > 0 && isOutputBufferNeeded == OMX_TRUE ) {
      tsem_down(pOutputSem);
      if(pOutputQueue->nelem>0){
        outBufExchanged++;
        isOutputBufferNeeded = OMX_FALSE;
        pOutputBuffer = dequeue(pOutputQueue);
        if(pOutputBuffer == NULL){
          DEBUG(DEB_LEV_ERR, "In %s Had NULL output buffer!!\n",__func__);
          break;
        }
      }
    }

    if(isOutputBufferNeeded == OMX_FALSE) {
      if((pOutputBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
        pOutputBuffer->nFlags = 0;
      }

      if(omx_base_source_Private->pMark.hMarkTargetComponent != NULL){
        pOutputBuffer->hMarkTargetComponent = omx_base_source_Private->pMark.hMarkTargetComponent;
        pOutputBuffer->pMarkData            = omx_base_source_Private->pMark.pMarkData;
        omx_base_source_Private->pMark.hMarkTargetComponent = NULL;
        omx_base_source_Private->pMark.pMarkData            = NULL;
      }

      target_component = (OMX_COMPONENTTYPE*)pOutputBuffer->hMarkTargetComponent;
      if(target_component == (OMX_COMPONENTTYPE *)openmaxStandComp) {
        /*Clear the mark and generate an event*/
        (*(omx_base_component_Private->callbacks->EventHandler))
          (openmaxStandComp,
          omx_base_component_Private->callbackData,
          OMX_EventMark, /* The command was completed */
          1, /* The commands was a OMX_CommandStateSet */
          0, /* The state has been changed in message->messageParam2 */
          pOutputBuffer->pMarkData);
      } else if(pOutputBuffer->hMarkTargetComponent != NULL) {
        /*If this is not the target component then pass the mark*/
        DEBUG(DEB_LEV_FULL_SEQ, "Pass Mark. This is a Source!!\n");
      }

      if(omx_base_source_Private->state == OMX_StateExecuting)  {
        if (omx_base_source_Private->BufferMgmtCallback && pOutputBuffer->nFilledLen == 0) {
          (*(omx_base_source_Private->BufferMgmtCallback))(openmaxStandComp, pOutputBuffer);
        } else {
          /*It no buffer management call back then don't produce any output buffer*/
          pOutputBuffer->nFilledLen = 0;
        }
      } else {
        DEBUG(DEB_LEV_ERR, "In %s Received Buffer in non-Executing State(%x)\n", __func__, (int)omx_base_source_Private->state);
      }
      if(omx_base_source_Private->state == OMX_StatePause && !PORT_IS_BEING_FLUSHED(pOutPort)) {
        /*Waiting at paused state*/
        tsem_wait(omx_base_source_Private->bStateSem);
      }

      if((pOutputBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
        DEBUG(DEB_LEV_SIMPLE_SEQ, "Detected EOS flags in output buffer\n");

        (*(omx_base_component_Private->callbacks->EventHandler))
          (openmaxStandComp,
          omx_base_component_Private->callbackData,
          OMX_EventBufferFlag, /* The command was completed */
          0, /* The commands was a OMX_CommandStateSet */
          pOutputBuffer->nFlags, /* The state has been changed in message->messageParam2 */
          NULL);
        //pOutputBuffer->nFlags = 0;
        omx_base_source_Private->bIsEOSReached = OMX_TRUE;
      }

      /*Output Buffer has been produced or EOS. So, return output buffer and get new buffer*/
      if((pOutputBuffer->nFilledLen != 0) || ((pOutputBuffer->nFlags & OMX_BUFFERFLAG_EOS) ==OMX_BUFFERFLAG_EOS) || (omx_base_source_Private->bIsEOSReached == OMX_TRUE)) {
    	  if((pOutputBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
    		  DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nFlags=%x Name=%s \n", __func__, (int)pOutputBuffer->nFlags, omx_base_source_Private->name);
    	  pOutPort->ReturnBufferFunction(pOutPort, pOutputBuffer);
    	  outBufExchanged--;
    	  pOutputBuffer = NULL;
    	  isOutputBufferNeeded = OMX_TRUE;
      }
    }
  }
  DEBUG(DEB_LEV_SIMPLE_SEQ, "Exiting Buffer Management Thread\n");
  return NULL;
}
Exemple #18
0
int useBufTest()
{
    OMX_ERRORTYPE err = OMX_ErrorNone;
    OMX_BOOL bOmxInitialized = OMX_FALSE;
    OMX_PARAM_PORTDEFINITIONTYPE sOmxPortDefinition;
    OMX_CONFIG_BOOLEANTYPE sOmxCapturing;
    OMX_CONFIG_BOOLEANTYPE sOmxAutoPause;
    OMX_STATETYPE sOmxState;
    OMX_U32 nBufferCount;
    OMX_U32 nBufferSize;
    OMX_U32 nPortIndex;
    OMX_U32 i;
    unsigned int nPreviewTime = 5;/* By default, running for 5 sec for preview */
    unsigned int nCaptureTime = 5;/* By default, running for 5 sec for video capture */
    OMX_BOOL bCameraStillImageMode = OMX_FALSE; /* By default, the camera is running in video capture mode */
    OMX_BOOL bCameraAutoPause = OMX_FALSE; /* By default, the camera is not running in autopause mode */
    unsigned int nMaxRunCount = 1;/* By default, running once */
    unsigned int nRunCount = 0;
    OMX_U8 *buf = NULL;
    

    surface_display_main_init(DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT);
    
    /* Init the Omx core */
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Init the OMX core\n");
    if ((err = OMX_Init()) != OMX_ErrorNone)
    {
        DEBUG(DEB_LEV_ERR,
                "The OpenMAX core can not be initialized. Exiting...\n");
        goto EXIT;
    }
    bOmxInitialized = OMX_TRUE;
    
    /* Initialize application private data */
    appPriv = malloc(sizeof(appPrivateType));
    if (appPriv == NULL)
    {
        DEBUG(DEB_LEV_ERR, "Allocate app private data failed!Exiting...\n");
        err = OMX_ErrorInsufficientResources;
        goto EXIT;
    }
    memset(appPriv, 0, sizeof(appPrivateType));
    
    memset(&sCameraPortBufferList, 0,
            NUM_CAMERAPORTS * sizeof(OMX_PORTBUFFERCTXT));
    
    /* Getting camera component handle */
    if ((err = OMX_GetHandle(&appPriv->camerahandle,
            "OMX.Action.Camera.Yuv", appPriv, &camera_source_callbacks))
            != OMX_ErrorNone)
    {
        DEBUG(DEB_LEV_ERR,
                "Getting camera component handle failed!Exiting...\n");
        goto EXIT;
    }

    /* Setting parameters for camera component */
    if ((err = setCameraParameters(bCameraStillImageMode)) != OMX_ErrorNone)
    {
        DEBUG(DEB_LEV_ERR,
                "Set camera parameters failed! Use default settings...\n");
        /* Do not exit! */
    }

    /* Allocate and init semaphores */
    appPriv->cameraSourceEventSem = malloc(sizeof(tsem_t));
    if (appPriv->cameraSourceEventSem == NULL)
    {
        DEBUG(DEB_LEV_ERR,
                "Allocate camera event semaphore failed!Exiting...\n");
        err = OMX_ErrorInsufficientResources;
        goto EXIT;
    }
    tsem_init(appPriv->cameraSourceEventSem, 0);
    
    RUN_AGAIN:

    for (nPortIndex = OMX_CAMPORT_INDEX_VF; nPortIndex <= OMX_CAMPORT_INDEX_CP; nPortIndex++)
    {
        
        if ((err = OMX_SendCommand(appPriv->camerahandle,
                OMX_CommandPortEnable, nPortIndex, NULL)) != OMX_ErrorNone)
        {
            DEBUG(DEB_LEV_ERR, "Camera Idle-->Exec failed!Exiting...\n");
            goto EXIT;
        }
        tsem_down(appPriv->cameraSourceEventSem);
    }
    /* Transition camera component Loaded-->Idle */
    if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet,
            OMX_StateIdle, NULL)) != OMX_ErrorNone)
    {
        DEBUG(DEB_LEV_ERR, "Camera Loaded-->Idle failed!Exiting...\n");
        goto EXIT;
    }

    /* Allocate port buffers for camera component */
    for (nPortIndex = OMX_CAMPORT_INDEX_VF; nPortIndex <= OMX_CAMPORT_INDEX_CP; nPortIndex++)
    {
        
        setHeader(&sOmxPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
        sOmxPortDefinition.nPortIndex = nPortIndex;
        if ((err = OMX_GetParameter(appPriv->camerahandle,
                OMX_IndexParamPortDefinition, &sOmxPortDefinition))
                != OMX_ErrorNone)
        {
            DEBUG(
                    DEB_LEV_ERR,
                    "OMX_GetParameter for camera on OMX_IndexParamPortDefinition index failed!Exiting...\n");
            goto EXIT;
        }
        nBufferCount = sOmxPortDefinition.nBufferCountActual;
        nBufferSize = sOmxPortDefinition.nBufferSize;
        DEBUG(
                DEB_LEV_SIMPLE_SEQ,
                "Camera port[%ld] needs %ld buffers each of which is %ld bytes\n",
                nPortIndex, nBufferCount, nBufferSize);
        
        for (i = 0; i < nBufferCount; i++)
        {
            buf = (OMX_U8 *)malloc(nBufferSize);
            if(buf == NULL){
                DEBUG(DEB_LEV_ERR,
                        "Allocate port buffer for camera failed!Exiting...\n");
                goto EXIT;
            }
            
            if ((err = OMX_UseBuffer(appPriv->camerahandle,
                    &sCameraPortBufferList[nPortIndex].pBufHeaderList[i],
                    nPortIndex, NULL, nBufferSize, buf)) != OMX_ErrorNone)
            {
                DEBUG(DEB_LEV_ERR,
                        "Allocate port buffer for camera failed!Exiting...\n");
                goto EXIT;
            }
            sCameraPortBufferList[nPortIndex].nBufferCountActual++;
        }
    }

    /* Wait camera (Loaded-->Idle) to complete */
    tsem_down(appPriv->cameraSourceEventSem);
    
    /* Transition camera component Idle-->Exec */
    if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet,
            OMX_StateExecuting, NULL)) != OMX_ErrorNone)
    {
        DEBUG(DEB_LEV_ERR, "Camera Idle-->Exec failed!Exiting...\n");
        goto EXIT;
    }

    /* Wait camera (Idle-->Exec) to complete */
    tsem_down(appPriv->cameraSourceEventSem);
    
    /* Fill buffers to camera preview port */
    for (i = 0; i
            < sCameraPortBufferList[OMX_CAMPORT_INDEX_VF].nBufferCountActual; i++)
    {
        sCameraPortBufferList[OMX_CAMPORT_INDEX_VF].pBufHeaderList[i]->nFilledLen
                = 0;
        sCameraPortBufferList[OMX_CAMPORT_INDEX_VF].pBufHeaderList[i]->nOffset
                = 0;
        if ((err = OMX_FillThisBuffer(appPriv->camerahandle,
                sCameraPortBufferList[OMX_CAMPORT_INDEX_VF].pBufHeaderList[i]))
                != OMX_ErrorNone)
        {
            DEBUG(DEB_LEV_ERR,
                    "Fill buffer to camera capture port failed!Exiting...\n");
            goto EXIT;
        }
        DEBUG(
                DEB_LEV_SIMPLE_SEQ,
                "%s: Fill buffer[%ld] (0x%lX) to camera capture port\n",
                __func__,
                i,
                (OMX_U32) sCameraPortBufferList[OMX_CAMPORT_INDEX_VF].pBufHeaderList[i]);
    }

    /* Fill buffers to camera capture port */
    for (i = 0; i
            < sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].nBufferCountActual; i++)
    {
        sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]->nFilledLen
                = 0;
        sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]->nOffset
                = 0;
        if ((err = OMX_FillThisBuffer(appPriv->camerahandle,
                sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]))
                != OMX_ErrorNone)
        {
            DEBUG(DEB_LEV_ERR,
                    "Fill buffer to camera capture port failed!Exiting...\n");
            goto EXIT;
        }
        DEBUG(
                DEB_LEV_SIMPLE_SEQ,
                "%s: Fill buffer[%ld] (0x%lX) to camera capture port\n",
                __func__,
                i,
                (OMX_U32) sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]);
    }

    fprintf(stdout, "Start preview, for %d sec...\n", nPreviewTime);
    sleep(nPreviewTime);
    
    /* Set up autopause mode */
    setHeader(&sOmxAutoPause, sizeof(OMX_CONFIG_BOOLEANTYPE));
    sOmxAutoPause.bEnabled = bCameraAutoPause;
    if ((err = OMX_SetConfig(appPriv->camerahandle,
            OMX_IndexAutoPauseAfterCapture, &sOmxAutoPause)) != OMX_ErrorNone)
    {
        DEBUG(DEB_LEV_ERR,
                "Set autopause mode failed!Use default settings...\n");
        /* Do not exit */
    }

    /*  Start capturing */
    setHeader(&sOmxCapturing, sizeof(OMX_CONFIG_BOOLEANTYPE));
    sOmxCapturing.bEnabled = OMX_TRUE;
    if ((err = OMX_SetConfig(appPriv->camerahandle, OMX_IndexConfigCapturing,
            &sOmxCapturing)) != OMX_ErrorNone)
    {
        DEBUG(DEB_LEV_ERR, "Start capturing failed!Exiting...\n");
        goto EXIT;
    }

    fprintf(stdout, "Start capturing, for %d sec...\n", nCaptureTime);
    sleep(nCaptureTime);
    
    /*  Stop capturing */
    if (!bCameraStillImageMode)
    {
        setHeader(&sOmxCapturing, sizeof(OMX_CONFIG_BOOLEANTYPE));
        sOmxCapturing.bEnabled = OMX_FALSE;
        if ((err = OMX_SetConfig(appPriv->camerahandle,
                OMX_IndexConfigCapturing, &sOmxCapturing)) != OMX_ErrorNone)
        {
            DEBUG(DEB_LEV_ERR, "Stop capturing failed!Exiting...\n");
            goto EXIT;
        }
        fprintf(stdout, "Stop capturing...\n");
    }

    /* If in autopause mode, stay for a while before exit */
    if (bCameraAutoPause)
    {
        fprintf( stdout,"pause state for capture, sleep(%d)\n",5);
        sleep(5);
        /* Stop autopause mode */
        if ((err = OMX_GetState(appPriv->camerahandle, &sOmxState))
                != OMX_ErrorNone)
        {
            DEBUG(DEB_LEV_ERR, "Get camera state failed!Exiting...\n");
            goto EXIT;
        }
        if (sOmxState == OMX_StatePause)
        {
            if ((err = OMX_SendCommand(appPriv->camerahandle,
                    OMX_CommandStateSet, OMX_StateExecuting, 0))
                    != OMX_ErrorNone)
            {
                DEBUG(DEB_LEV_ERR, "Pause-->Exec failed!Exiting...\n");
                goto EXIT;
            }
            /* Wait camera (Pause-->Exec) to complete */
            tsem_down(appPriv->cameraSourceEventSem);
            fprintf(
                    stdout,
                    "Now the camera is out of autopause mode, wait for %d sec before exit...\n",
                    5);
            sleep(5);
        }
        else
        {
            DEBUG(DEB_LEV_ERR,
                    "The camera is not in Pause state in autopause mode, ignore...\n");
        }
    }

#if 1
    /* Transition camera component Exec-->Idle */
    if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet,
            OMX_StateIdle, NULL)) != OMX_ErrorNone)
    {
        DEBUG(DEB_LEV_ERR, "Camera Exec-->Idle failed!Exiting...\n");
        goto EXIT;
    }

    /* Wait camera (Exec-->Idle) to complete */
    tsem_down(appPriv->cameraSourceEventSem);
    
    /* Transition camera component Idle-->Exec */
    if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet,
            OMX_StateExecuting, NULL)) != OMX_ErrorNone)
    {
        DEBUG(DEB_LEV_ERR, "Camera Idle-->Exec failed!Exiting...\n");
        goto EXIT;
    }

    /* Wait camera (Idle-->Exec) to complete */
    tsem_down(appPriv->cameraSourceEventSem);
    
    /* Fill buffers to camera preview port */
    for (i = 0; i
            < sCameraPortBufferList[OMX_CAMPORT_INDEX_VF].nBufferCountActual; i++)
    {
        sCameraPortBufferList[OMX_CAMPORT_INDEX_VF].pBufHeaderList[i]->nFilledLen
                = 0;
        sCameraPortBufferList[OMX_CAMPORT_INDEX_VF].pBufHeaderList[i]->nOffset
                = 0;
        if ((err = OMX_FillThisBuffer(appPriv->camerahandle,
                sCameraPortBufferList[OMX_CAMPORT_INDEX_VF].pBufHeaderList[i]))
                != OMX_ErrorNone)
        {
            DEBUG(DEB_LEV_ERR,
                    "Fill buffer to camera capture port failed!Exiting...\n");
            goto EXIT;
        }
        DEBUG(
                DEB_LEV_SIMPLE_SEQ,
                "%s: Fill buffer[%ld] (0x%lX) to camera capture port\n",
                __func__,
                i,
                (OMX_U32) sCameraPortBufferList[OMX_CAMPORT_INDEX_VF].pBufHeaderList[i]);
    }

    /* Fill buffers to camera capture port */
    for (i = 0; i
            < sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].nBufferCountActual; i++)
    {
        sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]->nFilledLen
                = 0;
        sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]->nOffset
                = 0;
        if ((err = OMX_FillThisBuffer(appPriv->camerahandle,
                sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]))
                != OMX_ErrorNone)
        {
            DEBUG(DEB_LEV_ERR,
                    "Fill buffer to camera capture port failed!Exiting...\n");
            goto EXIT;
        }
        DEBUG(
                DEB_LEV_SIMPLE_SEQ,
                "%s: Fill buffer[%ld] (0x%lX) to camera capture port\n",
                __func__,
                i,
                (OMX_U32) sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]);
    }

    fprintf(stdout, "Continue to preview, for %d sec...\n", nPreviewTime);
    sleep(nPreviewTime);
    
#endif
    /* Transition camera component Exec-->Idle */
    if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet,
            OMX_StateIdle, NULL)) != OMX_ErrorNone)
    {
        DEBUG(DEB_LEV_ERR, "Camera Exec-->Idle failed!Exiting...\n");
        goto EXIT;
    }

    /* Wait camera (Exec-->Idle) to complete */
    tsem_down(appPriv->cameraSourceEventSem);
    
    /* Transition camera component Idle-->Loaded */
    if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet,
            OMX_StateLoaded, NULL)) != OMX_ErrorNone)
    {
        DEBUG(DEB_LEV_ERR, "Camera Idle-->Loaded failed!Exiting...\n");
        goto EXIT;
    }

#if 1
    /* Free bufers for each non-tunneled port of camera component */
    for (nPortIndex = OMX_CAMPORT_INDEX_VF; nPortIndex <= OMX_CAMPORT_INDEX_CP; nPortIndex++)
    {
        for (i = 0; i < sCameraPortBufferList[nPortIndex].nBufferCountActual; i++)
        {
            if (sCameraPortBufferList[nPortIndex].pBufHeaderList[i] != NULL)
            {
                buf = sCameraPortBufferList[nPortIndex].pBufHeaderList[i]->pBuffer;
                OMX_FreeBuffer(appPriv->camerahandle, nPortIndex,
                        sCameraPortBufferList[nPortIndex].pBufHeaderList[i]);
                if(buf){
                    free(buf);
                }
                sCameraPortBufferList[nPortIndex].pBufHeaderList[i]=NULL;
            }
        }
        sCameraPortBufferList[nPortIndex].nBufferCountActual = 0;
    }
#endif
    
    /* Wait camera (Idle-->Loaded) to complete */
    tsem_down(appPriv->cameraSourceEventSem);
    
    nRunCount++;
    if (nRunCount < nMaxRunCount)
    {
        goto RUN_AGAIN;
    }

   
    EXIT: 

    for (nPortIndex = OMX_CAMPORT_INDEX_VF; nPortIndex <= OMX_CAMPORT_INDEX_CP; nPortIndex++)
    {
        for (i = 0; i < sCameraPortBufferList[nPortIndex].nBufferCountActual; i++)
        {
            if (sCameraPortBufferList[nPortIndex].pBufHeaderList[i] != NULL)
            {
                buf = sCameraPortBufferList[nPortIndex].pBufHeaderList[i]->pBuffer;
                OMX_FreeBuffer(appPriv->camerahandle, nPortIndex,
                        sCameraPortBufferList[nPortIndex].pBufHeaderList[i]);
                if(buf){
                    free(buf);
                }
                sCameraPortBufferList[nPortIndex].pBufHeaderList[i]=NULL; 
            }
        }
        sCameraPortBufferList[nPortIndex].nBufferCountActual = 0;
    }   

    /* Free app private data */
    if (appPriv != NULL)
    {
        /* Free semaphores */
        if (appPriv->cameraSourceEventSem != NULL)
        {
            tsem_deinit(appPriv->cameraSourceEventSem);
            free(appPriv->cameraSourceEventSem);
        }

        /* Free camera component handle */
        if (appPriv->camerahandle != NULL)
        {
            OMX_FreeHandle(appPriv->camerahandle);
        }
        
        free(appPriv);
    }

    /* Deinit the Omx core */
    if (bOmxInitialized)
    {
        OMX_Deinit();
    }
    
    return (int) err;
}
void* omx_clocksrc_BufferMgmtFunction (void* param) {
  OMX_COMPONENTTYPE*                  openmaxStandComp = (OMX_COMPONENTTYPE*)param;
  omx_base_component_PrivateType*     omx_base_component_Private=(omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
  omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private  = (omx_clocksrc_component_PrivateType*)omx_base_component_Private;
  omx_base_clock_PortType             *pOutPort[MAX_CLOCK_PORTS];
  tsem_t*                             pOutputSem[MAX_CLOCK_PORTS];
  queue_t*                            pOutputQueue[MAX_CLOCK_PORTS];
  OMX_BUFFERHEADERTYPE*               pOutputBuffer[MAX_CLOCK_PORTS];
  OMX_BOOL                            isOutputBufferNeeded[MAX_CLOCK_PORTS],bPortsBeingFlushed = OMX_FALSE;
  int                                 i,j,outBufExchanged[MAX_CLOCK_PORTS];

  for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
    pOutPort[i]             = (omx_base_clock_PortType *)omx_clocksrc_component_Private->ports[i];
    pOutputSem[i]           = pOutPort[i]->pBufferSem;
    pOutputQueue[i]         = pOutPort[i]->pBufferQueue;
    pOutputBuffer[i]        = NULL;
    isOutputBufferNeeded[i] = OMX_TRUE;
    outBufExchanged[i]      = 0;
  }

  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
  while(omx_clocksrc_component_Private->state == OMX_StateIdle
         || omx_clocksrc_component_Private->state == OMX_StateExecuting
         || omx_clocksrc_component_Private->state == OMX_StatePause
         || omx_clocksrc_component_Private->transientState == OMX_TransStateLoadedToIdle){

    /*Wait till the ports are being flushed*/
    pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
    for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
      bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[i]);
    }
    while(bPortsBeingFlushed) {
      pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
      for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
          if(isOutputBufferNeeded[i]==OMX_FALSE && PORT_IS_BEING_FLUSHED(pOutPort[i])) {
          pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]);
          outBufExchanged[i]--;
          pOutputBuffer[1]=NULL;
          isOutputBufferNeeded[i]=OMX_TRUE;
          DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output buffer for port %i\n",i);
        }
      }

      tsem_up(omx_clocksrc_component_Private->flush_all_condition);
      tsem_down(omx_clocksrc_component_Private->flush_condition);
      pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);

      bPortsBeingFlushed = OMX_FALSE;
      for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
        bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[i]);
      }
    }
    pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);

    /*Wait for clock state event*/
    DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Waiting for clock event\n",__func__);
    tsem_down(omx_clocksrc_component_Private->clockEventSem);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s clock event occured semval=%d \n",__func__,omx_clocksrc_component_Private->clockEventSem->semval);

    /*If port is not tunneled then simply return the buffer except paused state*/
    if(omx_clocksrc_component_Private->transientState == OMX_TransStatePauseToExecuting) {
      for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
        if(!PORT_IS_TUNNELED(pOutPort[i])) {

          if(pOutputSem[i]->semval>0 && isOutputBufferNeeded[i]==OMX_TRUE ) {
            tsem_down(pOutputSem[i]);
            if(pOutputQueue[i]->nelem>0){
              outBufExchanged[i]++;
              isOutputBufferNeeded[i]=OMX_FALSE;
              pOutputBuffer[i] = dequeue(pOutputQueue[i]);
              if(pOutputBuffer[i] == NULL){
                DEBUG(DEB_LEV_ERR, "Had NULL output buffer!!\n");
                break;
              }
            }
          }

          if(isOutputBufferNeeded[i]==OMX_FALSE) {
            /*Output Buffer has been produced or EOS. So, return output buffer and get new buffer*/
            if(pOutputBuffer[i]->nFilledLen!=0) {
              DEBUG(DEB_LEV_ERR, "In %s Returning Output nFilledLen=%d (line=%d)\n",
                __func__,(int)pOutputBuffer[i]->nFilledLen,__LINE__);
              pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]);
              outBufExchanged[i]--;
              pOutputBuffer[i]=NULL;
              isOutputBufferNeeded[i]=OMX_TRUE;
            }
          }
        }
      }
      omx_clocksrc_component_Private->transientState = OMX_TransStateMax;
    }

    if(omx_clocksrc_component_Private->state == OMX_StateLoaded  ||
       omx_clocksrc_component_Private->state == OMX_StateInvalid ||
       omx_clocksrc_component_Private->transientState == OMX_TransStateIdleToLoaded ||
       omx_clocksrc_component_Private->transientState == OMX_TransStateInvalid) {

      DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting (line %d)\n",__func__,__LINE__);
      break;
    }

    for(i=0;i<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;i++) {
      if(pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateClockStateChanged ||
         pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateScaleChanged      ||
         pOutPort[i]->sMediaTime.eUpdateType == OMX_TIME_UpdateRequestFulfillment) {

        if((isOutputBufferNeeded[i]==OMX_TRUE && pOutputSem[i]->semval==0) &&
          (omx_clocksrc_component_Private->state != OMX_StateLoaded && omx_clocksrc_component_Private->state != OMX_StateInvalid)
          && PORT_IS_ENABLED(pOutPort[i])) {
          //Signalled from EmptyThisBuffer or FillThisBuffer or some where else
          DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next output buffer %i\n",i);
          tsem_down(omx_clocksrc_component_Private->bMgmtSem);
        }
        if(omx_clocksrc_component_Private->state == OMX_StateLoaded  ||
           omx_clocksrc_component_Private->state == OMX_StateInvalid ||
           omx_clocksrc_component_Private->transientState == OMX_TransStateIdleToLoaded ||
           omx_clocksrc_component_Private->transientState == OMX_TransStateInvalid) {
          DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting (line %d)\n",__func__,__LINE__);
          break;
        }

        if(pOutputSem[i]->semval>0 && isOutputBufferNeeded[i]==OMX_TRUE ) {
          tsem_down(pOutputSem[i]);
          if(pOutputQueue[i]->nelem>0){
            outBufExchanged[i]++;
            isOutputBufferNeeded[i]=OMX_FALSE;
            pOutputBuffer[i] = dequeue(pOutputQueue[i]);
            if(pOutputBuffer[i] == NULL){
              DEBUG(DEB_LEV_ERR, "Had NULL output buffer!!\n");
              break;
            }
          }
        } else {
          DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Output buffer not available Port %d (line=%d)\n",__func__,(int)i,__LINE__);

          /*Check if any dummy bMgmtSem signal and ports are flushing*/
          pthread_mutex_lock(&omx_clocksrc_component_Private->flush_mutex);
          bPortsBeingFlushed = OMX_FALSE;
          for(j=0;j<omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts;j++) {
            bPortsBeingFlushed |= PORT_IS_BEING_FLUSHED(pOutPort[j]);
          }
          pthread_mutex_unlock(&omx_clocksrc_component_Private->flush_mutex);
          if(bPortsBeingFlushed) {
            DEBUG(DEB_LEV_ERR, "In %s Ports are being flushed - breaking (line %d)\n",__func__,__LINE__);
            break;
          }
        }
        /*Process Output buffer of Port i */
        if(isOutputBufferNeeded[i]==OMX_FALSE) {
          if (omx_clocksrc_component_Private->BufferMgmtCallback) {
            (*(omx_clocksrc_component_Private->BufferMgmtCallback))(openmaxStandComp, pOutputBuffer[i]);
          } else {
            /*If no buffer management call back then don't produce any output buffer*/
            pOutputBuffer[i]->nFilledLen = 0;
          }

           /*Output Buffer has been produced or EOS. So, return output buffer and get new buffer*/
          if(pOutputBuffer[i]->nFilledLen!=0) {
            pOutPort[i]->ReturnBufferFunction((omx_base_PortType*)pOutPort[i],pOutputBuffer[i]);
            outBufExchanged[i]--;
            pOutputBuffer[i]=NULL;
            isOutputBufferNeeded[i]=OMX_TRUE;
          }
        }
      }
    }

    DEBUG(DEB_LEV_SIMPLE_SEQ, "Sent Clock Event for all ports\n");
    tsem_up(omx_clocksrc_component_Private->clockEventCompleteSem);
  }
  DEBUG(DEB_LEV_SIMPLE_SEQ,"Exiting Buffer Management Thread\n");
  return NULL;
}
int main(int argc, char** argv) {

    OMX_ERRORTYPE err;
    int argn_dec;
    OMX_STRING full_component_name;
    int isRate=0,isChannel=0;
    OMX_AUDIO_PARAM_PCMMODETYPE sPCMModeParam;
    if(argc < 2) {
        display_help();
    } else {
        flagIsOutputExpected = 0;
        flagDecodedOutputReceived = 0;
        flagIsVolCompRequested = 0;
        flagSetupTunnel = 0;
        flagIsSinkRequested = 0;

        argn_dec = 1;
        while (argn_dec < argc) {
            if (*(argv[argn_dec]) == '-') {
                if (flagIsOutputExpected) {
                    display_help();
                }
                switch (*(argv[argn_dec] + 1)) {
                case 'h' :
                    display_help();
                    break;
                case 't' :
                    flagSetupTunnel = 1;
                    flagIsSinkRequested = 1;
                    flagIsVolCompRequested = 1;
                    break;
                case 's':
                    flagIsSinkRequested = 1;
                    break;
                case 'o':
                    flagIsOutputExpected = 1;
                    break;
                case 'v':
                    flagIsVolCompRequested = 1;
                    break;
                case 'r' :
                    isRate = 1;
                    break;
                case 'n' :
                    isChannel = 1;
                    break;
                default:
                    display_help();
                }
            } else {
                if (flagIsOutputExpected) {
                    if(strstr(argv[argn_dec], ".pcm") == NULL) {
                        output_file = malloc(strlen(argv[argn_dec]) + 5);
                        strcpy(output_file,argv[argn_dec]);
                        strcat(output_file, ".pcm");
                    } else {
                        output_file = malloc(strlen(argv[argn_dec]) + 1);
                        strcpy(output_file,argv[argn_dec]);
                    }
                    flagIsOutputExpected = 0;
                    flagDecodedOutputReceived = 1;
                } else if(isRate) {
                    rate=atoi(argv[argn_dec]);
                    isRate=0;
                    if(rate <0 || rate >48000) {
                        DEBUG(DEB_LEV_ERR, "Bad Parameter rate\n");
                        display_help();
                    }
                } else if(isChannel) {
                    channel=atoi(argv[argn_dec]);
                    isChannel = 0;
                    if(channel <0 || channel >6) {
                        DEBUG(DEB_LEV_ERR, "Bad Parameter channel\n");
                        display_help();
                    }
                }
            }
            argn_dec++;
        }

        /** if volume componenterter component is not selected then sink component will not work, even if specified */
        if(!flagIsVolCompRequested && flagIsSinkRequested) {
            DEBUG(DEB_LEV_ERR, "You requested for sink - not producing any output file\n");
            flagIsVolCompRequested = 1;
            flagDecodedOutputReceived = 0;
        }

        /** output file name check */
        //case 1 - user did not specify any output file
        if(!flagIsOutputExpected && !flagDecodedOutputReceived && !flagIsSinkRequested) {
            DEBUG(DEB_LEV_ERR,"\n you did not enter any output file name");
            output_file = malloc(20);
            strcpy(output_file,"output.pcm");
            DEBUG(DEB_LEV_ERR,"\n the decoded output file name will be %s \n", output_file);
        } else if(flagDecodedOutputReceived) {
            if(flagIsSinkRequested || flagSetupTunnel) {
                flagDecodedOutputReceived = 0;
                DEBUG(DEB_LEV_ERR, "Sink Requested or Components are tunneled. No FILE Output will be produced\n");
            } else {
                //case 2 - user has given wrong format
                if(flagIsVolCompRequested && strstr(output_file, ".pcm") == NULL) {
                    output_file[strlen(output_file) - strlen(strstr(output_file, "."))] = '\0';
                    strcat(output_file, ".rgb");
                    DEBUG(DEB_LEV_ERR,"\n volume component option is selected - so the output file is %s \n", output_file);
                }
            }
        }
        if(flagSetupTunnel) {
            DEBUG(DEFAULT_MESSAGES,"The components are tunneled between themselves\n");
        }
    }

    if(!flagIsSinkRequested) {
        outfile = fopen(output_file, "wb");
        if(outfile == NULL) {
            DEBUG(DEB_LEV_ERR, "Error in opening output file %s\n", output_file);
            exit(1);
        }
    }

    /* Initialize application private data */
    appPriv = malloc(sizeof(appPrivateType));
    appPriv->sourceEventSem = malloc(sizeof(tsem_t));
    if(flagIsVolCompRequested == 1) {
        if(flagIsSinkRequested == 1) {
            appPriv->alsasinkEventSem = malloc(sizeof(tsem_t));
        }
        appPriv->volumeEventSem = malloc(sizeof(tsem_t));
    }
    appPriv->eofSem = malloc(sizeof(tsem_t));
    tsem_init(appPriv->sourceEventSem, 0);
    if(flagIsVolCompRequested == 1) {
        if(flagIsSinkRequested == 1) {
            tsem_init(appPriv->alsasinkEventSem, 0);
        }
        tsem_init(appPriv->volumeEventSem, 0);
    }
    tsem_init(appPriv->eofSem, 0);

    DEBUG(DEB_LEV_SIMPLE_SEQ, "Init the Omx core\n");
    err = OMX_Init();
    if (err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR, "The OpenMAX core can not be initialized. Exiting...\n");
        exit(1);
    } else {
        DEBUG(DEB_LEV_SIMPLE_SEQ, "Omx core is initialized \n");
    }

    DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
    test_OMX_ComponentNameEnum();
    DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
    test_OMX_RoleEnum(COMPONENT_NAME_BASE);
    DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
    test_OMX_ComponentEnumByRole(BASE_ROLE);
    DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
    test_OpenClose(COMPONENT_NAME_BASE);
    DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");


    full_component_name = malloc(OMX_MAX_STRINGNAME_SIZE);
    strcpy(full_component_name, "OMX.st.alsa.alsasrc");

    DEBUG(DEFAULT_MESSAGES, "The component selected for decoding is %s\n", full_component_name);

    /** getting audio source handle */
    err = OMX_GetHandle(&appPriv->audiosrchandle, full_component_name, NULL, &audiosrccallbacks);
    if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR, "No audio source component found. Exiting...\n");
        exit(1);
    } else {
        DEBUG(DEFAULT_MESSAGES, "Found The component for capturing is %s\n", full_component_name);
    }

    /** getting volume componenterter component handle, if specified */
    if(flagIsVolCompRequested == 1) {
        err = OMX_GetHandle(&appPriv->volume_handle, "OMX.st.volume.component", NULL, &volume_callbacks);
        if(err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "No volume componenterter component found. Exiting...\n");
            exit(1);
        } else {
            DEBUG(DEFAULT_MESSAGES, "Found The component for volume componenterter \n");
        }

        /** getting sink component handle - if reqd' */
        if(flagIsSinkRequested == 1) {
            err = OMX_GetHandle(&appPriv->alsasink_handle, "OMX.st.alsa.alsasink", NULL, &alsasink_callbacks);
            if(err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "No audio sink component component found. Exiting...\n");
                exit(1);
            } else {
                DEBUG(DEFAULT_MESSAGES, "Found The audio sink component for volume componenterter \n");
            }
        }
    }

    if(rate >0 || channel >0) {
        setHeader(&sPCMModeParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
        err = OMX_GetParameter(appPriv->audiosrchandle,OMX_IndexParamAudioPcm,&sPCMModeParam);
        if (err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Err in GetParameter OMX_AUDIO_PARAM_PCMMODETYPE in AlsaSrc. Exiting...\n");
            exit(1);
        }
        sPCMModeParam.nChannels = (channel >0 ) ? channel:sPCMModeParam.nChannels;
        sPCMModeParam.nSamplingRate = (rate >0 ) ? rate:sPCMModeParam.nSamplingRate;
        err = OMX_SetParameter(appPriv->audiosrchandle,OMX_IndexParamAudioPcm,&sPCMModeParam);
        if (err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Err in SetParameter OMX_AUDIO_PARAM_PCMMODETYPE in AlsaSrc. Exiting...\n");
            exit(1);
        }
        if(flagIsSinkRequested) {
            err = OMX_SetParameter(appPriv->alsasink_handle,OMX_IndexParamAudioPcm,&sPCMModeParam);
            if (err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "Err in SetParameter OMX_AUDIO_PARAM_PCMMODETYPE in AlsaSink. Exiting...\n");
                exit(1);
            }
        }
    } else if(flagIsSinkRequested) {
        setHeader(&sPCMModeParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
        err = OMX_GetParameter(appPriv->audiosrchandle,OMX_IndexParamAudioPcm,&sPCMModeParam);
        if (err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Err in GetParameter OMX_AUDIO_PARAM_PCMMODETYPE in AlsaSrc. Exiting...\n");
            exit(1);
        }
        err = OMX_SetParameter(appPriv->alsasink_handle,OMX_IndexParamAudioPcm,&sPCMModeParam);
        if (err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Err in SetParameter OMX_AUDIO_PARAM_PCMMODETYPE in AlsaSink. Exiting...\n");
            exit(1);
        }
    }

    /** output buffer size calculation based on input dimension speculation */
    DEBUG(DEB_LEV_SIMPLE_SEQ, "\n buffer_out_size : %d \n", (int)buffer_out_size);

    /** if tunneling option is given then set up the tunnel between the components */
    if (flagSetupTunnel) {
        DEBUG(DEB_LEV_SIMPLE_SEQ, "Setting up Tunnel\n");
        err = OMX_SetupTunnel(appPriv->audiosrchandle, 0, appPriv->volume_handle, 0);
        if(err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Set up Tunnel between audio src & volume component Failed\n");
            exit(1);
        }
        err = OMX_SetupTunnel(appPriv->volume_handle, 1, appPriv->alsasink_handle, 0);
        if(err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Set up Tunnel between volume component & audio sink Failed\n");
            exit(1);
        }
        DEBUG(DEFAULT_MESSAGES, "Set up Tunnel Completed\n");
    }

    /** sending command to audio source component to go to idle state */
    err = OMX_SendCommand(appPriv->audiosrchandle, OMX_CommandStateSet, OMX_StateIdle, NULL);

    /** in tunnel case, change the volume component and sink comp state to idle */
    if(flagIsVolCompRequested && flagSetupTunnel) {
        err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
        if(flagIsSinkRequested && flagSetupTunnel) {
            err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
        }
    }

    if(flagSetupTunnel) {
        if(flagIsSinkRequested) {
            tsem_down(appPriv->alsasinkEventSem);
        }
        if(flagIsVolCompRequested) {
            tsem_down(appPriv->volumeEventSem);
        }
    }

    /** if tunneling option is not given then allocate buffers on audio source output port */
    if (!flagSetupTunnel) {
        pOutBuffer[0] = pOutBuffer[1] = NULL;
        err = OMX_AllocateBuffer(appPriv->audiosrchandle, &pOutBuffer[0], 0, NULL, buffer_out_size);
        err = OMX_AllocateBuffer(appPriv->audiosrchandle, &pOutBuffer[1], 0, NULL, buffer_out_size);
    }

    DEBUG(DEB_LEV_SIMPLE_SEQ, "Before locking on idle wait semaphore\n");
    tsem_down(appPriv->sourceEventSem);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "source Sem free\n");

    if(!flagSetupTunnel) {
        if(flagIsVolCompRequested == 1) {
            pOutBufferVolc[0] = pOutBufferVolc[1] = NULL;
            err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);

            /** in non tunneled case, using buffers in volume component input port, allocated by audio dec component output port */
            err = OMX_UseBuffer(appPriv->volume_handle, &pInBufferVolc[0], 0, NULL, buffer_out_size, pOutBuffer[0]->pBuffer);
            if(err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "Unable to use the volume component comp allocate buffer\n");
                exit(1);
            }
            err = OMX_UseBuffer(appPriv->volume_handle, &pInBufferVolc[1], 0, NULL, buffer_out_size, pOutBuffer[1]->pBuffer);
            if(err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "Unable to use the volume component comp allocate buffer\n");
                exit(1);
            }

            /** allocating buffers in the volume componenterter compoennt output port */

            err = OMX_AllocateBuffer(appPriv->volume_handle, &pOutBufferVolc[0], 1, NULL, buffer_out_size);
            if(err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "Unable to allocate buffer in volume component\n");
                exit(1);
            }
            err = OMX_AllocateBuffer(appPriv->volume_handle, &pOutBufferVolc[1], 1, NULL, buffer_out_size);
            if(err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "Unable to allocate buffer in colro conv\n");
                exit(1);
            }

            DEBUG(DEB_LEV_SIMPLE_SEQ, "Before locking on idle wait semaphore\n");
            tsem_down(appPriv->volumeEventSem);
            DEBUG(DEFAULT_MESSAGES, "volume Event Sem free\n");

            if(flagIsSinkRequested == 1) {
                err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
                err = OMX_UseBuffer(appPriv->alsasink_handle, &pInBufferSink[0], 0, NULL, buffer_out_size, pOutBufferVolc[0]->pBuffer);
                if(err != OMX_ErrorNone) {
                    DEBUG(DEB_LEV_ERR, "Unable to use the alsasink_handle comp allocate buffer\n");
                    exit(1);
                }
                err = OMX_UseBuffer(appPriv->alsasink_handle, &pInBufferSink[1], 0, NULL, buffer_out_size, pOutBufferVolc[1]->pBuffer);
                if(err != OMX_ErrorNone) {
                    DEBUG(DEB_LEV_ERR, "Unable to use the alsasink_handle comp allocate buffer\n");
                    exit(1);
                }

                DEBUG(DEB_LEV_SIMPLE_SEQ, "Before locking on idle wait semaphore\n");
                tsem_down(appPriv->alsasinkEventSem);
                DEBUG(DEB_LEV_SIMPLE_SEQ, "audio sink comp Sem free\n");
            }
        }

        if(flagIsVolCompRequested == 1) {
            err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
            tsem_down(appPriv->volumeEventSem);
            if(flagIsSinkRequested == 1) {
                err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
                tsem_down(appPriv->alsasinkEventSem);
            }
        }
    }

    /** send command to change color onv and sink comp in executing state */
    if(flagIsVolCompRequested == 1 && flagSetupTunnel) {
        err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
        tsem_down(appPriv->volumeEventSem);
        if(flagIsSinkRequested == 1) {
            err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
            tsem_down(appPriv->alsasinkEventSem);
        }
    }

    /** sending command to audio source component to go to executing state */
    err = OMX_SendCommand(appPriv->audiosrchandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
    tsem_down(appPriv->sourceEventSem);

    if(flagIsVolCompRequested == 1 && !flagSetupTunnel) {
        err = OMX_FillThisBuffer(appPriv->volume_handle, pOutBufferVolc[0]);
        err = OMX_FillThisBuffer(appPriv->volume_handle, pOutBufferVolc[1]);
        DEBUG(DEFAULT_MESSAGES, "---> After fill this buffer function calls to the volume component output buffers\n");
    }
    if (!flagSetupTunnel) {
        err = OMX_FillThisBuffer(appPriv->audiosrchandle, pOutBuffer[0]);
        err = OMX_FillThisBuffer(appPriv->audiosrchandle, pOutBuffer[1]);
    }

    DEBUG(DEB_LEV_SIMPLE_SEQ, "---> Before locking on condition and sourceMutex\n");

    DEBUG(DEFAULT_MESSAGES,"Enter 'q' or 'Q' to exit\n");

    while(1) {
        if('Q' == toupper(getchar())) {
            DEBUG(DEFAULT_MESSAGES,"Stoping capture\n");
            bEOS = OMX_TRUE;
            usleep(10000);
            break;
        }
    }

    DEBUG(DEFAULT_MESSAGES, "The execution of the audio decoding process is terminated\n");

    /** state change of all components from executing to idle */
    err = OMX_SendCommand(appPriv->audiosrchandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
    if(flagIsVolCompRequested == 1) {
        err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
        if(flagIsSinkRequested == 1) {
            err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
        }
    }

    tsem_down(appPriv->sourceEventSem);
    if(flagIsVolCompRequested == 1) {
        tsem_down(appPriv->volumeEventSem);
        if(flagIsSinkRequested == 1) {
            tsem_down(appPriv->alsasinkEventSem);
        }
    }

    DEBUG(DEFAULT_MESSAGES, "All audio components Transitioned to Idle\n");

    /** sending command to all components to go to loaded state */
    err = OMX_SendCommand(appPriv->audiosrchandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
    if(flagIsVolCompRequested == 1) {
        err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
        if(flagIsSinkRequested == 1) {
            err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
        }
    }

    /** freeing buffers of volume component and sink component */
    if(flagIsVolCompRequested == 1 && !flagSetupTunnel) {

        DEBUG(DEB_LEV_SIMPLE_SEQ, "volume component to loaded\n");
        err = OMX_FreeBuffer(appPriv->volume_handle, 0, pInBufferVolc[0]);
        err = OMX_FreeBuffer(appPriv->volume_handle, 0, pInBufferVolc[1]);

        err = OMX_FreeBuffer(appPriv->volume_handle, 1, pOutBufferVolc[0]);
        err = OMX_FreeBuffer(appPriv->volume_handle, 1, pOutBufferVolc[1]);

        if(flagIsSinkRequested == 1) {
            DEBUG(DEB_LEV_SIMPLE_SEQ, "Audio sink to loaded\n");
            err = OMX_FreeBuffer(appPriv->alsasink_handle, 0, pInBufferSink[0]);
            err = OMX_FreeBuffer(appPriv->alsasink_handle, 0, pInBufferSink[1]);
        }
    }

    /** freeing buffers of audio source input ports */
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Audio dec to loaded\n");
    if(!flagSetupTunnel) {
        DEBUG(DEB_LEV_PARAMS, "Free Audio dec output ports\n");
        err = OMX_FreeBuffer(appPriv->audiosrchandle, 0, pOutBuffer[0]);
        err = OMX_FreeBuffer(appPriv->audiosrchandle, 0, pOutBuffer[1]);
    }

    if(flagIsVolCompRequested == 1) {
        if(flagIsSinkRequested == 1) {
            tsem_down(appPriv->alsasinkEventSem);
        }
        tsem_down(appPriv->volumeEventSem);
    }
    tsem_down(appPriv->sourceEventSem);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "All components released\n");

    OMX_FreeHandle(appPriv->audiosrchandle);
    if(flagIsVolCompRequested == 1) {
        if(flagIsSinkRequested == 1) {
            OMX_FreeHandle(appPriv->alsasink_handle);
        }
        OMX_FreeHandle(appPriv->volume_handle);
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ, "audio dec freed\n");

    OMX_Deinit();

    DEBUG(DEFAULT_MESSAGES, "All components freed. Closing...\n");
    free(appPriv->sourceEventSem);
    if(flagIsVolCompRequested == 1) {
        if(flagIsSinkRequested == 1) {
            free(appPriv->alsasinkEventSem);
        }
        free(appPriv->volumeEventSem);
    }
    free(appPriv->eofSem);
    free(appPriv);

    free(full_component_name);

    /** closing the output file */
    if(!flagIsSinkRequested) {
        fclose(outfile);
    }
    if(output_file) {
        free(output_file);
    }

    return 0;
}
/** This is the central function for component processing. It
  * is executed in a separate thread, is synchronized with 
  * semaphores at each port, those are released each time a new buffer
  * is available on the given port.
  */
void* omx_base_sink_BufferMgmtFunction (void* param) {
  OMX_COMPONENTTYPE* openmaxStandComp = (OMX_COMPONENTTYPE*)param;
  omx_base_component_PrivateType* omx_base_component_Private  = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
  omx_base_sink_PrivateType*      omx_base_sink_Private       = (omx_base_sink_PrivateType*)omx_base_component_Private;
  omx_base_PortType               *pInPort                    = (omx_base_PortType *)omx_base_sink_Private->ports[OMX_BASE_SINK_INPUTPORT_INDEX];
  tsem_t*                         pInputSem                   = pInPort->pBufferSem;
  queue_t*                        pInputQueue                 = pInPort->pBufferQueue;
  OMX_BUFFERHEADERTYPE*           pInputBuffer                = NULL;
  OMX_COMPONENTTYPE*              target_component;
  OMX_BOOL                        isInputBufferNeeded         = OMX_TRUE;
  int                             inBufExchanged              = 0;

  DEBUG(DEB_LEV_FUNCTION_NAME, "In %s \n", __func__);
  while(omx_base_component_Private->state == OMX_StateIdle || omx_base_component_Private->state == OMX_StateExecuting ||  omx_base_component_Private->state == OMX_StatePause || 
    omx_base_component_Private->transientState == OMX_TransStateLoadedToIdle){

    /*Wait till the ports are being flushed*/
    pthread_mutex_lock(&omx_base_sink_Private->flush_mutex);
    while( PORT_IS_BEING_FLUSHED(pInPort)) {
      pthread_mutex_unlock(&omx_base_sink_Private->flush_mutex);

      if(isInputBufferNeeded==OMX_FALSE) {
        pInPort->ReturnBufferFunction(pInPort,pInputBuffer);
        inBufExchanged--;
        pInputBuffer=NULL;
        isInputBufferNeeded=OMX_TRUE;
        DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning input buffer\n");
      }
      DEBUG(DEB_LEV_FULL_SEQ, "In %s signalling flush all condition \n", __func__);
      
      tsem_up(omx_base_sink_Private->flush_all_condition);
      tsem_down(omx_base_sink_Private->flush_condition);
      pthread_mutex_lock(&omx_base_sink_Private->flush_mutex);
    }
    pthread_mutex_unlock(&omx_base_sink_Private->flush_mutex);

    /*No buffer to process. So wait here*/
    if((pInputSem->semval==0 && isInputBufferNeeded==OMX_TRUE ) && 
      (omx_base_sink_Private->state != OMX_StateLoaded && omx_base_sink_Private->state != OMX_StateInvalid)) {
      DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for input buffer \n");
      tsem_down(omx_base_sink_Private->bMgmtSem);
    }

    if(omx_base_sink_Private->state == OMX_StateLoaded || omx_base_sink_Private->state == OMX_StateInvalid) {
      DEBUG(DEB_LEV_FULL_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
      break;
    }

    DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for input buffer semval=%d \n",pInputSem->semval);
    if(pInputSem->semval>0 && isInputBufferNeeded==OMX_TRUE ) {
      tsem_down(pInputSem);
      if(pInputQueue->nelem>0){
        inBufExchanged++;
        isInputBufferNeeded=OMX_FALSE;
        pInputBuffer = dequeue(pInputQueue);
        if(pInputBuffer == NULL){
          DEBUG(DEB_LEV_ERR, "Had NULL input buffer!!\n");
          break;
        }
      }
    }
    
    if(isInputBufferNeeded==OMX_FALSE) {
      if(pInputBuffer->nFlags==OMX_BUFFERFLAG_EOS) {
        DEBUG(DEB_LEV_SIMPLE_SEQ, "Detected EOS flags in input buffer\n");
        
        (*(omx_base_component_Private->callbacks->EventHandler))
          (openmaxStandComp,
          omx_base_component_Private->callbackData,
          OMX_EventBufferFlag, /* The command was completed */
          0, /* The commands was a OMX_CommandStateSet */
          pInputBuffer->nFlags, /* The state has been changed in message->messageParam2 */
          NULL);
        pInputBuffer->nFlags=0;
      }
      
      target_component=(OMX_COMPONENTTYPE*)pInputBuffer->hMarkTargetComponent;
      if(target_component==(OMX_COMPONENTTYPE *)openmaxStandComp) {
        /*Clear the mark and generate an event*/
        (*(omx_base_component_Private->callbacks->EventHandler))
          (openmaxStandComp,
          omx_base_component_Private->callbackData,
          OMX_EventMark, /* The command was completed */
          1, /* The commands was a OMX_CommandStateSet */
          0, /* The state has been changed in message->messageParam2 */
          pInputBuffer->pMarkData);
      } else if(pInputBuffer->hMarkTargetComponent!=NULL){
        /*If this is not the target component then pass the mark*/
        DEBUG(DEB_LEV_FULL_SEQ, "Can't Pass Mark. This is a Sink!!\n");
      }
      if (omx_base_sink_Private->BufferMgmtCallback && pInputBuffer->nFilledLen > 0) {
        (*(omx_base_sink_Private->BufferMgmtCallback))(openmaxStandComp, pInputBuffer);
      }
      else {
        /*If no buffer management call back the explicitly consume input buffer*/
        pInputBuffer->nFilledLen = 0;
      }
      /*Input Buffer has been completely consumed. So, get new input buffer*/

      if(omx_base_sink_Private->state==OMX_StatePause && !PORT_IS_BEING_FLUSHED(pInPort)) {
        /*Waiting at paused state*/
        tsem_wait(omx_base_sink_Private->bStateSem);
      }

      /*Input Buffer has been completely consumed. So, return input buffer*/
      if(pInputBuffer->nFilledLen==0) {
        pInPort->ReturnBufferFunction(pInPort,pInputBuffer);
        inBufExchanged--;
        pInputBuffer=NULL;
        isInputBufferNeeded = OMX_TRUE;
      }

    }
  }
  DEBUG(DEB_LEV_SIMPLE_SEQ,"Exiting Buffer Management Thread\n");
  return NULL;
}
int main(int argc, char** argv) {
  int argn_dec;
  OMX_ERRORTYPE err;
  OMX_INDEXTYPE eIndexParamFilename;
  int gain=-1;
  OMX_AUDIO_CONFIG_VOLUMETYPE sVolume;
  OMX_TIME_CONFIG_TIMESTAMPTYPE sTimeStamp;
  OMX_PARAM_COMPONENTROLETYPE sComponentRole;
  
  char *stream_dir=NULL;
  DIR *dirp;
	struct dirent *dp;
  int seek=1;

  flagSetupTunnel = 1;
  flagPlaybackOn = 1;
  flagUsingFFMpeg = 1;
  flagIsGain = 0;

  if(argc <= 3) {
    argn_dec = 1;
    while (argn_dec<argc) {
      if (*(argv[argn_dec]) =='-') {
        switch (*(argv[argn_dec]+1)) {
        case 's':
          seek = 0;
          break;
        //case 't':
        //  flagSetupTunnel = 0;
        //  break;
        default:
          display_help();
        }
      } else {
        stream_dir = malloc(strlen(argv[argn_dec]) * sizeof(char) + 1);
        strcpy(stream_dir,argv[argn_dec]);
      }
      argn_dec++;
    }
  } else if(argc > 3) {
    display_help();
  }

  if(stream_dir==NULL) {

    stream_dir = malloc(strlen(getenv("HOME")) * sizeof(char) + 20);
    memset(stream_dir, 0, sizeof(stream_dir));
	  strcat(stream_dir, getenv("HOME"));
	  strcat(stream_dir, "/stream/audio/");
  }

  DEBUG(DEFAULT_MESSAGES, "Directory Name=%s\n",stream_dir);

  /* Populate the registry file */
	dirp = opendir(stream_dir);
	if(dirp == NULL){
    int err = errno;
		DEBUG(DEB_LEV_ERR, "Cannot open directory %s\n", stream_dir);
		return err;
	}

  
  /** initializing appPriv structure */
  appPriv = malloc(sizeof(appPrivateType));
  appPriv->filereaderEventSem = malloc(sizeof(tsem_t));
  appPriv->decoderEventSem = malloc(sizeof(tsem_t));
  appPriv->eofSem = malloc(sizeof(tsem_t));
  if (flagPlaybackOn) {
    appPriv->sinkEventSem = malloc(sizeof(tsem_t));
    tsem_init(appPriv->sinkEventSem, 0);
    appPriv->volumeEventSem = malloc(sizeof(tsem_t));
    tsem_init(appPriv->volumeEventSem, 0);
  }
  tsem_init(appPriv->filereaderEventSem, 0);
  tsem_init(appPriv->decoderEventSem, 0);
  tsem_init(appPriv->eofSem, 0);

  /** initialising openmax */
  err = OMX_Init();
  if (err != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "The OpenMAX core can not be initialized. Exiting...\n");
    exit(1);
  } 

  

  if(flagUsingFFMpeg) {
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Using File Reader\n");
    /** file reader component name -- gethandle*/
    err = OMX_GetHandle(&appPriv->filereaderhandle, FILE_READER, NULL , &filereadercallbacks);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "FileReader Component Not Found\n");
      exit(1);
    }  
    err = OMX_GetExtensionIndex(appPriv->filereaderhandle,"OMX.ST.index.param.inputfilename",&eIndexParamFilename);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"\n error in get extension index\n");
			exit(1);
    } 
  }

  /** getting the handle of audio decoder */
  err = OMX_GetHandle(&appPriv->audiodechandle, COMPONENT_NAME_BASE, NULL , &audiodeccallbacks);
  if(err != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Audio Decoder Component Not Found\n");
		exit(1);
  } 
  DEBUG(DEFAULT_MESSAGES, "Component %s opened\n", COMPONENT_NAME_BASE);

  if (flagPlaybackOn) {
    err = OMX_GetHandle(&appPriv->audiosinkhandle, SINK_NAME, NULL , &audiosinkcallbacks);
    if(err != OMX_ErrorNone){
      DEBUG(DEB_LEV_ERR, "No sink found. Exiting...\n");
      exit(1);
    }

    DEBUG(DEFAULT_MESSAGES, "Getting Handle for Component %s\n", AUDIO_EFFECT);
    err = OMX_GetHandle(&appPriv->volumehandle, AUDIO_EFFECT, NULL , &volumecallbacks);
    if(err != OMX_ErrorNone){
      DEBUG(DEB_LEV_ERR, "No sink found. Exiting...\n");
      exit(1);
    }

    if((gain >= 0) && (gain <100)) {
      err = OMX_GetConfig(appPriv->volumehandle, OMX_IndexConfigAudioVolume, &sVolume);
      if(err!=OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"Error %08x In OMX_GetConfig 0 \n",err);
      }
      sVolume.sVolume.nValue = gain;
      DEBUG(DEFAULT_MESSAGES, "Setting Gain %d \n", gain);
      err = OMX_SetConfig(appPriv->volumehandle, OMX_IndexConfigAudioVolume, &sVolume);
      if(err!=OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig 0 \n",err);
      }
    }
  }

  if (flagSetupTunnel) {
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Setting up Tunnel\n");
    if(flagUsingFFMpeg) {
      err = OMX_SetupTunnel(appPriv->filereaderhandle, 0, appPriv->audiodechandle, 0);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR, "Set up Tunnel Failed\n");
        exit(1);
      }
    }
    err = OMX_SetupTunnel(appPriv->audiodechandle, 1, appPriv->volumehandle, 0);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Set up Tunnel Failed\n");
      exit(1);
    }
    err = OMX_SetupTunnel(appPriv->volumehandle, 1, appPriv->audiosinkhandle, 0);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Set up Tunnel Failed\n");
      exit(1);
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Set up Tunnel Completed\n");
  }

  if(flagUsingFFMpeg) {
    /** now set the filereader component to idle and executing state */
    OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
  }

  /*Send State Change Idle command to Audio Decoder*/
  DEBUG(DEB_LEV_SIMPLE_SEQ, "Send Command Idle to Audio Dec\n");
  err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
  if (flagPlaybackOn) {
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Send Command Idle to Audio Sink\n");
    err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
    err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
  }

  if(flagUsingFFMpeg) {
      /*Wait for File reader state change to */
    tsem_down(appPriv->filereaderEventSem);
    DEBUG(DEFAULT_MESSAGES,"File reader idle state \n");
  }

  tsem_down(appPriv->decoderEventSem);
  if (flagPlaybackOn) {
    tsem_down(appPriv->volumeEventSem);
    DEBUG(DEFAULT_MESSAGES,"volume state idle\n");
    tsem_down(appPriv->sinkEventSem);
    DEBUG(DEFAULT_MESSAGES,"audio sink state idle\n");
  }

  if (flagPlaybackOn) {
    err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"volume state executing failed\n");
			exit(1);
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ,"waiting for  volume state executing\n");
    tsem_down(appPriv->volumeEventSem);

    DEBUG(DEB_LEV_SIMPLE_SEQ,"sending audio sink state executing\n");
    err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"audio sink state executing failed\n");
			exit(1);
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ,"waiting for  audio sink state executing\n");
    tsem_down(appPriv->sinkEventSem);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "audio sink state executing successful\n");
  } 
  
  setHeader(&sComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
  strcpy((char*)&sComponentRole.cRole[0], MP3_ROLE);

  while((dp = readdir(dirp)) != NULL) {
    int len = strlen(dp->d_name);

		if(len >= 3){
      
      if(strncmp(dp->d_name+len-4, ".mp3", 4) == 0){
        
        if(input_file!=NULL) {
          free(input_file);
          input_file=NULL;
        }

        input_file = malloc(strlen(stream_dir) * sizeof(char) + sizeof(dp->d_name) +1);
        strcpy(input_file,stream_dir);
				strcat(input_file, dp->d_name);

        DEBUG(DEFAULT_MESSAGES, "Input Mp3 File Name=%s\n",input_file);

        flagUsingFFMpeg = 1;

        strcpy((char*)&sComponentRole.cRole[0], MP3_ROLE);

      } else if(strncmp(dp->d_name+len-4, ".ogg", 4) == 0){
        
        if(input_file!=NULL) {
          free(input_file);
          input_file=NULL;
        }

        input_file = malloc(strlen(stream_dir) * sizeof(char) + sizeof(dp->d_name) +1);
        strcpy(input_file,stream_dir);
				strcat(input_file, dp->d_name);

        DEBUG(DEFAULT_MESSAGES, "Input Vorbis File Name=%s\n",input_file);

        flagUsingFFMpeg = 1;

        strcpy((char*)&sComponentRole.cRole[0], VORBIS_ROLE);
                
      } else if(strncmp(dp->d_name+len-4, ".aac", 4) == 0){
        
        if(input_file!=NULL) {
          free(input_file);
          input_file=NULL;
        }

        input_file = malloc(strlen(stream_dir) * sizeof(char) + sizeof(dp->d_name) +1);
        strcpy(input_file,stream_dir);
				strcat(input_file, dp->d_name);

        DEBUG(DEFAULT_MESSAGES, "Input AAC File Name=%s\n",input_file);

        flagUsingFFMpeg = 1;

        strcpy((char*)&sComponentRole.cRole[0], AAC_ROLE);
                
      } else {
        continue;
      }
    } else {
      continue;
    }

    
    /*Reset Global Variables*/
    tsem_reset(appPriv->eofSem);
    bEOS=OMX_FALSE;

    if (flagUsingFFMpeg) {
      DEBUG(DEB_LEV_SIMPLE_SEQ,"Sending Port Disable Command State Idle\n");
      /*Port Disable for filereader is sent from Port Settings Changed event of FileReader*/
      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandPortDisable, 0, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"file reader port disable failed\n");
			  exit(1);
      }
      err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandPortDisable, OMX_ALL, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"audio decoder port disable failed\n");
			  exit(1);
      }

      err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandPortDisable, 0, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"audio sink port disable failed\n");
			  exit(1);
      }
      
      DEBUG(DEB_LEV_SIMPLE_SEQ,"Waiting File reader Port Disable event \n");
      /*Wait for File Reader Ports Disable Event*/
      tsem_down(appPriv->filereaderEventSem);
      DEBUG(DEB_LEV_SIMPLE_SEQ,"File reader Port Disable State Idle\n");
      /*Wait for Audio Decoder Ports Disable Event*/
      tsem_down(appPriv->decoderEventSem);
      tsem_down(appPriv->decoderEventSem);

      tsem_down(appPriv->volumeEventSem);

      err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
      tsem_down(appPriv->decoderEventSem);
    }


    DEBUG(DEB_LEV_SIMPLE_SEQ,"Setting Role\n");

    err = OMX_SetParameter(appPriv->audiodechandle,OMX_IndexParamStandardComponentRole,&sComponentRole);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"\n error in input audio format - exiting\n");
      exit(1);
    }

    if(flagUsingFFMpeg) {
      /** setting the input audio format in file reader */
      DEBUG(DEB_LEV_SIMPLE_SEQ,"FileName Param index : %x \n",eIndexParamFilename);
      err = OMX_SetParameter(appPriv->filereaderhandle,eIndexParamFilename,input_file);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"\n error in input audio format - exiting\n");
        exit(1);
      }
    }
    
    if (flagUsingFFMpeg) {
      DEBUG(DEB_LEV_SIMPLE_SEQ,"Sending Port Enable Command State Idle\n");

      err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
      tsem_down(appPriv->decoderEventSem);

      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandPortEnable, 0, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"file reader port enable failed\n");
			  exit(1);
      }
      err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandPortEnable, OMX_ALL, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"audio decoder port enable failed\n");
			  exit(1);
      }

      err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandPortEnable, 0, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"audio sink port enable failed\n");
			  exit(1);
      }
      
      DEBUG(DEB_LEV_SIMPLE_SEQ,"Waiting File reader Port Disable event \n");
      /*Wait for File Reader Ports Disable Event*/
      tsem_down(appPriv->filereaderEventSem);
      DEBUG(DEB_LEV_SIMPLE_SEQ,"File reader Port Disable State Idle\n");
      /*Wait for Audio Decoder Ports Disable Event*/
      tsem_down(appPriv->decoderEventSem);
      tsem_down(appPriv->decoderEventSem);
      
      tsem_down(appPriv->volumeEventSem);

      
    }

    if(flagUsingFFMpeg) {
      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"file reader state executing failed\n");
			  exit(1);
      }
      /*Wait for File reader state change to executing*/
      tsem_down(appPriv->filereaderEventSem);
      DEBUG(DEFAULT_MESSAGES,"File reader executing state \n");
    }

    err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"audio decoder state executing failed\n");
      exit(1);
    }
    
    DEBUG(DEB_LEV_SIMPLE_SEQ,"Waiting for audio dec state exec\n");
    /*Wait for decoder state change to executing*/
    tsem_down(appPriv->decoderEventSem);

    DEBUG(DEB_LEV_SIMPLE_SEQ,"All Component state changed to Executing\n");
    
    DEBUG(DEFAULT_MESSAGES,"Waiting for  EOS = %d\n",appPriv->eofSem->semval);

    if (seek==1) {

      DEBUG(DEFAULT_MESSAGES,"Sleeping for 5 Secs \n");
      /* Play for 5 Secs */
      sleep(5);
      DEBUG(DEFAULT_MESSAGES,"Sleep for 5 Secs is over\n");

      /*Then Pause the filereader component*/
      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StatePause, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"file reader state executing failed\n");
			  exit(1);
      }
      /*Wait for File reader state change to Pause*/
      tsem_down(appPriv->filereaderEventSem);

      setHeader(&sTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
      sTimeStamp.nPortIndex=0;
      /*Seek to 30 secs and play for 10 secs*/
      sTimeStamp.nTimestamp = 2351*38*30; // 23.51ms*38fps*30secs
      //sTimeStamp.nTimestamp = 2351*38*60*3; // 23.51ms*38fps*60secs*4mins
      DEBUG(DEFAULT_MESSAGES, "nTimestamp %llx \n", sTimeStamp.nTimestamp);
      err = OMX_SetConfig(appPriv->filereaderhandle, OMX_IndexConfigTimePosition, &sTimeStamp);
      if(err!=OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetParameter 0 \n",err);
      }

      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"file reader state executing failed\n");
			  exit(1);
      }
      /*Wait for File reader state change to Pause*/
      tsem_down(appPriv->filereaderEventSem);

      DEBUG(DEFAULT_MESSAGES,"Sleeping for 10 Secs \n");
      /*Play for 10 secs*/
      sleep(10);
      DEBUG(DEFAULT_MESSAGES,"Sleep for 10 Secs is over\n");

      if(!bEOS) {
        /*Then Pause the filereader component*/
        err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StatePause, NULL);
        if(err != OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"file reader state executing failed\n");
			    exit(1);
        }
        /*Wait for File reader state change to Pause*/
        tsem_down(appPriv->filereaderEventSem);

        /*Seek to 5 mins or EOF*/
        sTimeStamp.nTimestamp = 2351*38*60*5; // 23.51ms*38fps*30secs
        //sTimeStamp.nTimestamp = 2351*38*60*3; // 23.51ms*38fps*60secs*4mins
        DEBUG(DEFAULT_MESSAGES, "nTimestamp %llx \n", sTimeStamp.nTimestamp);
        err = OMX_SetConfig(appPriv->filereaderhandle, OMX_IndexConfigTimePosition, &sTimeStamp);
        if(err!=OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetParameter 0 \n",err);
        }

        err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
        if(err != OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"file reader state executing failed\n");
			    exit(1);
        }
        /*Wait for File reader state change to Pause*/
        tsem_down(appPriv->filereaderEventSem);
      }
    }

    tsem_down(appPriv->eofSem);

    DEBUG(DEFAULT_MESSAGES,"Received EOS \n");
    /*Send Idle Command to all components*/
    DEBUG(DEFAULT_MESSAGES, "The execution of the decoding process is terminated\n");
    if(flagUsingFFMpeg) {
      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
    }
    err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
    
    if(flagUsingFFMpeg) {
      tsem_down(appPriv->filereaderEventSem);
      DEBUG(DEFAULT_MESSAGES,"File reader idle state \n");
    }
    tsem_down(appPriv->decoderEventSem);
    
    DEBUG(DEFAULT_MESSAGES, "All component Transitioned to Idle\n");

  } /*Loop While Play List*/

  if (flagPlaybackOn) {
    err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
    err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
  }

  if (flagPlaybackOn) {
    tsem_down(appPriv->volumeEventSem);
    tsem_down(appPriv->sinkEventSem);
  }
  /*Send Loaded Command to all components*/
  if(flagUsingFFMpeg) {
    err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
  }
  err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
  if (flagPlaybackOn) {
    err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
    err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
  }

  DEBUG(DEFAULT_MESSAGES, "Audio dec to loaded\n");

  if(flagUsingFFMpeg) {
    tsem_down(appPriv->filereaderEventSem);
    DEBUG(DEFAULT_MESSAGES,"File reader loaded state \n");
  }
  tsem_down(appPriv->decoderEventSem);
  if (flagPlaybackOn) {
    tsem_down(appPriv->volumeEventSem);
    tsem_down(appPriv->sinkEventSem);
  }

  if(input_file!=NULL) {
    free(input_file);
    input_file=NULL;
  }

  closedir(dirp);

  DEBUG(DEFAULT_MESSAGES, "All components released\n");

  /** freeing all handles and deinit omx */
  OMX_FreeHandle(appPriv->audiodechandle);

  DEBUG(DEB_LEV_SIMPLE_SEQ, "audiodec dec freed\n");
  
  if(flagUsingFFMpeg) {
    OMX_FreeHandle(appPriv->filereaderhandle);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "filereader freed\n");
  }

  if (flagPlaybackOn) {
    OMX_FreeHandle(appPriv->volumehandle);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "volume component freed\n");
    OMX_FreeHandle(appPriv->audiosinkhandle);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "audiosink freed\n");
  }

  OMX_Deinit();

  DEBUG(DEB_LEV_SIMPLE_SEQ, "All components freed. Closing...\n");

  free(appPriv->filereaderEventSem);
  appPriv->filereaderEventSem = NULL;

  free(appPriv->decoderEventSem);
  appPriv->decoderEventSem = NULL;
  if (flagPlaybackOn) {
    free(appPriv->volumeEventSem);
    appPriv->volumeEventSem = NULL;

    free(appPriv->sinkEventSem);
    appPriv->sinkEventSem = NULL;
  }

  free(appPriv->eofSem);
  appPriv->eofSem = NULL;
  free(appPriv);
  appPriv = NULL;

  if(input_file) {
    free(input_file);
  }

  return 0;
}