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; }
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); } }
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); }
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; }
void *initServerRcam(void *VoidPtrArgs) { struct cameraControl *currentArgs = VoidPtrArgs; pthread_mutex_lock(¤tArgs->mutexPtr); ILCLIENT_T *client = currentArgs->client; pthread_mutex_unlock(¤tArgs->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(¤tArgs->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, ¤tArgs->previewWidth, sizeof(currentArgs->previewWidth)); write(client_socket_fd, ¤tArgs->previewHeight, sizeof(currentArgs->previewHeight)); write(client_socket_fd, ¤tArgs->previewFramerate, sizeof(currentArgs->previewFramerate)); //initalize capture write(client_socket_fd, ¤tArgs->photoWidth, sizeof(currentArgs->photoWidth)); write(client_socket_fd, ¤tArgs->photoHeight, sizeof(currentArgs->photoHeight)); pthread_mutex_unlock(¤tArgs->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, ¤t_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(¤tArgs->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, ¤t_command, sizeof(current_command)); //send needed paramaters to rcam_remote_slave for the preview change write(client_socket_fd, ¤tArgs->previewWidth, sizeof(currentArgs->previewWidth)); write(client_socket_fd, ¤tArgs->previewHeight, sizeof(currentArgs->previewHeight)); write(client_socket_fd, ¤tArgs->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, ¤t_command, sizeof(current_command)); //send needed paramaters to rcam_remote_slave for the photo change write(client_socket_fd, ¤tArgs->previewWidth, sizeof(currentArgs->previewWidth)); write(client_socket_fd, ¤tArgs->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, ¤t_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, ¤t_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, ¤t_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(¤tArgs->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); }
void *initLocalCamera(void *VoidPtrArgs) { struct cameraControl *currentArgs = VoidPtrArgs; pthread_mutex_lock(¤tArgs->mutexPtr); ILCLIENT_T *client = currentArgs->client; pthread_mutex_unlock(¤tArgs->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(¤tArgs->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(¤tArgs->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(¤tArgs->mutexPtr); //call pthread_exit so caller can join pthread_exit(NULL); }