/** The Constructor
 */
OMX_ERRORTYPE omx_clocksrc_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName) {
  int                                 omxErr;
  omx_clocksrc_component_PrivateType* omx_clocksrc_component_Private;
  OMX_U32 i;

	RM_RegisterComponent(CLOCK_COMP_NAME, MAX_CLOCK_COMPONENTS);

  if (!openmaxStandComp->pComponentPrivate) {
    openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_clocksrc_component_PrivateType));
    if(openmaxStandComp->pComponentPrivate==NULL) {
      return OMX_ErrorInsufficientResources;
    }
  }

  omx_clocksrc_component_Private = openmaxStandComp->pComponentPrivate;
  omx_clocksrc_component_Private->ports = NULL;

  omxErr = omx_base_source_Constructor(openmaxStandComp,cComponentName);
  if (omxErr != OMX_ErrorNone) {
    return OMX_ErrorInsufficientResources;
  }

  omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nStartPortNumber = 0;
  omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts = 3;

  /** Allocate Ports and call port constructor. */
  if (omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts && !omx_clocksrc_component_Private->ports) {
    omx_clocksrc_component_Private->ports = calloc(omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts, sizeof(omx_base_PortType *));
    if (!omx_clocksrc_component_Private->ports) {
      return OMX_ErrorInsufficientResources;
    }
    for (i=0; i < omx_clocksrc_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts; i++) {
      omx_clocksrc_component_Private->ports[i] = calloc(1, sizeof(omx_base_clock_PortType));
      if (!omx_clocksrc_component_Private->ports[i]) {
        return OMX_ErrorInsufficientResources;
      }
      base_clock_port_Constructor(openmaxStandComp, &omx_clocksrc_component_Private->ports[i], i, OMX_FALSE);
      omx_clocksrc_component_Private->ports[i]->FlushProcessingBuffers = clocksrc_port_FlushProcessingBuffers;
    }
  }


  /* initializing the OMX_TIME_CONFIG_CLOCKSTATETYPE */
  setHeader(&omx_clocksrc_component_Private->sClockState, sizeof(OMX_TIME_CONFIG_CLOCKSTATETYPE));
  omx_clocksrc_component_Private->sClockState.eState     = OMX_TIME_ClockStateStopped;
  omx_clocksrc_component_Private->sClockState.nStartTime = 0;
  omx_clocksrc_component_Private->sClockState.nOffset    = 0;
  omx_clocksrc_component_Private->sClockState.nWaitMask  = 0xFF;

  setHeader(&omx_clocksrc_component_Private->sMinStartTime, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
  omx_clocksrc_component_Private->sMinStartTime.nTimestamp = 0;
  omx_clocksrc_component_Private->sMinStartTime.nPortIndex = 0;

  setHeader(&omx_clocksrc_component_Private->sConfigScale, sizeof(OMX_TIME_CONFIG_SCALETYPE));
  omx_clocksrc_component_Private->sConfigScale.xScale = 1<<16;  /* normal play mode */

  setHeader(&omx_clocksrc_component_Private->sRefClock, sizeof(OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE));
  omx_clocksrc_component_Private->sRefClock.eClock = OMX_TIME_RefClockNone;
  omx_clocksrc_component_Private->eUpdateType = OMX_TIME_UpdateMax;

  if(!omx_clocksrc_component_Private->clockEventSem) {
    omx_clocksrc_component_Private->clockEventSem = calloc(1,sizeof(tsem_t));
    tsem_init(omx_clocksrc_component_Private->clockEventSem, 0);
  }

  if(!omx_clocksrc_component_Private->clockEventCompleteSem) {
    omx_clocksrc_component_Private->clockEventCompleteSem = calloc(1,sizeof(tsem_t));
    tsem_init(omx_clocksrc_component_Private->clockEventCompleteSem, 0);
  }

  omx_clocksrc_component_Private->BufferMgmtCallback = omx_clocksrc_component_BufferMgmtCallback;
  omx_clocksrc_component_Private->destructor = omx_clocksrc_component_Destructor;
  omx_clocksrc_component_Private->BufferMgmtFunction = omx_clocksrc_BufferMgmtFunction;

  openmaxStandComp->SetParameter  = omx_clocksrc_component_SetParameter;
  openmaxStandComp->GetParameter  = omx_clocksrc_component_GetParameter;

  openmaxStandComp->SetConfig  = omx_clocksrc_component_SetConfig;
  openmaxStandComp->GetConfig  = omx_clocksrc_component_GetConfig;
  openmaxStandComp->SendCommand = omx_clocksrc_component_SendCommand;

  return OMX_ErrorNone;
}
/** The Constructor
 */
OMX_ERRORTYPE omx_parser3gp_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName) {

  OMX_ERRORTYPE err = OMX_ErrorNone;
  omx_base_video_PortType *pPortV;
  omx_base_audio_PortType *pPortA;
  omx_parser3gp_component_PrivateType* omx_parser3gp_component_Private;
  DEBUG(DEB_LEV_FUNCTION_NAME,"In %s \n",__func__);

  if (!openmaxStandComp->pComponentPrivate) {
    openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_parser3gp_component_PrivateType));
    if(openmaxStandComp->pComponentPrivate == NULL) {
      return OMX_ErrorInsufficientResources;
    }
  }

  /*Assign size of the derived port class,so that proper memory for port class can be allocated*/
  omx_parser3gp_component_Private = openmaxStandComp->pComponentPrivate;
  omx_parser3gp_component_Private->ports = NULL;

  err = omx_base_source_Constructor(openmaxStandComp, cComponentName);

  omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainVideo].nStartPortNumber = 0;
  omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts = 1;

  omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainAudio].nStartPortNumber = 1;
  omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts = 1;

  omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainOther].nStartPortNumber = 2;
  omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts = 1;

   /** Allocate Ports and call port constructor. */
  if ((omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts  +
       omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts +
       omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts ) && !omx_parser3gp_component_Private->ports) {
       omx_parser3gp_component_Private->ports = calloc((omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts  +
                                                        omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts +
                                                        omx_parser3gp_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts ), sizeof(omx_base_PortType *));
    if (!omx_parser3gp_component_Private->ports) {
      return OMX_ErrorInsufficientResources;
    }
    /* allocate video port*/
   omx_parser3gp_component_Private->ports[VIDEO_PORT_INDEX] = calloc(1, sizeof(omx_base_video_PortType));
   if (!omx_parser3gp_component_Private->ports[VIDEO_PORT_INDEX])
       return OMX_ErrorInsufficientResources;
   /* allocate audio port*/
   omx_parser3gp_component_Private->ports[AUDIO_PORT_INDEX] = calloc(1, sizeof(omx_base_audio_PortType));
   if (!omx_parser3gp_component_Private->ports[AUDIO_PORT_INDEX])
       return OMX_ErrorInsufficientResources;
   /* allocate clock port*/
   omx_parser3gp_component_Private->ports[CLOCK_PORT_INDEX] = calloc(1, sizeof(omx_base_clock_PortType));
   if (!omx_parser3gp_component_Private->ports[CLOCK_PORT_INDEX])
     return OMX_ErrorInsufficientResources;

  }

  base_video_port_Constructor(openmaxStandComp, &omx_parser3gp_component_Private->ports[VIDEO_PORT_INDEX], VIDEO_PORT_INDEX, OMX_FALSE);
  base_audio_port_Constructor(openmaxStandComp, &omx_parser3gp_component_Private->ports[AUDIO_PORT_INDEX], AUDIO_PORT_INDEX, OMX_FALSE);
  base_clock_port_Constructor(openmaxStandComp, &omx_parser3gp_component_Private->ports[CLOCK_PORT_INDEX], CLOCK_PORT_INDEX, OMX_TRUE);
  omx_parser3gp_component_Private->ports[CLOCK_PORT_INDEX]->sPortParam.bEnabled = OMX_FALSE;

  pPortV = (omx_base_video_PortType *) omx_parser3gp_component_Private->ports[VIDEO_PORT_INDEX];
  pPortA = (omx_base_audio_PortType *) omx_parser3gp_component_Private->ports[AUDIO_PORT_INDEX];

  /*Input pPort buffer size is equal to the size of the output buffer of the previous component*/
  pPortV->sPortParam.nBufferSize = DEFAULT_OUT_BUFFER_SIZE;
  pPortA->sPortParam.nBufferSize = DEFAULT_IN_BUFFER_SIZE;

  omx_parser3gp_component_Private->BufferMgmtCallback = omx_parser3gp_component_BufferMgmtCallback;
  omx_parser3gp_component_Private->BufferMgmtFunction = omx_base_source_twoport_BufferMgmtFunction;

  setHeader(&omx_parser3gp_component_Private->sTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
  omx_parser3gp_component_Private->sTimeStamp.nPortIndex=0;
  omx_parser3gp_component_Private->sTimeStamp.nTimestamp=0x0;

  omx_parser3gp_component_Private->destructor = omx_parser3gp_component_Destructor;
  omx_parser3gp_component_Private->messageHandler = omx_parser3gp_component_MessageHandler;

  noParser3gpInstance++;
  if(noParser3gpInstance > MAX_COMPONENT_PARSER_3GP) {
    return OMX_ErrorInsufficientResources;
  }

  openmaxStandComp->SetParameter  = omx_parser3gp_component_SetParameter;
  openmaxStandComp->GetParameter  = omx_parser3gp_component_GetParameter;
  openmaxStandComp->SetConfig     = omx_parser3gp_component_SetConfig;
  openmaxStandComp->GetExtensionIndex = omx_parser3gp_component_GetExtensionIndex;

  /* Write in the default paramenters */

  omx_parser3gp_component_Private->pTmpOutputBuffer = calloc(1,sizeof(OMX_BUFFERHEADERTYPE));
  omx_parser3gp_component_Private->pTmpOutputBuffer->pBuffer = calloc(1,DEFAULT_OUT_BUFFER_SIZE);
  omx_parser3gp_component_Private->pTmpOutputBuffer->nFilledLen=0;
  omx_parser3gp_component_Private->pTmpOutputBuffer->nAllocLen=DEFAULT_OUT_BUFFER_SIZE;
  omx_parser3gp_component_Private->pTmpOutputBuffer->nOffset=0;

  omx_parser3gp_component_Private->avformatReady      = OMX_FALSE;
  omx_parser3gp_component_Private->isFirstBufferAudio = OMX_TRUE;
  omx_parser3gp_component_Private->isFirstBufferVideo = OMX_TRUE;

  if(!omx_parser3gp_component_Private->avformatSyncSem) {
    omx_parser3gp_component_Private->avformatSyncSem = calloc(1,sizeof(tsem_t));
    if(omx_parser3gp_component_Private->avformatSyncSem == NULL) return OMX_ErrorInsufficientResources;
    tsem_init(omx_parser3gp_component_Private->avformatSyncSem, 0);
  }
  omx_parser3gp_component_Private->sInputFileName = malloc(DEFAULT_FILENAME_LENGTH);
  /*Default Coding type*/
  omx_parser3gp_component_Private->video_coding_type = OMX_VIDEO_CodingAVC;
  omx_parser3gp_component_Private->audio_coding_type = OMX_AUDIO_CodingMP3;
  av_register_all();  /* without this file opening gives an error */

  return err;
}
/** The Constructor 
 */
OMX_ERRORTYPE omx_videosrc_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName) {
 
  OMX_ERRORTYPE err = OMX_ErrorNone;  
  omx_base_video_PortType *pPort;
  omx_videosrc_component_PrivateType* omx_videosrc_component_Private;
  OMX_U32 i;

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

  if (!openmaxStandComp->pComponentPrivate) {
    openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_videosrc_component_PrivateType));
    if(openmaxStandComp->pComponentPrivate == NULL) {
      return OMX_ErrorInsufficientResources;
    }
  }

  omx_videosrc_component_Private = openmaxStandComp->pComponentPrivate;
  omx_videosrc_component_Private->ports = NULL;
  omx_videosrc_component_Private->deviceHandle = -1;
  
  err = omx_base_source_Constructor(openmaxStandComp, cComponentName);
  
  omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo].nStartPortNumber = 0;
  omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts = 1;

    /** Allocate Ports and call port constructor. */  
  if (omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts && !omx_videosrc_component_Private->ports) {
    omx_videosrc_component_Private->ports = calloc(omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts, sizeof(omx_base_PortType *));
    if (!omx_videosrc_component_Private->ports) {
      return OMX_ErrorInsufficientResources;
    }
    for (i=0; i < omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts; i++) {
      omx_videosrc_component_Private->ports[i] = calloc(1, sizeof(omx_base_video_PortType));
      if (!omx_videosrc_component_Private->ports[i]) {
        return OMX_ErrorInsufficientResources;
      }
    }
  }

  base_video_port_Constructor(openmaxStandComp, &omx_videosrc_component_Private->ports[0], 0, OMX_FALSE);
  omx_videosrc_component_Private->ports[0]->Port_AllocateBuffer = videosrc_port_AllocateBuffer;
  omx_videosrc_component_Private->ports[0]->Port_FreeBuffer = videosrc_port_FreeBuffer;
  omx_videosrc_component_Private->ports[0]->Port_AllocateTunnelBuffer = videosrc_port_AllocateTunnelBuffer;
  omx_videosrc_component_Private->ports[0]->Port_FreeTunnelBuffer = videosrc_port_FreeTunnelBuffer;

  pPort = (omx_base_video_PortType *) omx_videosrc_component_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX];
  
  pPort->sPortParam.format.video.nFrameWidth = 320;
  pPort->sPortParam.format.video.nFrameHeight= 240;
  pPort->sPortParam.format.video.eColorFormat= OMX_COLOR_FormatYUV420Planar;
  pPort->sVideoParam.eColorFormat = OMX_COLOR_FormatYUV420Planar;

  pPort->sPortParam.nBufferSize = pPort->sPortParam.format.video.nFrameWidth*
                                  pPort->sPortParam.format.video.nFrameHeight*3; // RGB888
  omx_videosrc_component_Private->iFrameSize = pPort->sPortParam.nBufferSize;

  omx_videosrc_component_Private->BufferMgmtCallback = omx_videosrc_component_BufferMgmtCallback;
  omx_videosrc_component_Private->destructor = omx_videosrc_component_Destructor;
  omx_videosrc_component_Private->messageHandler = omx_videosrc_component_MessageHandler;

  noViderSrcInstance++;
  if(noViderSrcInstance > MAX_COMPONENT_VIDEOSRC) {
    return OMX_ErrorInsufficientResources;
  }

  openmaxStandComp->SetParameter  = omx_videosrc_component_SetParameter;
  openmaxStandComp->GetParameter  = omx_videosrc_component_GetParameter;

  /* Write in the default paramenters */
  omx_videosrc_component_Private->videoReady = OMX_FALSE;
  if(!omx_videosrc_component_Private->videoSyncSem) {
    omx_videosrc_component_Private->videoSyncSem = calloc(1,sizeof(tsem_t));
    if(omx_videosrc_component_Private->videoSyncSem == NULL) return OMX_ErrorInsufficientResources;
    tsem_init(omx_videosrc_component_Private->videoSyncSem, 0);
  }

  omx_videosrc_component_Private->bOutBufferMemoryMapped = OMX_FALSE;

  /* Test if Camera Attached */
  omx_videosrc_component_Private->deviceHandle = open(VIDEO_DEV_NAME, O_RDWR /* required */  | O_NONBLOCK, 0);
  if (omx_videosrc_component_Private->deviceHandle < 0) {
    DEBUG(DEB_LEV_ERR, "In %s Unable to open video capture device %s! errno=%d  ENODEV : %d \n", 
      __func__,VIDEO_DEV_NAME,errno,ENODEV);
    return OMX_ErrorHardware;
  } 

  omx_videosrc_component_Private->pixel_format = V4L2_PIX_FMT_YUV420;

  err = init_device(omx_videosrc_component_Private);

  err = init_mmap(omx_videosrc_component_Private);

  return err;
}
OMX_ERRORTYPE omx_audio_capturer_component_Constructor(
  OMX_COMPONENTTYPE *pComponent,
  OMX_STRING cComponentName)
{
  OMX_ERRORTYPE err = OMX_ErrorNone;
  omx_audio_capturer_component_PrivateType* pPrivate;
  omx_audio_capturer_component_PortType* pPort;

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

  if(OMX_ErrorNone == err) {
    if(NULL == pComponent->pComponentPrivate) {
      pComponent->pComponentPrivate = calloc(1, sizeof(omx_audio_capturer_component_PrivateType));
      if(pComponent->pComponentPrivate == NULL) {
	return OMX_ErrorInsufficientResources;
      }
    } else {
      DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, Error Component %x Already Allocated\n", __func__, (int) pComponent->pComponentPrivate);
    }
  }

  /** Calling base source constructor */
  if(OMX_ErrorNone == err)
    err = omx_base_source_Constructor(pComponent, cComponentName);

  if(OMX_ErrorNone == err) {

    pPrivate = pComponent->pComponentPrivate;
    pPrivate->sPortTypesParam[OMX_PortDomainAudio].nPorts = NUM_PORTS;

    /** Allocate Ports and call port constructor. */
    pPrivate->ports = calloc(pPrivate->sPortTypesParam[OMX_PortDomainAudio].nPorts, sizeof(omx_base_PortType *));
    if (NULL == pPrivate->ports)
      return OMX_ErrorInsufficientResources;

    pPrivate->ports[0] = calloc(1, sizeof(omx_audio_capturer_component_PortType));
    if (NULL == pPrivate->ports[0])
      return OMX_ErrorInsufficientResources;

    /* construct output port */
    base_audio_port_Constructor(pComponent, &pPrivate->ports[0], 0, OMX_FALSE);

    /** Domain specific section for the ports. */
    pPort = (omx_audio_capturer_component_PortType *) pPrivate->ports[0];
    pPort->sPortParam.nBufferSize = DEFAULT_OUT_BUFFER_SIZE;

    /* OMX_AUDIO_PARAM_PCMMODETYPE */
    setHeader(&pPort->sPCMModeParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
    pPort->sPCMModeParam.nPortIndex = 0;
    pPort->sPCMModeParam.nChannels = 2;
    pPort->sPCMModeParam.eNumData = OMX_NumericalDataSigned;
    pPort->sPCMModeParam.eEndian = OMX_EndianLittle;
    pPort->sPCMModeParam.bInterleaved = OMX_TRUE;
    pPort->sPCMModeParam.nBitPerSample = 16;
    pPort->sPCMModeParam.nSamplingRate = 8000;
    pPort->sPCMModeParam.ePCMMode = OMX_AUDIO_PCMModeLinear;
    pPort->sPCMModeParam.eChannelMapping[0] = OMX_AUDIO_ChannelNone;

    pComponent->GetParameter = omx_audio_capturer_GetParameter;
    pComponent->SetParameter = omx_audio_capturer_SetParameter;
    pPrivate->BufferMgmtCallback = omx_audio_capturer_component_BufferMgmtCallback;
    pPrivate->destructor = omx_audio_capturer_component_Destructor;


  }

  if((MAX_COMPONENT_INSTANCES > 0) &&
     (nComponentInstances >= MAX_COMPONENT_INSTANCES)) {
    return OMX_ErrorInsufficientResources;
  } else nComponentInstances++;

  return err;
}