void setup_renderComponent(ILCLIENT_T *handle, char *renderComponentName, COMPONENT_T **renderComponent) { int err; err = ilclient_create_component(handle, renderComponent, renderComponentName, ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS); if (err == -1) { fprintf(stderr, "RenderComponent create failed\n"); exit(1); } printState(ilclient_get_handle(*renderComponent)); err = ilclient_change_component_state(*renderComponent, OMX_StateIdle); if (err < 0) { fprintf(stderr, "Couldn't change state to Idle\n"); exit(1); } printState(ilclient_get_handle(*renderComponent)); }
void setup_fxComponent(ILCLIENT_T *handle, char *fxComponentName, COMPONENT_T **fxComponent) { int err; err = ilclient_create_component(handle, fxComponent, fxComponentName, ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS | ILCLIENT_ENABLE_OUTPUT_BUFFERS); if (err == -1) { fprintf(stderr, "fxComponent create failed\n"); exit(1); } printState(ilclient_get_handle(*fxComponent)); err = ilclient_change_component_state(*fxComponent, OMX_StateIdle); if (err < 0) { fprintf(stderr, "Couldn't change state to Idle\n"); exit(1); } printState(ilclient_get_handle(*fxComponent)); // must be before we enable buffers setup_deinterlace(*fxComponent); }
void setup_shared_buffer_format(COMPONENT_T *decodeComponent, int decodePort, COMPONENT_T *renderComponent, int renderPort) { OMX_PARAM_PORTDEFINITIONTYPE portdef, rportdef; ; int ret; OMX_ERRORTYPE err; // 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 = decodePort; OMX_GetParameter(ilclient_get_handle(decodeComponent), OMX_IndexParamPortDefinition, &portdef); // Get default values of render rportdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); rportdef.nVersion.nVersion = OMX_VERSION; rportdef.nPortIndex = renderPort; // rportdef.nBufferSize = portdef.nBufferSize; // nBufferSize = portdef.nBufferSize; err = OMX_GetParameter(ilclient_get_handle(renderComponent), OMX_IndexParamPortDefinition, &rportdef); if (err != OMX_ErrorNone) { fprintf(stderr, "Error getting render port params %s\n", err2str(err)); exit(1); } // tell render input what the decoder output will be providing //Copy some rportdef.format.video.nFrameWidth = portdef.format.image.nFrameWidth; rportdef.format.video.nFrameHeight = portdef.format.image.nFrameHeight; rportdef.format.video.nStride = portdef.format.image.nStride; rportdef.format.video.nSliceHeight = portdef.format.image.nSliceHeight; err = OMX_SetParameter(ilclient_get_handle(renderComponent), OMX_IndexParamPortDefinition, &rportdef); if (err != OMX_ErrorNone) { fprintf(stderr, "Error setting render port params %s\n", err2str(err)); exit(1); } else { printf("Render port params set up ok\n"); } }
static void set_video_decoder_input_format(COMPONENT_T *component) { int err; // set input video format printf("Setting video decoder format\n"); OMX_VIDEO_PARAM_PORTFORMATTYPE videoPortFormat; //setHeader(&videoPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); memset(&videoPortFormat, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); videoPortFormat.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); videoPortFormat.nVersion.nVersion = OMX_VERSION; videoPortFormat.nPortIndex = 130; videoPortFormat.eCompressionFormat = OMX_VIDEO_CodingMPEG2; // videoPortFormat.eCompressionFormat = OMX_VIDEO_CodingAVC; err = OMX_SetParameter(ilclient_get_handle(component), OMX_IndexParamVideoPortFormat, &videoPortFormat); if (err != OMX_ErrorNone) { fprintf(stderr, "Error setting video decoder format %s\n", err2str(err)); return; // err; } else { printf("Video decoder format set up ok\n"); } }
OMX_ERRORTYPE read_into_buffer_and_empty(FILE *fp, COMPONENT_T *component, OMX_BUFFERHEADERTYPE *buff_header, int *toread) { OMX_ERRORTYPE r; int buff_size = buff_header->nAllocLen; int nread = fread(buff_header->pBuffer, 1, buff_size, fp); buff_header->nFilledLen = nread; *toread -= nread; printf("Read %d, %d still left\n", nread, *toread); if (*toread <= 0) { printf("Setting EOS on input\n"); buff_header->nFlags |= OMX_BUFFERFLAG_EOS; } r = OMX_EmptyThisBuffer(ilclient_get_handle(component), buff_header); if (r != OMX_ErrorNone) { fprintf(stderr, "Empty buffer error %s\n", err2str(r)); } return r; }
void setParamImageFormat(COMPONENT_T *image_encode, enum formatType formatType) { printf("in setParamImageFormat\n"); OMX_ERRORTYPE OMXstatus; //image format stucture */ OMX_IMAGE_PARAM_PORTFORMATTYPE image_format; memset(&image_format, 0, sizeof(image_format)); image_format.nVersion.nVersion = OMX_VERSION; image_format.nSize = sizeof(image_format); image_format.nPortIndex = 341; if(formatType == JPEG_HIGH_FORMAT || formatType == JPEG_MEDIUM_FORMAT || formatType == JPEG_LOW_FORMAT) { image_format.eCompressionFormat = OMX_IMAGE_CodingJPEG; OMX_IMAGE_PARAM_QFACTORTYPE compression_format; memset(&compression_format, 0, sizeof(compression_format)); compression_format.nVersion.nVersion = OMX_VERSION; compression_format.nSize = sizeof(compression_format); compression_format.nPortIndex = 341; if(formatType == JPEG_HIGH_FORMAT) compression_format.nQFactor = 100; else if (formatType == JPEG_MEDIUM_FORMAT) compression_format.nQFactor = 60; else if (formatType == JPEG_LOW_FORMAT) compression_format.nQFactor = 10; OMXstatus = OMX_SetParameter(ilclient_get_handle(image_encode), OMX_IndexParamQFactor, &compression_format); if(OMXstatus != OMX_ErrorNone) printf("Error Setting Paramter Error = %s\n", err2str(OMXstatus)); } OMXstatus = OMX_SetParameter(ilclient_get_handle(image_encode), OMX_IndexParamImagePortFormat, &image_format); if(OMXstatus != OMX_ErrorNone) printf("Error Setting Paramter Error = %s\n", err2str(OMXstatus)); // print the resultant format OMXstatus = OMX_GetParameter(ilclient_get_handle(image_encode), OMX_IndexParamImagePortFormat, &image_format); if(OMXstatus != OMX_ErrorNone) printf("Error Getting Paramter Error = %s\n", err2str(OMXstatus)); print_OMX_IMAGE_PARAM_PORTFORMATTYPE(image_format); }
void my_fill_buffer_done(void* data, COMPONENT_T* comp) { if (OMX_FillThisBuffer(ilclient_get_handle(video_render), eglBuffer) != OMX_ErrorNone) { printf("OMX_FillThisBuffer failed in callback\n"); exit(1); } }
//sets the capture resolution of the camera (any camera) void setCaptureRes2(COMPONENT_T *camera, int width, int height) { //needs to check width and height to see if compatible with rpi printf("in setCapture\n"); OMX_PARAM_PORTDEFINITIONTYPE port_params; OMX_ERRORTYPE OMXstatus; memset(&port_params, 0, sizeof(port_params)); port_params.nVersion.nVersion = OMX_VERSION; port_params.nSize = sizeof(port_params); port_params.nPortIndex = 341; OMXstatus = OMX_GetParameter(ilclient_get_handle(camera), OMX_IndexParamPortDefinition, &port_params); if(OMXstatus != OMX_ErrorNone) printf("Error Getting Parameter In setCaptureRes. Error = %s\n", err2str(OMXstatus)); //change needed params //port_params.nBufferCountActual = 1; //port_params.nBufferCountMin = 1; port_params.format.image.nFrameWidth = width; port_params.format.image.nFrameHeight = height; port_params.format.image.nStride = 0; //width + (width % 16); //needed! set to 0 to recalculate port_params.format.image.nSliceHeight = 0; // height + (height % 16); //notneeded? port_params.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar; //set changes OMXstatus = OMX_SetParameter(ilclient_get_handle(camera), OMX_IndexParamPortDefinition, &port_params); if(OMXstatus != OMX_ErrorNone) printf("Error Setting Parameter In setCaptureRes. Error = %s\n", err2str(OMXstatus)); //print current config memset(&port_params, 0, sizeof(port_params)); port_params.nVersion.nVersion = OMX_VERSION; port_params.nSize = sizeof(port_params); port_params.nPortIndex = 341; OMXstatus = OMX_GetConfig(ilclient_get_handle(camera), OMX_IndexParamPortDefinition, &port_params); if (OMXstatus != OMX_ErrorNone) printf("Error Getting Parameter (2) In setCaptureRes. Error = %s\n", err2str(OMXstatus)); print_OMX_PARAM_PORTDEFINITIONTYPE(port_params); }
//sets the preview res of the camera void setPreviewRes(COMPONENT_T *camera, int width, int height, int framerate) { //needs to check width and height to see if compatible with rpi printf("in setPreviewRes\n"); OMX_PARAM_PORTDEFINITIONTYPE port_params; OMX_ERRORTYPE OMXstatus; memset(&port_params, 0, sizeof(port_params)); port_params.nVersion.nVersion = OMX_VERSION; port_params.nSize = sizeof(port_params); port_params.nPortIndex = 70; //prepopulate structure OMXstatus = OMX_GetConfig(ilclient_get_handle(camera), OMX_IndexParamPortDefinition, &port_params); if (OMXstatus != OMX_ErrorNone) printf("Error Getting Parameter In setPreviewRes. Error = %s\n", err2str(OMXstatus)); //change needed params port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar; port_params.format.video.nFrameWidth = width; port_params.format.video.nFrameHeight = height; port_params.format.video.nStride = width; port_params.format.video.nSliceHeight = height; port_params.format.video.xFramerate = framerate << 16; //set changes OMXstatus = OMX_SetConfig(ilclient_get_handle(camera), OMX_IndexParamPortDefinition, &port_params); if (OMXstatus != OMX_ErrorNone) printf("Error Setting Parameter In setPreviewRes. Error = %s\n", err2str(OMXstatus)); //print current config memset(&port_params, 0, sizeof(port_params)); port_params.nVersion.nVersion = OMX_VERSION; port_params.nSize = sizeof(port_params); port_params.nPortIndex = 70; OMXstatus = OMX_GetConfig(ilclient_get_handle(camera), OMX_IndexParamPortDefinition, &port_params); if (OMXstatus != OMX_ErrorNone) printf("Error Getting Parameter (2) In setPreviewRes. Error = %s\n", err2str(OMXstatus)); print_OMX_PARAM_PORTDEFINITIONTYPE(port_params); }
static void setup_deinterlace(COMPONENT_T *component) { int err; // add extra buffers for Advanced Deinterlace printf("Setting deinterlace\n"); OMX_PARAM_U32TYPE extra_buffers; memset(&extra_buffers, 0, sizeof(OMX_PARAM_U32TYPE)); extra_buffers.nSize = sizeof(OMX_PARAM_U32TYPE); extra_buffers.nVersion.nVersion = OMX_VERSION; extra_buffers.nU32 = 3; err = OMX_SetParameter(ilclient_get_handle(component), OMX_IndexParamBrcmExtraBuffers, &extra_buffers); OMX_CONFIG_IMAGEFILTERPARAMSTYPE image_filter; memset(&image_filter, 0, sizeof(OMX_CONFIG_IMAGEFILTERPARAMSTYPE)); image_filter.nSize = sizeof(OMX_CONFIG_IMAGEFILTERPARAMSTYPE); image_filter.nVersion.nVersion = OMX_VERSION; image_filter.nPortIndex = 191; image_filter.nNumParams = 1; image_filter.nParams[0] = 3; image_filter.eImageFilter = OMX_ImageFilterDeInterlaceAdvanced; if (err == OMX_ErrorNone) err = OMX_SetConfig(ilclient_get_handle(component), OMX_IndexConfigCommonImageFilterParameters, &image_filter); if (err != OMX_ErrorNone) { fprintf(stderr, "Error setting deinterlace %s\n", err2str(err)); return; // err; } else { printf("Deinterlace set up ok\n"); } }
static void omx_renderer_decode_and_play_sample(char* data, int length) { int decodeLen = opus_multistream_decode(decoder, data, length, pcmBuffer, FRAME_SIZE, 0); if (decodeLen > 0) { buf = ilclient_get_input_buffer(component, 100, 1); buf->nOffset = 0; buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; int bufLength = decodeLen * sizeof(short) * channelCount; memcpy(buf->pBuffer, pcmBuffer, bufLength); buf->nFilledLen = bufLength; int r = OMX_EmptyThisBuffer(ilclient_get_handle(component), buf); if (r != OMX_ErrorNone) { fprintf(stderr, "Empty buffer error\n"); } } else { printf("Opus error from decode: %d\n", decodeLen); } }
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); }
///////////////////////////////////////////////////////// // savePhoto() saves a photo locally // needs to be passed camera component and image_encode component // because it has to directly manipulate the ports on both void savePhoto(COMPONENT_T *camera, COMPONENT_T *image_encode, char *filePrefix, char *filePostFix) { printf("in savePhoto\n"); OMX_ERRORTYPE OMXstatus; OMX_BUFFERHEADERTYPE *decode_out; printf("filePreFix = %s filePostFix = %s", filePrefix, filePostFix); printf("%s\n", fileFindNext(filePrefix, filePostFix)); FILE *file_out; file_out = fopen(fileFindNext(filePrefix, filePostFix), "wb"); //check file? printf("capture started\n"); // needed to notify camera component of image capture OMX_CONFIG_PORTBOOLEANTYPE still_capture_in_progress; memset(&still_capture_in_progress, 0, sizeof(still_capture_in_progress)); still_capture_in_progress.nVersion.nVersion = OMX_VERSION; still_capture_in_progress.nSize = sizeof(still_capture_in_progress); still_capture_in_progress.nPortIndex = 72; still_capture_in_progress.bEnabled = OMX_FALSE; //tell camera component port is taking picture - appears to be nessesery! still_capture_in_progress.bEnabled = OMX_TRUE; OMXstatus = OMX_SetConfig(ilclient_get_handle(camera), OMX_IndexConfigPortCapturing, &still_capture_in_progress); if (OMXstatus != OMX_ErrorNone) { fprintf(stderr, "unable to set Config (1)\n"); exit(EXIT_FAILURE); } while(1) { decode_out = ilclient_get_output_buffer(image_encode, 341, 1/*blocking*/); printf("decode_out bytes = %d : ", decode_out->nFilledLen); printf("decode_out bufferflags = %d\n", decode_out->nFlags); if(decode_out->nFilledLen != 0) { fwrite(decode_out->pBuffer, 1, decode_out->nFilledLen, file_out); } if(decode_out->nFlags == 1) { fwrite(decode_out->pBuffer, 1, decode_out->nFilledLen, file_out); OMX_FillThisBuffer(ilclient_get_handle(image_encode), decode_out); break; } //crashes if starts with 0 buffer? OMX_FillThisBuffer(ilclient_get_handle(image_encode), decode_out); } //tell API port is finished capture memset(&still_capture_in_progress, 0, sizeof(still_capture_in_progress)); still_capture_in_progress.nVersion.nVersion = OMX_VERSION; still_capture_in_progress.nSize = sizeof(still_capture_in_progress); still_capture_in_progress.nPortIndex = 72; still_capture_in_progress.bEnabled = OMX_FALSE; OMXstatus = OMX_SetConfig(ilclient_get_handle(camera), OMX_IndexConfigPortCapturing, &still_capture_in_progress); if (OMXstatus != OMX_ErrorNone) { fprintf(stderr, "unable to set Config (1)\n"); exit(EXIT_FAILURE); } fclose(file_out); printf("captureSaved\n"); }
// sets the preview size and position // takes the enum displayTypes the contents of which should hopefully be self explanitory void setRenderConfig(COMPONENT_T *video_render, enum displayTypes presetScreenConfig) { struct screenSizeStruct currentScreenSize; currentScreenSize = returnScreenSize(); int screenWidth = currentScreenSize.width; int screenHeight = currentScreenSize.height; printf("in setRenderConfig\n"); OMX_ERRORTYPE OMXstatus; OMX_CONFIG_DISPLAYREGIONTYPE render_config; memset(&render_config, 0, sizeof(render_config)); render_config.nVersion.nVersion = OMX_VERSION; render_config.nSize = sizeof(render_config); render_config.nPortIndex = 90; //curently only does fullscreen modify the stucture below with switch/if statements for the others render_config.set = (OMX_DISPLAYSETTYPE)(OMX_DISPLAY_SET_DEST_RECT |OMX_DISPLAY_SET_FULLSCREEN |OMX_DISPLAY_SET_NOASPECT |OMX_DISPLAY_SET_MODE); //FULLSCREEN if(presetScreenConfig == DISPLAY_FULLSCREEN) { render_config.dest_rect.width = screenWidth; render_config.dest_rect.height = screenHeight; render_config.dest_rect.x_offset = 0; render_config.dest_rect.y_offset = 0; } //SIDEBYSIDE else if(presetScreenConfig == DISPLAY_SIDEBYSIDE_LEFT) { render_config.dest_rect.width = screenWidth/2; render_config.dest_rect.height = screenHeight; render_config.dest_rect.x_offset = 0; render_config.dest_rect.y_offset = 0; } else if(presetScreenConfig == DISPLAY_SIDEBYSIDE_RIGHT) { render_config.dest_rect.width = screenWidth/2; render_config.dest_rect.height = screenHeight; render_config.dest_rect.x_offset = screenWidth/2; render_config.dest_rect.y_offset = 0; } //QUARTER else if(presetScreenConfig == DISPLAY_QUARTER_TOP_LEFT) { render_config.dest_rect.width = screenWidth/2; render_config.dest_rect.height = screenHeight/2; render_config.dest_rect.x_offset = 0; render_config.dest_rect.y_offset = 0; } else if(presetScreenConfig == DISPLAY_QUARTER_TOP_RIGHT) { render_config.dest_rect.width = screenWidth/2; render_config.dest_rect.height = screenHeight/2; render_config.dest_rect.x_offset = screenWidth/2;; render_config.dest_rect.y_offset = 0; } else if(presetScreenConfig == DISPLAY_QUARTER_BOTTOM_LEFT) { render_config.dest_rect.width = screenWidth/2; render_config.dest_rect.height = screenHeight/2; render_config.dest_rect.x_offset = 0; render_config.dest_rect.y_offset = screenHeight/2; } else if(presetScreenConfig == DISPLAY_QUARTER_BOTTOM_RIGHT) { render_config.dest_rect.width = screenWidth/2; render_config.dest_rect.height = screenHeight/2; render_config.dest_rect.x_offset = screenWidth/2; render_config.dest_rect.y_offset = screenHeight/2; } //SIXTH else if(presetScreenConfig == DISPLAY_SIXTH_TOP_LEFT) { render_config.dest_rect.width = screenWidth/3; render_config.dest_rect.height = screenHeight/2; render_config.dest_rect.x_offset = 0; render_config.dest_rect.y_offset = 0; } else if(presetScreenConfig == DISPLAY_SIXTH_TOP_MIDDLE) { render_config.dest_rect.width = screenWidth/3; render_config.dest_rect.height = screenHeight/2; render_config.dest_rect.x_offset = screenWidth/3; render_config.dest_rect.y_offset = 0; } else if(presetScreenConfig == DISPLAY_SIXTH_TOP_RIGHT) { render_config.dest_rect.width = screenWidth/3; render_config.dest_rect.height = screenHeight/2; render_config.dest_rect.x_offset = (screenWidth/3)*2; render_config.dest_rect.y_offset = 0; } else if(presetScreenConfig == DISPLAY_SIXTH_BOTTOM_LEFT) { render_config.dest_rect.width = screenWidth/3; render_config.dest_rect.height = screenHeight/2; render_config.dest_rect.x_offset = 0; render_config.dest_rect.y_offset = screenHeight/2; } else if(presetScreenConfig == DISPLAY_SIXTH_BOTTOM_MIDDLE) { render_config.dest_rect.width = screenWidth/3; render_config.dest_rect.height = screenHeight/2; render_config.dest_rect.x_offset = screenWidth/3; render_config.dest_rect.y_offset = screenHeight/2; } else if(presetScreenConfig == DISPLAY_SIXTH_BOTTOM_RIGHT) { render_config.dest_rect.width = screenWidth/3; render_config.dest_rect.height = screenHeight/2; render_config.dest_rect.x_offset = (screenWidth/3)*2; render_config.dest_rect.y_offset = screenHeight/2; } render_config.fullscreen = OMX_FALSE; render_config.noaspect = OMX_FALSE; render_config.mode = OMX_DISPLAY_MODE_LETTERBOX; OMXstatus = OMX_SetConfig(ilclient_get_handle(video_render), OMX_IndexConfigDisplayRegion, &render_config); if(OMXstatus != OMX_ErrorNone) printf("Error Setting Parameter. Error = %s\n", err2str(OMXstatus)); }
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); }