int
portSettingsChangedAgain(OPENMAX_JPEG_DECODER * decoder)
{
    printf("Port settings changed again\n");
    ilclient_disable_port(decoder->imageDecoder->component,
			  decoder->imageDecoder->outPort);

    OMX_PARAM_PORTDEFINITIONTYPE portdef;

    // need to setup the input for the render with the output of the
    // decoder
    portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
    portdef.nVersion.nVersion = OMX_VERSION;
    portdef.nPortIndex = decoder->imageDecoder->outPort;
    OMX_GetParameter(decoder->imageDecoder->handle,
		     OMX_IndexParamPortDefinition, &portdef);


    // enable output of decoder and input of render (ie enable tunnel)
    ilclient_enable_port(decoder->imageDecoder->component,
			 decoder->imageDecoder->outPort);

    // need to wait for this event
    ilclient_wait_for_event(decoder->imageDecoder->component,
			    OMX_EventPortSettingsChanged,
			    decoder->imageDecoder->outPort, 1,
			    0, 0, 0, TIMEOUT_MS);
    return OMXJPEG_OK;
}
示例#2
0
static void omx_renderer_init(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig) {
  int rc, error;
  OMX_ERRORTYPE err;
  unsigned char omxMapping[6];
  char* componentName = "audio_render";

  channelCount = opusConfig->channelCount;
  /* The supplied mapping array has order: FL-FR-C-LFE-RL-RR
   * OMX expects the order: FL-FR-LFE-C-RL-RR
   * We need copy the mapping locally and swap the channels around.
   */
  memcpy(omxMapping, opusConfig->mapping, sizeof(omxMapping));
  if (opusConfig->channelCount > 2) {
    omxMapping[2] = opusConfig->mapping[3];
    omxMapping[3] = opusConfig->mapping[2];
  }

  decoder = opus_multistream_decoder_create(opusConfig->sampleRate,
                                            opusConfig->channelCount,
                                            opusConfig->streams,
                                            opusConfig->coupledStreams,
                                            omxMapping,
                                            &rc);

  handle = ilclient_init();
  if (handle == NULL) {
  	fprintf(stderr, "IL client init failed\n");
  	exit(1);
  }

  if (ilclient_create_component(handle, &component, componentName, ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0) {
    fprintf(stderr, "Component create failed\n");
    exit(1);
  }

  if (ilclient_change_component_state(component, OMX_StateIdle)!= 0) {
    fprintf(stderr, "Couldn't change state to Idle\n");
    exit(1);
  }

  // must be before we enable buffers
  OMX_AUDIO_PARAM_PORTFORMATTYPE audioPortFormat;
  memset(&audioPortFormat, 0, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
  audioPortFormat.nSize = sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE);
  audioPortFormat.nVersion.nVersion = OMX_VERSION;

  audioPortFormat.nPortIndex = 100;

  OMX_GetParameter(ilclient_get_handle(component), OMX_IndexParamAudioPortFormat, &audioPortFormat);

  audioPortFormat.eEncoding = OMX_AUDIO_CodingPCM;
  OMX_SetParameter(ilclient_get_handle(component), OMX_IndexParamAudioPortFormat, &audioPortFormat);

  OMX_AUDIO_PARAM_PCMMODETYPE sPCMMode;

  memset(&sPCMMode, 0, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
  sPCMMode.nSize = sizeof(OMX_AUDIO_PARAM_PCMMODETYPE);
  sPCMMode.nVersion.nVersion = OMX_VERSION;
  sPCMMode.nPortIndex = 100;
  sPCMMode.nChannels = channelCount;
  sPCMMode.eNumData = OMX_NumericalDataSigned;
  sPCMMode.eEndian = OMX_EndianLittle;
  sPCMMode.nSamplingRate = opusConfig->sampleRate;
  sPCMMode.bInterleaved = OMX_TRUE;
  sPCMMode.nBitPerSample = 16;
  sPCMMode.ePCMMode = OMX_AUDIO_PCMModeLinear;

  switch(channelCount) {
  case 1:
     sPCMMode.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
     break;
  case 8:
     sPCMMode.eChannelMapping[7] = OMX_AUDIO_ChannelRS;
  case 7:
     sPCMMode.eChannelMapping[6] = OMX_AUDIO_ChannelLS;
  case 6:
     sPCMMode.eChannelMapping[5] = OMX_AUDIO_ChannelRR;
  case 5:
     sPCMMode.eChannelMapping[4] = OMX_AUDIO_ChannelLR;
  case 4:
     sPCMMode.eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
  case 3:
     sPCMMode.eChannelMapping[2] = OMX_AUDIO_ChannelCF;
  case 2:
     sPCMMode.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
     sPCMMode.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
     break;
  }

  err = OMX_SetParameter(ilclient_get_handle(component), OMX_IndexParamAudioPcm, &sPCMMode);
  if(err != OMX_ErrorNone){
  	fprintf(stderr, "PCM mode unsupported\n");
  	return;
  }
  OMX_CONFIG_BRCMAUDIODESTINATIONTYPE arDest;

  if (audio_device == NULL)
    audio_device = "hdmi";

  if (audio_device && strlen(audio_device) < sizeof(arDest.sName)) {
    memset(&arDest, 0, sizeof(OMX_CONFIG_BRCMAUDIODESTINATIONTYPE));
    arDest.nSize = sizeof(OMX_CONFIG_BRCMAUDIODESTINATIONTYPE);
    arDest.nVersion.nVersion = OMX_VERSION;

    strcpy((char *)arDest.sName, audio_device);

    err = OMX_SetParameter(ilclient_get_handle(component), OMX_IndexConfigBrcmAudioDestination, &arDest);
    if (err != OMX_ErrorNone) {
      fprintf(stderr, "Error on setting audio destination\nomx option must be set to hdmi or local\n");
      exit(1);
    }
  }

  // input port
  ilclient_enable_port_buffers(component, 100, NULL, NULL, NULL);
  ilclient_enable_port(component, 100);

  err = ilclient_change_component_state(component, OMX_StateExecuting);
  if (err < 0) {
  	fprintf(stderr, "Couldn't change state to Executing\n");
  	exit(1);
  }
}
示例#3
0
int main(int argc, char **argv)
{

    int i;
    char *decodeComponentName;
    char *renderComponentName;
    int err;
    ILCLIENT_T *handle;
    COMPONENT_T *decodeComponent;
    COMPONENT_T *renderComponent;
    COMPONENT_T *fxComponent;
    int do_deinterlace = 0;

    if (argc >= 2)
    {
        IMG = argv[1];
    }
    if (argc >= 3)
    {
        if (strcmp(argv[2],"d")==0)
            do_deinterlace = 1;
    }

    FILE *fp = fopen(IMG, "r");
    int toread = get_file_size(IMG);
    OMX_BUFFERHEADERTYPE *buff_header;

    decodeComponentName = "video_decode";
    renderComponentName = "video_render";

    bcm_host_init();

    handle = ilclient_init();
    if (handle == NULL)
    {
        fprintf(stderr, "IL client init failed\n");
        exit(1);
    }

    if (OMX_Init() != OMX_ErrorNone)
    {
        ilclient_destroy(handle);
        fprintf(stderr, "OMX init failed\n");
        exit(1);
    }

    ilclient_set_error_callback(handle,
                                error_callback,
                                NULL);
    ilclient_set_eos_callback(handle,
                              eos_callback,
                              NULL);

    setup_decodeComponent(handle, decodeComponentName, &decodeComponent);
    setup_renderComponent(handle, renderComponentName, &renderComponent);
    if (do_deinterlace)
        setup_fxComponent(handle, "image_fx", &fxComponent);
    // both components now in Idle state, no buffers, ports disabled

    // input port
    ilclient_enable_port_buffers(decodeComponent, 130,
                                 NULL, NULL, NULL);
    ilclient_enable_port(decodeComponent, 130);

    err = ilclient_change_component_state(decodeComponent,
                                          OMX_StateExecuting);
    if (err < 0)
    {
        fprintf(stderr, "Couldn't change state to Executing\n");
        exit(1);
    }
    printState(ilclient_get_handle(decodeComponent));

    // Read the first block so that the decodeComponent can get
    // the dimensions of the video and call port settings
    // changed on the output port to configure it
    while (toread > 0)
    {
        buff_header =
            ilclient_get_input_buffer(decodeComponent,
                                      130,
                                      1 /* block */);
        if (buff_header != NULL)
        {
            read_into_buffer_and_empty(fp,
                                       decodeComponent,
                                       buff_header,
                                       &toread);

            // If all the file has been read in, then
            // we have to re-read this first block.
            // Broadcom bug?
            if (toread <= 0)
            {
                printf("Rewinding\n");
                // wind back to start and repeat
                fp = freopen(IMG, "r", fp);
                toread = get_file_size(IMG);
            }
        }

        if (toread > 0 && ilclient_remove_event(decodeComponent, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0)
        {
            printf("Removed port settings event\n");
            break;
        }
        else
        {
            printf("No port setting seen yet\n");
        }
        // wait for first input block to set params for output port
        if (toread == 0)
        {
            // wait for first input block to set params for output port
            err = ilclient_wait_for_event(decodeComponent,
                                          OMX_EventPortSettingsChanged,
                                          131, 0, 0, 1,
                                          ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED,
                                          2000);
            if (err < 0)
            {
                fprintf(stderr, "No port settings change\n");
                //exit(1);
            }
            else
            {
                printf("Port settings changed\n");
                break;
            }
        }
    }

    // set the decode component to idle and disable its ports
    err = ilclient_change_component_state(decodeComponent,
                                          OMX_StateIdle);
    if (err < 0)
    {
        fprintf(stderr, "Couldn't change state to Idle\n");
        exit(1);
    }
    ilclient_disable_port(decodeComponent, 131);
    ilclient_disable_port_buffers(decodeComponent, 131,
                                  NULL, NULL, NULL);

    if (do_deinterlace)
    {
        // set up the tunnel between decode and fx ports
        err = OMX_SetupTunnel(ilclient_get_handle(decodeComponent),
                            131,
                            ilclient_get_handle(fxComponent),
                            190);
        if (err != OMX_ErrorNone)
        {
            fprintf(stderr, "Error setting up tunnel 1 %X\n", err);
            exit(1);
        }
        else
        {
            printf("Tunnel 1 set up ok\n");
        }

        // set up the tunnel between fx and render ports
        err = OMX_SetupTunnel(ilclient_get_handle(fxComponent),
                            191,
                            ilclient_get_handle(renderComponent),
                            90);
        if (err != OMX_ErrorNone)
        {
            fprintf(stderr, "Error setting up tunnel 2 %X\n", err);
            exit(1);
        }
        else
        {
            printf("Tunnel 2 set up ok\n");
        }
    }
    else
    {
        // set up the tunnel between decode and render ports
        err = OMX_SetupTunnel(ilclient_get_handle(decodeComponent),
                            131,
                            ilclient_get_handle(renderComponent),
                            90);
        if (err != OMX_ErrorNone)
        {
            fprintf(stderr, "Error setting up tunnel %X\n", err);
        exit(1);
        }
        else
        {
            printf("Tunnel set up ok\n");
        }
    }
    // Okay to go back to processing data
    // enable the decode output ports

//UNNECESSARY?? PGB    OMX_SendCommand(ilclient_get_handle(decodeComponent),
//UNNECESSARY?? PGB                    OMX_CommandPortEnable, 131, NULL);

    ilclient_enable_port(decodeComponent, 131);

    if (do_deinterlace)
    {
        setup_shared_buffer_format(decodeComponent, 131, fxComponent, 191);
        // enable fx ports
        ilclient_enable_port(fxComponent, 190);
        ilclient_enable_port(fxComponent, 191);

//UNNECESSARY?? PGB    OMX_SendCommand(ilclient_get_handle(renderComponent),
//UNNECESSARY?? PGB                    OMX_CommandPortEnable, 90, NULL);

        // setup_shared_buffer_format(fxComponent, renderComponent);
    }
    // enable the render output ports
    ilclient_enable_port(renderComponent, 90);

    // set all components to executing state
    err = ilclient_change_component_state(decodeComponent,
                                          OMX_StateExecuting);
    if (err < 0)
    {
        fprintf(stderr, "Couldn't change decode to Executing\n");
        exit(1);
    }
    if (do_deinterlace)
    {
        err = ilclient_change_component_state(fxComponent,
                                            OMX_StateExecuting);
        if (err < 0)
        {
            fprintf(stderr, "Couldn't change fx to Executing\n");
            exit(1);
        }
    }
    err = ilclient_change_component_state(renderComponent,
                                          OMX_StateExecuting);
    if (err < 0)
    {
        fprintf(stderr, "Couldn't change render to Executing\n");
        exit(1);
    }

    print_port_info(ilclient_get_handle(decodeComponent), 131);
    if (do_deinterlace)
    {
        print_port_info(ilclient_get_handle(fxComponent), 190);
        print_port_info(ilclient_get_handle(fxComponent), 191);
    }
    print_port_info(ilclient_get_handle(renderComponent), 90);

    // now work through the file
    while (toread > 0)
    {
        OMX_ERRORTYPE r;

        // do we have a decode input buffer we can fill and empty?
        buff_header =
            ilclient_get_input_buffer(decodeComponent,
                                      130,
                                      1 /* block */);
        if (buff_header != NULL)
        {
            read_into_buffer_and_empty(fp,
                                       decodeComponent,
                                       buff_header,
                                       &toread);
        }
        usleep(100000);
        // print_port_info(ilclient_get_handle(renderComponent), 90);
    }


    ilclient_wait_for_event(renderComponent,
                            OMX_EventBufferFlag,
                            90, 0, OMX_BUFFERFLAG_EOS, 0,
                            ILCLIENT_BUFFER_FLAG_EOS, 10000);
    printf("EOS on render\n");

    sleep(100);

    exit(0);
}
示例#4
0
static int image_decode_test(char *filename)
{

     OMX_BUFFERHEADERTYPE *pIbuf;
     int bytes_read;
     int status = 0, ret;
     int port_settings_changed = 0;

     OMX_IMAGE_PARAM_PORTFORMATTYPE imagePortFormat;
     COMPONENT_T *image_decode = NULL;
     COMPONENT_T *video_render = NULL;
     COMPONENT_T *list[3];
     TUNNEL_T tunnel[2];
     ILCLIENT_T *client;
     FILE *fin;

     memset(list, 0, sizeof(list));
     memset(tunnel, 0, sizeof(tunnel));

     if((fin = fopen(filename, "rb")) == NULL ) {
	  perror(filename);
	  return -1;
     }

     if((client = ilclient_init()) == NULL) {
	  return -3;
     }     

     if(OMX_Init() != OMX_ErrorNone) {
	  ilclient_destroy(client);
	  fclose(fin);
	  return -4;
     }

#if 0 //this was an attempt to use the image_read component
     COMPONENT_T *image_read;
     // create image_read
     if(ilclient_create_component(client, &image_read, "image_read",
				  ILCLIENT_DISABLE_ALL_PORTS ) != 0)
	  status = -14;


     //set URI
     OMX_PARAM_CONTENTURITYPE *pUri;
     sz = sizeof(pUri)+strlen(filename);
     pUri = (OMX_PARAM_CONTENTURITYPE*)calloc(1, sz);
     pUri->nSize = sz;
     pUri->nVersion.nVersion = OMX_VERSION;
     strcpy(pUri->contentURI, filename);
     if(image_read != NULL && OMX_SetParameter(ILC_GET_HANDLE(image_read), OMX_IndexParamContentURI, pUri) != 0)
	  status = -17;

     //enable port
     ilclient_enable_port(image_read, 310);

     //get OMX_IndexParamPortDefinition
     {
	  OMX_PARAM_PORTDEFINITIONTYPE portDef;
	  portDef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
	  portDef.nVersion.nVersion = OMX_VERSION;
	  portDef.nPortIndex = 310;
	  ret = OMX_GetParameter(ILC_GET_HANDLE(image_read), OMX_IndexParamPortDefinition, &portDef);
     }

     //get OMX_IndexParamImagePortFormat
     i=0;
     while(ret == 0) {
	  OMX_IMAGE_PARAM_PORTFORMATTYPE portFormat;
	  portFormat.nSize = sizeof(OMX_IMAGE_PARAM_PORTFORMATTYPE);
	  portFormat.nVersion.nVersion = OMX_VERSION;
	  portFormat.nPortIndex = 310;
	  portFormat.nIndex = i;
	  ret = OMX_GetParameter(ILC_GET_HANDLE(image_read), OMX_IndexParamImagePortFormat, &portFormat);
	  i++;
     }

     {
	  OMX_IMAGE_PARAM_PORTFORMATTYPE portFormat;
	  portFormat.nSize = sizeof(OMX_IMAGE_PARAM_PORTFORMATTYPE);
	  portFormat.nVersion.nVersion = OMX_VERSION;
	  portFormat.nPortIndex = 310;
	  portFormat.eCompressionFormat = OMX_IMAGE_CodingJPEG;

	  ret = OMX_SetParameter(ILC_GET_HANDLE(image_read), OMX_IndexParamImagePortFormat, &portFormat);
     }

     if((ret = ilclient_change_component_state(image_read, OMX_StateIdle) < 0)) //this fails
	  printf("Cannot change image_read component state to OMX_StateIdle\n"); 

#endif //image_read attempt


     // create image_decode
     ret = ilclient_create_component(client, &image_decode, "image_decode", 
				     ILCLIENT_DISABLE_ALL_PORTS | 
				     ILCLIENT_ENABLE_INPUT_BUFFERS );
     if (ret != 0)
	  status = -15;
     list[0] = image_decode;

     // create video_render
     ret = ilclient_create_component(client, &video_render, "video_render", 
				   ILCLIENT_DISABLE_ALL_PORTS);
     if (ret != 0)
	  status = -14;
     list[1] = video_render;
     list[2] = NULL;
     

     ret = ilclient_change_component_state(image_decode, OMX_StateIdle);

     set_tunnel(tunnel, image_decode, 321, video_render, 90);

#if 0 //not necessary
     {
	  //get OMX_IndexParamPortDefinition
	  OMX_PARAM_PORTDEFINITIONTYPE portDef;
	  portDef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
	  portDef.nVersion.nVersion = OMX_VERSION;
	  portDef.nPortIndex = 320;
	  ret = OMX_GetParameter(ILC_GET_HANDLE(image_decode), OMX_IndexParamPortDefinition, &portDef);
     }
#endif

     {
	  // OMX_IndexParamImagePortFormat
	  imagePortFormat.nSize = sizeof(OMX_IMAGE_PARAM_PORTFORMATTYPE);
	  imagePortFormat.nVersion.nVersion = OMX_VERSION;
	  imagePortFormat.nPortIndex = 320;
	  imagePortFormat.eCompressionFormat = OMX_IMAGE_CodingJPEG;
//	  imagePortFormat.eCompressionFormat = OMX_IMAGE_CodingPNG; //does not seem to work
//	  imagePortFormat.eCompressionFormat = OMX_IMAGE_CodingAutoDetect; //does not seem to work.

	  ret = OMX_SetParameter(ILC_GET_HANDLE(image_decode), OMX_IndexParamImagePortFormat, &imagePortFormat);
     }

     ret = ilclient_enable_port_buffers(image_decode, 320, NULL, NULL, NULL);

     ret = ilclient_change_component_state(image_decode, OMX_StateExecuting);

     while( (pIbuf = ilclient_get_input_buffer(image_decode, 320, 1)) != NULL ) {
	  bytes_read = fread(pIbuf->pBuffer, 1, pIbuf->nAllocLen, fin);

	  if( port_settings_changed == 0 &&
	      (( bytes_read > 0 && ilclient_remove_event(image_decode, OMX_EventPortSettingsChanged, 321, 0, 0, 1) == 0) ||
	       ( bytes_read == 0 && ilclient_wait_for_event(image_decode, OMX_EventPortSettingsChanged, 321, 0, 0, 1,
							    ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 10000) == 0)))
	  {
	       port_settings_changed = 1;

		    
	       if(ilclient_setup_tunnel(tunnel, 0, 0) != 0)
	       {
		    status = -7;
		    break;
	       }
		    
	       ilclient_change_component_state(video_render, OMX_StateExecuting);

	  }

	  if(!bytes_read)
	       break;
	       
	  pIbuf->nFilledLen = bytes_read;
	  pIbuf->nOffset = 0;
	  pIbuf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;

	  if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(image_decode), pIbuf) != OMX_ErrorNone)
	  {
	       status = -6;
	       break;
	  }
     }

     pIbuf->nFilledLen = 0;
     pIbuf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS;
      
     if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(image_decode), pIbuf) != OMX_ErrorNone)
	  status = -20;
      

     // wait for EOS from render
     ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0,
			     ILCLIENT_BUFFER_FLAG_EOS, 10000);
      

     printf("Press ENTER to continue...\n");
     fflush(stdout);
     getchar();

     
     // need to flush the renderer to allow video_decode to disable its input port
//     ilclient_flush_tunnels(tunnel, 0);

     ilclient_disable_port_buffers(image_decode, 320, NULL, NULL, NULL);

     fclose(fin);

     ilclient_disable_tunnel(tunnel);
     ilclient_teardown_tunnels(tunnel);

      
     ret = ilclient_change_component_state(image_decode, OMX_StateIdle);
     ret = ilclient_change_component_state(image_decode, OMX_StateLoaded);
     
     ilclient_cleanup_components(list);
     OMX_Deinit();
     ilclient_destroy(client);
     return status;
}
示例#5
0
void *initServerRcam(void *VoidPtrArgs)
{
  struct cameraControl *currentArgs = VoidPtrArgs;

  pthread_mutex_lock(&currentArgs->mutexPtr);
  ILCLIENT_T *client = currentArgs->client;
  pthread_mutex_unlock(&currentArgs->mutexPtr);

  ///////////////////////////////////////////
  // Variables

  COMPONENT_T *client_video_render = NULL;
  OMX_ERRORTYPE OMXstatus;

  OMX_BUFFERHEADERTYPE *client_video_render_in;

  OMX_PARAM_PORTDEFINITIONTYPE render_params;
  memset(&render_params, 0, sizeof(render_params));
  render_params.nVersion.nVersion = OMX_VERSION;
  render_params.nSize = sizeof(render_params);
  render_params.nPortIndex = 90;

  enum rcam_command rcam_command = NO_COMMAND;


  ///////////////////////////////////////////
  ////Initialise client video render

  pthread_mutex_lock(&currentArgs->mutexPtr);

  ilclient_create_component(client,
			    &client_video_render,
			    "video_render",
			    ILCLIENT_DISABLE_ALL_PORTS
			    | ILCLIENT_ENABLE_INPUT_BUFFERS);

  OMXstatus = ilclient_change_component_state(client_video_render, OMX_StateIdle);
  if (OMXstatus != OMX_ErrorNone)
    {
      fprintf(stderr, "unable to move render component to Idle (1)\n");
      exit(EXIT_FAILURE);
    }

  //set the port params to the same as remoteCam.c
  // !!!
  // needs the checks that the local camera does
  // to ensure sanity as only particular values excepted (OR DOES IT ALREADY DO THIS ? IT MIGHT BE)

  OMXstatus = OMX_GetConfig(ilclient_get_handle(client_video_render), OMX_IndexParamPortDefinition, &render_params);
  if (OMXstatus != OMX_ErrorNone)
    printf("Error Getting video render port parameters (1)");

  render_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
  render_params.format.video.nFrameWidth = currentArgs->previewWidth;
  render_params.format.video.nFrameHeight = currentArgs->previewHeight;
  render_params.format.video.nStride = currentArgs->previewWidth;
  render_params.format.video.nSliceHeight = currentArgs->previewHeight;
  render_params.format.video.xFramerate = currentArgs->previewFramerate << 16;

  OMXstatus = OMX_SetConfig(ilclient_get_handle(client_video_render), OMX_IndexParamPortDefinition, &render_params);
  if (OMXstatus != OMX_ErrorNone)
    printf("Error Setting video render port parameters (1)");

  //check(print) the port params
  memset(&render_params, 0, sizeof(render_params));
  render_params.nVersion.nVersion = OMX_VERSION;
  render_params.nSize = sizeof(render_params);
  render_params.nPortIndex = 90;

  OMXstatus = OMX_GetConfig(ilclient_get_handle(client_video_render), OMX_IndexParamPortDefinition, &render_params);
  if (OMXstatus != OMX_ErrorNone)
    printf("Error Getting video render port parameters (1)");

  print_OMX_PARAM_PORTDEFINITIONTYPE(render_params);


  //ask ilclient to allocate buffers for client_video_render

  //printf("enable client_video_render_input port\n");
  ilclient_enable_port_buffers(client_video_render, 90, NULL, NULL,  NULL);
  ilclient_enable_port(client_video_render, 90);

  //change preview render to executing
  OMXstatus = ilclient_change_component_state(client_video_render, OMX_StateExecuting);
  if (OMXstatus != OMX_ErrorNone)
    {
      fprintf(stderr, "unable to move video render component to Executing (1)\n");
      exit(EXIT_FAILURE);
    }
  printf("client_video_render state is ");
  printState(ilclient_get_handle(client_video_render));
  printf("***\n");

  //set the position on the screen
  setRenderConfig(client_video_render, currentArgs->displayType);

  /////////////////////////////////////////////////////////////////
  // SOCKET STUFF

  printf("start of socket stuff in rcam\n");

  int socket_fd = 0, client_socket_fd = 0;

  socket_fd = getAndBindTCPServerSocket(PORT);
  printf("waiting for remotecam to connect\n");
  client_socket_fd = listenAndAcceptTCPServerSocket(socket_fd, 10/*backlog*/);

  
  ////////////////////////////////////////////////////////////
  // INITIATE RCAM_REMOTE_SLAVE

  char char_buffer[12];

  //handshake
  printf("waiting to recive handshake ... \n");
  read(client_socket_fd, char_buffer, 11);
  printf("handshake result = %s", char_buffer);

  write(client_socket_fd, "got\0", sizeof(char)*4);
  //initalize preview
  write(client_socket_fd, &currentArgs->previewWidth, sizeof(currentArgs->previewWidth));
  write(client_socket_fd, &currentArgs->previewHeight, sizeof(currentArgs->previewHeight));
  write(client_socket_fd, &currentArgs->previewFramerate, sizeof(currentArgs->previewFramerate));
  //initalize capture
  write(client_socket_fd, &currentArgs->photoWidth, sizeof(currentArgs->photoWidth));
  write(client_socket_fd, &currentArgs->photoHeight, sizeof(currentArgs->photoHeight));

  pthread_mutex_unlock(&currentArgs->mutexPtr);

  ////////////////////////////////////////////////////////////
  //// Main Thread Loop

  void * preview_buffer;
  preview_buffer = malloc(render_params.nBufferSize + 1 );
  printf("***preview nBufferSize = %d\n", render_params.nBufferSize);

  int photo_buffer_size;
  void * photo_buffer;
  //photo_buffer = malloc();
  
  long int num_bytes = 0;

  enum rcam_command current_command = START_PREVIEW;
  printf("current_command = %d\n", current_command);
  printf("sending command ...");
  write(client_socket_fd, &current_command, sizeof(current_command));
  printf("sent command\n");

  current_command = NO_COMMAND;
	  // possibly abandon current command struct
	  // and serialize the cameraControlStruct and sent that instead
	  // see: http://stackoverflow.com/questions/1577161/passing-a-structure-through-sockets-in-c


  int count = 500;
  while(1)
    {
      pthread_mutex_lock(&currentArgs->mutexPtr);

      if (currentArgs->previewChanged == true)
	{
	  printf("In previewChanged\n");
	  //needs to:
	  //change the renderer params this side
	  OMXstatus = ilclient_change_component_state(client_video_render, OMX_StateIdle);

	  memset(&render_params, 0, sizeof(render_params));
	  render_params.nVersion.nVersion = OMX_VERSION;
	  render_params.nSize = sizeof(render_params);
	  render_params.nPortIndex = 90;

	  OMXstatus = OMX_GetConfig(ilclient_get_handle(client_video_render),
				    OMX_IndexParamPortDefinition,
				    &render_params);
	  if (OMXstatus != OMX_ErrorNone)
	    printf("Error Getting video render port parameters (in loop)");

	  render_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
	  render_params.format.video.nFrameWidth = currentArgs->previewWidth;
	  render_params.format.video.nFrameHeight = currentArgs->previewHeight;
	  render_params.format.video.nStride = currentArgs->previewWidth;
	  render_params.format.video.nSliceHeight = currentArgs->previewHeight;
	  render_params.format.video.xFramerate = currentArgs->previewFramerate << 16;

	  OMXstatus = OMX_SetConfig(ilclient_get_handle(client_video_render),
				    OMX_IndexParamPortDefinition,
				    &render_params);
	  if (OMXstatus != OMX_ErrorNone)
	    printf("Error Setting video render port parameters (in loop)");

	  OMXstatus = ilclient_change_component_state(client_video_render, OMX_StateExecuting);

	  //resize the preview buffer

	  memset(&render_params, 0, sizeof(render_params));
	  render_params.nVersion.nVersion = OMX_VERSION;
	  render_params.nSize = sizeof(render_params);
	  render_params.nPortIndex = 90;

	  OMXstatus = OMX_GetConfig(ilclient_get_handle(client_video_render),
				    OMX_IndexParamPortDefinition,
				    &render_params);
	  if (OMXstatus != OMX_ErrorNone)
	    printf("Error Getting video render port parameters (in loop)");

	  free(preview_buffer);
	  preview_buffer = malloc(render_params.nBufferSize + 1);

	  //change the preview on the remote side
	  current_command = SET_PREVIEW_RES;
	  write(client_socket_fd, &current_command, sizeof(current_command));
	  //send needed paramaters to rcam_remote_slave for the preview change
	  write(client_socket_fd, &currentArgs->previewWidth, sizeof(currentArgs->previewWidth));
	  write(client_socket_fd, &currentArgs->previewHeight, sizeof(currentArgs->previewHeight));
	  write(client_socket_fd, &currentArgs->previewFramerate, sizeof(currentArgs->previewFramerate));
	  //!!!
	  //possibly wait for confirmation
	  currentArgs->previewChanged = false;
	  sleep(1);
	}
      else if (currentArgs->photoChanged == true)
	{
	  printf("in photoChanged !\n");
	  //needs to:
	  //change the capture res on the remote side
	  current_command = SET_CAPTURE_RES;
	  write(client_socket_fd, &current_command, sizeof(current_command));
	  //send needed paramaters to rcam_remote_slave for the photo change
	  write(client_socket_fd, &currentArgs->previewWidth, sizeof(currentArgs->previewWidth));
	  write(client_socket_fd, &currentArgs->previewHeight, sizeof(currentArgs->previewHeight));
	  //change the photo_buffer??
	  read(client_socket_fd, &photo_buffer_size, sizeof(photo_buffer_size));
	  free(photo_buffer);
	  photo_buffer = malloc(photo_buffer_size + 1);
	  //!!!
	  //possibly wait for confirmation
	  currentArgs->photoChanged = false;
	}
      else if (currentArgs->displayChanged == true)
	{
	  printf("in displayChanged !\n");
	  setRenderConfig(client_video_render, currentArgs->displayType);
	  currentArgs->displayChanged = false;
	}
      else if (currentArgs->takePhoto == true)
	{
	  printf("in takePhoto !\n");
	  //needs to:
	  //send command and then recive the capture
	  current_command = TAKE_PHOTO;
	  write(client_socket_fd, &current_command, sizeof(current_command));	  
	  currentArgs->takePhoto = false;
	  printf("end of take photo\n");
	}
      //loop terminationcurrent_command = TAKE_PHOTO;
      else if(currentArgs->rcamDeInit)
	{
	  printf("in rcamDiInit !\n");
	  current_command = END_REMOTE_CAM;
	  write(client_socket_fd, &current_command, sizeof(current_command));
  	  printf("END_REMOTE_CAM sent\n");
	  break; //exits loop and ultimatly ends this pthread
	}
      else
	{
	  printf("no commands in struct to parse !\n");
	  //send no command
	  current_command = NO_COMMAND;
	  write(client_socket_fd, &current_command, sizeof(current_command));

	  //printf("get a buffer to process\n");
	  //printf("waiting to recv buffer of size %d... ", render_params.nBufferSize);
	  num_bytes = read(client_socket_fd,
			   preview_buffer,
			   render_params.nBufferSize);
	  while (num_bytes < render_params.nBufferSize)
	    {
	      num_bytes += read(client_socket_fd,
				preview_buffer + num_bytes,
				render_params.nBufferSize - num_bytes);
	    }
	  //printf("buffer recived, recived %ld bytes\n", num_bytes);

	  //change nAllocLen in bufferheader
	  client_video_render_in = ilclient_get_input_buffer(client_video_render, 90, 1);
	  memcpy(client_video_render_in->pBuffer, preview_buffer, render_params.nBufferSize);
	  //printf("copied buffer form preview_buffer into client_video_render_in\n");
	  client_video_render_in->nFilledLen = render_params.nBufferSize;

	  //empty buffer into render component
	  OMX_EmptyThisBuffer(ilclient_get_handle(client_video_render), client_video_render_in);
	  count++;
	  //printf("Emptied buffer --- count = %d\n", count);
	}
      pthread_mutex_unlock(&currentArgs->mutexPtr);
      usleep(500);
    }

  ////////////////////////////////////////////////////////////
  //// end of thread, Cleanup

  //free buffer memory
  free(preview_buffer);
  printf("preview_buffer memory free\n");
  //!free ilobjects and make sure all allocated memory is free!

  //!free sockets try to ensure no zombies
  printf("exiting rcam thread");
  pthread_exit(NULL);
}
示例#6
0
void *initLocalCamera(void *VoidPtrArgs)
{
  struct cameraControl *currentArgs = VoidPtrArgs;

  pthread_mutex_lock(&currentArgs->mutexPtr);
  ILCLIENT_T *client = currentArgs->client;
  pthread_mutex_unlock(&currentArgs->mutexPtr);

  //////////////////
  //VARIABLES

  COMPONENT_T *camera = NULL, *video_render = NULL, *image_encode = NULL;
  COMPONENT_T *component_list[3] = {camera, video_render, image_encode};
  COMPONENT_T *image_encode_list[1] = {image_encode}; //needed to destroy component?
  OMX_ERRORTYPE OMXstatus;

  TUNNEL_T tunnel_camera_to_render, tunnel_camera_to_encode;
  memset(&tunnel_camera_to_render, 0, sizeof(tunnel_camera_to_render));
  memset(&tunnel_camera_to_encode, 0, sizeof(tunnel_camera_to_encode));

  //////////////////
  // STARTUP

  //////////////////
  // Initalize Components

  //////////////////
  ////initialise camera

  ilclient_create_component(client,
			    &camera,
			    "camera",
			    ILCLIENT_DISABLE_ALL_PORTS);

  OMXstatus = ilclient_change_component_state(camera, OMX_StateIdle);
  if (OMXstatus != OMX_ErrorNone)
    {
      fprintf(stderr, "unable to move camera component to Idle (1)");
      exit(EXIT_FAILURE);
    }

  //change the capture resolution
  setCaptureRes(camera, currentArgs->photoWidth, currentArgs->photoHeight);

  //change the preview resolution
  setPreviewRes(camera, currentArgs->previewWidth, currentArgs->previewHeight, currentArgs->previewFramerate);

  //////////////////
  ////Initialise video render
  
  ilclient_create_component(client,
			    &video_render,
			    "video_render",
			    ILCLIENT_DISABLE_ALL_PORTS
			    );

  OMXstatus = ilclient_change_component_state(video_render, OMX_StateIdle);
  if (OMXstatus != OMX_ErrorNone)
    {
      fprintf(stderr, "unable to move render component to Idle (1)\n");
      exit(EXIT_FAILURE);
    }

  setRenderConfig(video_render, currentArgs->displayType);

  ////////////////////
  ////Initalise Image Encoder

  ilclient_create_component(client,
			    &image_encode,
			    "image_encode",
			    ILCLIENT_DISABLE_ALL_PORTS
			    /*| ILCLIENT_ENABLE_INPUT_BUFFERS*/
			    | ILCLIENT_ENABLE_OUTPUT_BUFFERS);

  OMXstatus = ilclient_change_component_state(image_encode, OMX_StateIdle);
  if (OMXstatus != OMX_ErrorNone)
    {
      fprintf(stderr, "unable to move image encode component to Idle (1)\n");
      exit(EXIT_FAILURE);
    }

  //image format Param set
  setParamImageFormat(image_encode, JPEG_HIGH_FORMAT);

  ////////////////////
  // enable components and tunnels

  //setup tunnel of camera preview to renderer
  set_tunnel(&tunnel_camera_to_render, camera, 70, video_render, 90);
  ilclient_setup_tunnel(&tunnel_camera_to_render, 0, 0);

  // change camera component to executing
  OMXstatus = ilclient_change_component_state(camera, OMX_StateExecuting);
  if (OMXstatus != OMX_ErrorNone)
    {
      fprintf(stderr, "unable to move camera component to Executing (1)\n");
      exit(EXIT_FAILURE);
    }

  //change preview render to executing
  OMXstatus = ilclient_change_component_state(video_render, OMX_StateExecuting);
  if (OMXstatus != OMX_ErrorNone)
    {
      fprintf(stderr, "unable to move video render component to Executing (1)\n");
      exit(EXIT_FAILURE);
    }

  //enable port and buffers for output port of image encode
  ilclient_enable_port_buffers(image_encode, 341, NULL, NULL, NULL);
  ilclient_enable_port(image_encode, 341);
  
  //setup tunnel from camera image port too image encode
  set_tunnel(&tunnel_camera_to_encode, camera, 72, image_encode, 340);
  ilclient_setup_tunnel(&tunnel_camera_to_encode, 0, 0);

  //change image_encode to executing
  OMXstatus = ilclient_change_component_state(image_encode, OMX_StateExecuting);
  if (OMXstatus != OMX_ErrorNone)
    {
      fprintf(stderr, "unable to move image_encode component to Executing (1) Error = %s\n", err2str(OMXstatus));
      exit(EXIT_FAILURE);
    }

  /////////////////
  // Main initLocalCamera() Loop

  while(1)
    {
      pthread_mutex_lock(&currentArgs->mutexPtr);
      if (currentArgs->previewChanged == true)
	{
	  //working
	  ilclient_disable_tunnel(&tunnel_camera_to_render);
	  OMXstatus = ilclient_change_component_state(camera, OMX_StatePause);
	  setPreviewRes(camera,
			currentArgs->previewWidth,
			currentArgs->previewHeight,
			currentArgs->previewFramerate);
	  OMXstatus = ilclient_change_component_state(camera, OMX_StateExecuting);
  	  ilclient_enable_tunnel(&tunnel_camera_to_render);
	  currentArgs->previewChanged = false;
	}
      else if (currentArgs->photoChanged == true)
	{
	  //NOT WORKING? CANT GET WORKING!!
	  //TUNNEL_T *tunnel_ptr = &tunnel_camera_to_encode;
	  ilclient_disable_tunnel(&tunnel_camera_to_encode);
	  ilclient_flush_tunnels(&tunnel_camera_to_encode, 30);
	  //ilclient_teardown_tunnels(&tunnel_camera_to_encode);
	  //printf("teardown done");
	  setCaptureRes(camera, currentArgs->photoWidth, currentArgs->photoHeight);
	  // DESTROY image encode and recreate (appears to be the only way)
	  //destory
	  
	  OMXstatus = ilclient_change_component_state(image_encode, OMX_StateIdle);
	  OMXstatus = ilclient_change_component_state(image_encode, OMX_StateLoaded);
	  //OMX_FreeHandle(ilclient_get_handle(image_encode));
	  ilclient_cleanup_components(image_encode_list);
	  printf("managed to free the image_encode handle");
	  image_encode = NULL;
	  
	  //recreate
	  ilclient_create_component(client,
				    &image_encode,
				    "image_encode",
				    ILCLIENT_DISABLE_ALL_PORTS
				    /*| ILCLIENT_ENABLE_INPUT_BUFFERS*/
				    | ILCLIENT_ENABLE_OUTPUT_BUFFERS);

	  OMXstatus = ilclient_change_component_state(image_encode, OMX_StateIdle);
	  if (OMXstatus != OMX_ErrorNone)
	    {
	      fprintf(stderr, "unable to move image encode component to Idle (1)\n");
	      exit(EXIT_FAILURE);
	    }

	  //image format Param set
	  setParamImageFormat(image_encode, JPEG_HIGH_FORMAT);

	  //OMXstatus = ilclient_change_component_state(camera, OMX_StateExecuting);
	  ilclient_enable_tunnel(&tunnel_camera_to_encode);
	  	  
	  currentArgs->photoChanged = false;
	}
      else if (currentArgs->displayChanged == true)
	{
	  //working
	  setRenderConfig(video_render, currentArgs->displayType);
	  currentArgs->displayChanged = false;
	}
      else if (currentArgs->takePhoto == true)
	{
	  //working
	  savePhoto(camera, image_encode, "/home/pi/Desktop/photo_", "_L.jpg");	  
	  currentArgs->takePhoto = false;
	}
      //loop termination
      else if (currentArgs->rcamDeInit == true)
	{
	  //working
	  printf("~~~~~ End local camera ~~~~~\n");
	  break;
	}
      pthread_mutex_unlock(&currentArgs->mutexPtr);
      usleep(500);
    }

  ///////////////
  //CLEANUP

  // Teardown tunnels
  ilclient_disable_tunnel(&tunnel_camera_to_render);
  ilclient_disable_tunnel(&tunnel_camera_to_encode);
  
  ilclient_teardown_tunnels(&tunnel_camera_to_render);
  ilclient_teardown_tunnels(&tunnel_camera_to_encode);
  
  // Disable components
  ilclient_cleanup_components(component_list);


  //Destroy ilclient
  // dont do for local as its done in main program
  //ilclient_destroy(currentArgs->client)
  
  //unlock mutex before teminating
  pthread_mutex_unlock(&currentArgs->mutexPtr);
    
  //call pthread_exit so caller can join
  pthread_exit(NULL);
}