static int prepareResizer(OMX_RESIZER *resizer){ int ret = ilclient_create_component(resizer->client, &resizer->component, "resize", ILCLIENT_DISABLE_ALL_PORTS| ILCLIENT_ENABLE_INPUT_BUFFERS| ILCLIENT_ENABLE_OUTPUT_BUFFERS); if (ret != 0) { return OMX_IMAGE_ERROR_CREATING_COMP; } resizer->handle = ILC_GET_HANDLE(resizer->component); OMX_PORT_PARAM_TYPE port; port.nSize = sizeof(OMX_PORT_PARAM_TYPE); port.nVersion.nVersion = OMX_VERSION; OMX_GetParameter(resizer->handle,OMX_IndexParamImageInit, &port); if (port.nPorts != 2) { return OMX_IMAGE_ERROR_PORTS; } resizer->inPort = port.nStartPortNumber; resizer->outPort = port.nStartPortNumber + 1; resizer->pOutputBufferHeader = NULL; return OMX_IMAGE_OK; }
ILCLIENT_T * encode_init(COMPONENT_T **video_encode) { ILCLIENT_T *client = ilclient_init(); if (client == NULL) { return NULL; } if (OMX_Init() != OMX_ErrorNone) { ilclient_destroy(client); return NULL; } // create video_encode int omx_return = ilclient_create_component(client, video_encode, "video_encode", (ILCLIENT_CREATE_FLAGS_T)(ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS | ILCLIENT_ENABLE_OUTPUT_BUFFERS)); if (omx_return != 0) { fprintf(stderr, "ilclient_create_component() for video_encode failed with %x!\n", omx_return); ilclient_destroy(client); return NULL; } return client; }
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_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)); }
int prepareImageDecoder(OPENMAX_JPEG_DECODER * decoder) { decoder->imageDecoder = malloc(sizeof(COMPONENT_DETAILS)); if (decoder->imageDecoder == NULL) { perror("malloc image decoder"); return OMXJPEG_ERROR_MEMORY; } int ret = ilclient_create_component(decoder->client, &decoder-> imageDecoder-> component, "image_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS | ILCLIENT_ENABLE_OUTPUT_BUFFERS); if (ret != 0) { perror("image decode"); return OMXJPEG_ERROR_CREATING_COMP; } // grab the handle for later use in OMX calls directly decoder->imageDecoder->handle = ILC_GET_HANDLE(decoder->imageDecoder->component); // get and store the ports OMX_PORT_PARAM_TYPE port; port.nSize = sizeof(OMX_PORT_PARAM_TYPE); port.nVersion.nVersion = OMX_VERSION; OMX_GetParameter(decoder->imageDecoder->handle, OMX_IndexParamImageInit, &port); if (port.nPorts != 2) { return OMXJPEG_ERROR_WRONG_NO_PORTS; } decoder->imageDecoder->inPort = port.nStartPortNumber; decoder->imageDecoder->outPort = port.nStartPortNumber + 1; decoder->pOutputBufferHeader = NULL; return OMXJPEG_OK; }
int prepareRender(OPENMAX_JPEG_DECODER * decoder) { decoder->imageRender = malloc(sizeof(COMPONENT_DETAILS)); if (decoder->imageRender == NULL) { perror("malloc image render"); return OMXJPEG_ERROR_MEMORY; } int ret = ilclient_create_component(decoder->client, &decoder-> imageRender-> component, "video_render", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS ); if (ret != 0) { perror("image render"); return OMXJPEG_ERROR_CREATING_COMP; } // grab the handle for later use decoder->imageRender->handle = ILC_GET_HANDLE(decoder->imageRender->component); // get and store the ports OMX_PORT_PARAM_TYPE port; port.nSize = sizeof(OMX_PORT_PARAM_TYPE); port.nVersion.nVersion = OMX_VERSION; OMX_GetParameter(ILC_GET_HANDLE(decoder->imageRender->component), OMX_IndexParamVideoInit, &port); if (port.nPorts != 1) { return OMXJPEG_ERROR_WRONG_NO_PORTS; } decoder->imageRender->inPort = port.nStartPortNumber; /* decoder->imageRender->outPort = port.nStartPortNumber + 1; */ // the default is 3 buffers, but we want to use only one // query output buffer requirements for render OMX_PARAM_PORTDEFINITIONTYPE portdef; portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion.nVersion = OMX_VERSION; portdef.nPortIndex = decoder->imageRender->inPort; OMX_GetParameter(decoder->imageRender->handle, OMX_IndexParamPortDefinition, &portdef); decoder->renderInputBufferHeaderCount = portdef.nBufferCountActual; /* later settings params doesn't like this! portdef.nBufferCountActual = 1; ret = OMX_SetParameter(decoder->imageRender->handle, OMX_IndexParamPortDefinition, &portdef); if (ret != OMX_ErrorNone) { fprintf(stderr, "Eror setting render buffers to one %s\n", err2str(ret)); return OMXJPEG_ERROR_MEMORY; } */ decoder->pOutputBufferHeader = NULL; return OMXJPEG_OK; }
static int video_decode_test(char *filename) { OMX_VIDEO_PARAM_PORTFORMATTYPE format; OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; COMPONENT_T *video_decode = NULL, *video_scheduler = NULL, *video_render = NULL, *clock = NULL; COMPONENT_T *list[5]; TUNNEL_T tunnel[4]; ILCLIENT_T *client; FILE *in; int status = 0; unsigned int data_len = 0; memset(list, 0, sizeof(list)); memset(tunnel, 0, sizeof(tunnel)); if((in = fopen(filename, "rb")) == NULL) return -2; if((client = ilclient_init()) == NULL) { fclose(in); return -3; } if(OMX_Init() != OMX_ErrorNone) { ilclient_destroy(client); fclose(in); return -4; } // create video_decode if(ilclient_create_component(client, &video_decode, "video_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0) status = -14; list[0] = video_decode; // create video_render if(status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0) status = -14; list[1] = video_render; // create clock if(status == 0 && ilclient_create_component(client, &clock, "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0) status = -14; list[2] = clock; memset(&cstate, 0, sizeof(cstate)); cstate.nSize = sizeof(cstate); cstate.nVersion.nVersion = OMX_VERSION; cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; cstate.nWaitMask = 1; if(clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(clock), OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone) status = -13; // create video_scheduler if(status == 0 && ilclient_create_component(client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0) status = -14; list[3] = video_scheduler; set_tunnel(tunnel, video_decode, 131, video_scheduler, 10); set_tunnel(tunnel+1, video_scheduler, 11, video_render, 90); set_tunnel(tunnel+2, clock, 80, video_scheduler, 12); // setup clock tunnel first if(status == 0 && ilclient_setup_tunnel(tunnel+2, 0, 0) != 0) status = -15; else ilclient_change_component_state(clock, OMX_StateExecuting); if(status == 0) ilclient_change_component_state(video_decode, OMX_StateIdle); memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); format.nVersion.nVersion = OMX_VERSION; format.nPortIndex = 130; format.eCompressionFormat = OMX_VIDEO_CodingAVC; if(status == 0 && OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone && ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0) { OMX_BUFFERHEADERTYPE *buf; int port_settings_changed = 0; int first_packet = 1; ilclient_change_component_state(video_decode, OMX_StateExecuting); while((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL) { // feed data and wait until we get port settings changed unsigned char *dest = buf->pBuffer; data_len += fread(dest, 1, buf->nAllocLen-data_len, in); if(port_settings_changed == 0 && ((data_len > 0 && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) || (data_len == 0 && ilclient_wait_for_event(video_decode, OMX_EventPortSettingsChanged, 131, 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_scheduler, OMX_StateExecuting); // now setup tunnel to video_render if(ilclient_setup_tunnel(tunnel+1, 0, 1000) != 0) { status = -12; break; } ilclient_change_component_state(video_render, OMX_StateExecuting); } if(!data_len) break; buf->nFilledLen = data_len; data_len = 0; buf->nOffset = 0; if(first_packet) { buf->nFlags = OMX_BUFFERFLAG_STARTTIME; first_packet = 0; } else buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) { status = -6; break; } } buf->nFilledLen = 0; buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS; if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != 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); // need to flush the renderer to allow video_decode to disable its input port ilclient_flush_tunnels(tunnel, 0); } fclose(in); ilclient_disable_tunnel(tunnel); ilclient_disable_tunnel(tunnel+1); ilclient_disable_tunnel(tunnel+2); ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL); ilclient_teardown_tunnels(tunnel); ilclient_state_transition(list, OMX_StateIdle); ilclient_state_transition(list, OMX_StateLoaded); ilclient_cleanup_components(list); OMX_Deinit(); ilclient_destroy(client); return status; }
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); } }
static int brcm_omx_vc03_recd_init(void) { OMX_ERRORTYPE error; OMX_PARAM_PORTDEFINITIONTYPE param; OMX_AUDIO_PARAM_PCMMODETYPE param1; int i,size; DEBUG("\n %lx:brcm_omx_vc03_recd_init\n",jiffies); g_brcm_alsa_chip->pcm_ptr[1] = 0; //recorder stuff memset(&st_recd,0,sizeof(COMPONENT_T)); error = ilclient_create_component(client, &st_recd, "audio_record", 0, 1, 1); ERROR_RETURN("ilclient_create_component record",error); ilclient_disable_port(&st_recd,181); // memset(¶m, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); param.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); param.nVersion.nVersion = OMX_VERSION; param.nPortIndex = 180; error = OMX_GetParameter(st_recd.comp, OMX_IndexParamPortDefinition, ¶m); ERROR_RETURN("OMX_GetParameter record param",error); DEBUG("\n brcm_omx_vc03_recd_init:nBufferCountActual=%d\n", (int)param.nBufferCountActual); param.nBufferSize = g_brcm_alsa_chip->period_bytes[1]; error = OMX_SetParameter(st_recd.comp, OMX_IndexParamPortDefinition, ¶m); ERROR_RETURN("OMX_SetParameter record param",error); // memset(¶m1, 0, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); param1.nSize = sizeof(OMX_AUDIO_PARAM_PCMMODETYPE); param1.nVersion.nVersion = OMX_VERSION; param1.nPortIndex = 180; error = OMX_GetParameter(st_recd.comp, OMX_IndexParamAudioPcm, ¶m1); ERROR_RETURN("OMX_GetParameter record param",error); param1.nSamplingRate = 16000;//support 16000 only? error = OMX_SetParameter(st_recd.comp, OMX_IndexParamAudioPcm, ¶m1); ERROR_RETURN("OMX_SetParameter record param1",error); // error = OMX_SendCommand(st_recd.comp, OMX_CommandStateSet, OMX_StateIdle, NULL); ERROR_RETURN("OMX_SendCommand",error); // size = g_brcm_alsa_chip->period_bytes[1]; for(i=0; i<param.nBufferCountActual; i++) { error = OMX_UseBuffer(st_recd.comp, &st_recd.out_list, 180, st_recd.out_list, size, NULL); ERROR_RETURN("OMX_UseBuffer",error); DEBUG("\n record %lx:st.out_list=%x st.out_list->private=%x\n",jiffies, (unsigned int)st_recd.out_list,(unsigned int)st_recd.out_list->pAppPrivate); } recd_buffer = st_recd.out_list; error = ilclient_wait_for_event(&st_recd, OMX_EventCmdComplete, OMX_CommandStateSet, 0, OMX_StateIdle, 0, ILCLIENT_STATE_CHANGED, PLATFORM_EVENTGROUP_SUSPEND); ERROR_RETURN("ilclient_wait_for_event record",error); if (alsa_pcm_event & PCM_EVENT_RECD_START) { error = ilclient_change_component_state(&st_recd, OMX_StateExecuting); ERROR_RETURN("ilclient_change_component_state record",error); } return 0; }
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); }
void native_audio_init() { OMX_ERRORTYPE error; OMX_PARAM_PORTDEFINITIONTYPE param; OMX_AUDIO_PARAM_PCMMODETYPE pcm; int32_t s; // create and start up everything client = ilclient_init(); assert(client != NULL); error = OMX_Init(); assert(error == OMX_ErrorNone); ilclient_create_component(client, &audio_render, "audio_render", ILCLIENT_ENABLE_INPUT_BUFFERS | ILCLIENT_DISABLE_ALL_PORTS); assert(audio_render != NULL); // set up the number/size of buffers memset(¶m, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); param.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); param.nVersion.nVersion = OMX_VERSION; param.nPortIndex = 100; error = OMX_GetParameter(ILC_GET_HANDLE(audio_render), OMX_IndexParamPortDefinition, ¶m); assert(error == OMX_ErrorNone); int size = scaled_buffer_size(NUM_SAMPLES); size = (size + 15) & ~15; param.nBufferSize = size; param.nBufferCountActual = 2; error = OMX_SetParameter(ILC_GET_HANDLE(audio_render), OMX_IndexParamPortDefinition, ¶m); assert(error == OMX_ErrorNone); // set the pcm parameters memset(&pcm, 0, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); pcm.nSize = sizeof(OMX_AUDIO_PARAM_PCMMODETYPE); pcm.nVersion.nVersion = OMX_VERSION; pcm.nPortIndex = 100; pcm.nChannels = 2; pcm.eNumData = OMX_NumericalDataSigned; pcm.eEndian = OMX_EndianLittle; pcm.nSamplingRate = SAMPLE_FREQ; pcm.bInterleaved = OMX_TRUE; pcm.nBitPerSample = 16; pcm.ePCMMode = OMX_AUDIO_PCMModeLinear; pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF; pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF; error = OMX_SetParameter(ILC_GET_HANDLE(audio_render), OMX_IndexParamAudioPcm, &pcm); assert(error == OMX_ErrorNone); assert(ilclient_change_component_state(audio_render, OMX_StateIdle) == 0); if(ilclient_enable_port_buffers(audio_render, 100, NULL, NULL, NULL) < 0) { // error ilclient_change_component_state(audio_render, OMX_StateLoaded); COMPONENT_T* list[2]; list[0] = audio_render; list[1] = 0; ilclient_cleanup_components(list); error = OMX_Deinit(); assert(error == OMX_ErrorNone); ilclient_destroy(client); exit(-1); } assert(ilclient_change_component_state(audio_render, OMX_StateExecuting) == 0); // set the destination OMX_CONFIG_BRCMAUDIODESTINATIONTYPE ar_dest; const char* name = "hdmi"; memset(&ar_dest, 0, sizeof(ar_dest)); ar_dest.nSize = sizeof(OMX_CONFIG_BRCMAUDIODESTINATIONTYPE); ar_dest.nVersion.nVersion = OMX_VERSION; strcpy((char *)ar_dest.sName, name); error = OMX_SetConfig(ILC_GET_HANDLE(audio_render), OMX_IndexConfigBrcmAudioDestination, &ar_dest); assert(error == OMX_ErrorNone); // get the buffer flow going pthread_create(&audio_thread, NULL, audio_exec, NULL); }
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; }
// Modified function prototype to work with pthreads void *video_decode_test(void* arg) { pthread_mutex_init(&m_lock, NULL); printf("OMX version : %d.%d.%d-%d\n",OMX_VERSION_MAJOR, OMX_VERSION_MINOR, OMX_VERSION_REVISION, OMX_VERSION_STEP); printf("file to read : %s\n", filename); eglImage = arg; if (eglImage == 0) { printf("eglImage is null.\n"); exit(1); } int status = 0; unsigned int data_len = 0; int packet_size = 80<<10; memset(list, 0, sizeof(list)); memset(tunnel, 0, sizeof(tunnel)); if((in = fopen(filename, "rb")) == NULL) return (void *)-2; if((client = ilclient_init()) == NULL) { fclose(in); return (void *)-3; } if(OMX_Init() != OMX_ErrorNone) { ilclient_destroy(client); fclose(in); return (void *)-4; } // callback ilclient_set_fill_buffer_done_callback(client, my_fill_buffer_done, 0); // create video_decode if(ilclient_create_component(client, &video_decode, "video_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0) status = -14; list[0] = video_decode; // create video_render //if(status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0) if(status == 0 && ilclient_create_component(client, &video_render, "egl_render", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_OUTPUT_BUFFERS) != 0) status = -14; list[1] = video_render; // create clock if(status == 0 && ilclient_create_component(client, &omx_clock, "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0) status = -14; list[2] = omx_clock; memset(&cstate, 0, sizeof(cstate)); cstate.nSize = sizeof(cstate); cstate.nVersion.nVersion = OMX_VERSION; cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; cstate.nWaitMask = 1; if(omx_clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(omx_clock), OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone) status = -13; // set the clock refenrece to "none" memset(&cref,0,sizeof(cref)); cref.nSize = sizeof(cref); cref.nVersion.nVersion = OMX_VERSION; cref.eClock = OMX_TIME_RefClockNone; if(omx_clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(omx_clock), OMX_IndexConfigTimeActiveRefClock, &cref) != OMX_ErrorNone){ status = -13; printf("error setting refclock\n"); } // create video_scheduler if(status == 0 && ilclient_create_component(client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0) status = -14; list[3] = video_scheduler; set_tunnel(tunnel, video_decode, 131, video_scheduler, 10); //set_tunnel(tunnel+1, video_scheduler, 11, video_render, 90); set_tunnel(tunnel+1, video_scheduler, 11, video_render, 220); set_tunnel(tunnel+2, omx_clock, 80, video_scheduler, 12); // setup clock tunnel first if(status == 0 && ilclient_setup_tunnel(tunnel+2, 0, 0) != 0) status = -15; else ilclient_change_component_state(omx_clock, OMX_StateExecuting); if(status == 0) ilclient_change_component_state(video_decode, OMX_StateIdle); memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); format.nVersion.nVersion = OMX_VERSION; format.nPortIndex = 130; format.eCompressionFormat = OMX_VIDEO_CodingAVC; if(status == 0 && OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone && ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0) { OMX_BUFFERHEADERTYPE *buf; int port_settings_changed = 0; int first_packet = 1; ilclient_change_component_state(video_decode, OMX_StateExecuting); while((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL && stop_flag==0 ) { // feed data and wait until we get port settings changed unsigned char *dest = buf->pBuffer; // loop if at end if (feof(in)) rewind(in); data_len += fread(dest, 1, packet_size-data_len, in); if(port_settings_changed == 0 && ((data_len > 0 && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) || (data_len == 0 && ilclient_wait_for_event(video_decode, OMX_EventPortSettingsChanged, 131, 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_scheduler, OMX_StateExecuting); // now setup tunnel to video_render if(ilclient_setup_tunnel(tunnel+1, 0, 1000) != 0) { status = -12; break; } // Set egl_render to idle ilclient_change_component_state(video_render, OMX_StateIdle); // Enable the output port and tell egl_render to use the texture as a buffer //ilclient_enable_port(video_render, 221); THIS BLOCKS SO CANT BE USED if (OMX_SendCommand(ILC_GET_HANDLE(video_render), OMX_CommandPortEnable, 221, NULL) != OMX_ErrorNone) { printf("OMX_CommandPortEnable failed.\n"); exit(1); } if (OMX_UseEGLImage(ILC_GET_HANDLE(video_render), &eglBuffer, 221, NULL, eglImage) != OMX_ErrorNone) { printf("OMX_UseEGLImage failed.\n"); exit(1); } // Set egl_render to executing ilclient_change_component_state(video_render, OMX_StateExecuting); // Request egl_render to write data to the texture buffer if(OMX_FillThisBuffer(ILC_GET_HANDLE(video_render), eglBuffer) != OMX_ErrorNone) { printf("OMX_FillThisBuffer failed.\n"); //~ exit(1); } } if(!data_len) break; buf->nFilledLen = data_len; data_len = 0; buf->nOffset = 0; if(first_packet) { buf->nFlags = OMX_BUFFERFLAG_STARTTIME; first_packet = 0; } else buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) { status = -6; break; } } printf("loop ends, now flush the buffer\n"); OMX_SendCommand(ILC_GET_HANDLE(video_decode),OMX_CommandFlush,130,NULL); OMX_SendCommand(ILC_GET_HANDLE(video_decode),OMX_CommandFlush,131,NULL); ilclient_wait_for_event(video_decode, OMX_EventCmdComplete, OMX_CommandFlush, 0, 130, 0, ILCLIENT_PORT_FLUSH, -1); ilclient_wait_for_event(video_decode, OMX_EventCmdComplete, OMX_CommandFlush, 0, 131, 0, ILCLIENT_PORT_FLUSH, -1); data_len=0; memset(&cstate, 0, sizeof(cstate)); cstate.nSize = sizeof(cstate); cstate.nVersion.nVersion = OMX_VERSION; cstate.eState = OMX_TIME_ClockStateStopped; cstate.nWaitMask = 1; OMX_SetParameter(ILC_GET_HANDLE(omx_clock), OMX_IndexConfigTimeClockState, &cstate); memset(&cstate, 0, sizeof(cstate)); cstate.nSize = sizeof(cstate); cstate.nVersion.nVersion = OMX_VERSION; cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; cstate.nWaitMask = 1; OMX_SetParameter(ILC_GET_HANDLE(omx_clock), OMX_IndexConfigTimeClockState, &cstate); //~ scheduler should be stopped... buf->nFilledLen = 0; buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS; if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) status = -20; // wait for EOS from render //~ printf("wait for EOS from render\n"); //~ ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0, //~ ILCLIENT_BUFFER_FLAG_EOS, 10000); while ((ilclient_remove_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0) <0 ) && !stop_flag){ } printf("flush the render\n"); // need to flush the renderer to allow video_decode to disable its input port ilclient_flush_tunnels(tunnel, 0); ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL); } printf("close file\n"); fclose(in); ilclient_disable_tunnel(tunnel); ilclient_disable_tunnel(tunnel+1); ilclient_disable_tunnel(tunnel+2); ilclient_teardown_tunnels(tunnel); ilclient_state_transition(list, OMX_StateIdle); ilclient_state_transition(list, OMX_StateLoaded); ilclient_cleanup_components(list); OMX_Deinit(); ilclient_destroy(client); printf("thread will return...\n"); pthread_mutex_destroy(&m_lock); return (void *)status; }
/* ------------------------------------------------- / audioplay_create() / Create audio decoder & render & other hardware component /---------------------------------------------------*/ static INT32 audioplay_create( AUDIOPLAY_STATE_T **handle, UINT32 sample_rate, UINT32 num_channels, UINT32 bit_depth, UINT32 num_buffers, ///< 100 UINT32 buffer_size ///< 480*(16/8)*2 = 1920 ){ OMX_AUDIO_PARAM_PCMMODETYPE pcm; UINT32 bytes_per_sample = (bit_depth * num_channels) >> 3; INT32 ret = -1; int rv; *handle = NULL; /* TODO basic sanity check on arguments */ if(sample_rate >= 8000 && sample_rate <= 96000 && (num_channels == 1 || num_channels == 2 || num_channels == 4 || num_channels == 8) && (bit_depth == 16 || bit_depth == 32) && (num_buffers > 0) && (buffer_size >= bytes_per_sample)){ /* TODO buffer length must be 16 bytes aligned for VCHI */ int size = (buffer_size + 15) & ~15; /* TODO buffer length must be 16 bytes aligned for VCHI */ st = calloc(1, sizeof(AUDIOPLAY_STATE_T)); assert(st != NULL); OMX_ERRORTYPE error; OMX_PARAM_PORTDEFINITIONTYPE param; INT32 s; ret = 0; /* TODO combine with st = calloc()?*/ *handle = st; /* create and start up audio codec hardware component */ /* TODO semaphore */ s = sem_init(&st->sema, 0 ,1); assert(s == 0); st->bytes_per_sample = bytes_per_sample; st->num_buffers = num_buffers; st->client = ilclient_init(); assert(st->client != NULL); /*TODO input_buffer_callback*/ ilclient_set_empty_buffer_done_callback(st->client, input_buffer_callback, st); error = OMX_Init(); assert(error == OMX_ErrorNone); /* Create audio render */ ilclient_create_component(st->client, &(st->audio_render), "audio_render", ILCLIENT_ENABLE_INPUT_BUFFERS | ILCLIENT_DISABLE_ALL_PORTS); assert(st->audio_render != NULL); st->list[0] = st->audio_render; /* Create clock component */ ilclient_create_component(st->client, &(st->clock), "clock", ILCLIENT_DISABLE_ALL_PORTS); assert(st->clock != NULL); st->list[1] = st->clock; /* Configure clock */ OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; memset(&cstate, 0, sizeof(cstate)); cstate.nSize = sizeof(cstate); cstate.nVersion.nVersion = OMX_VERSION; cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; cstate.nWaitMask = 1; //TODO error = OMX_SetParameter(ILC_GET_HANDLE(st->clock), OMX_IndexConfigTimeClockState, &cstate); assert(error == 0); /* Setup tunnel to connect clock and audio render */ set_tunnel(&st->tunnel, st->clock, 80, st->audio_render, 101); rv = ilclient_setup_tunnel(&st->tunnel, 0, 0); assert(rv == 0); /* kick off clock */ ilclient_change_component_state(st->clock, OMX_StateExecuting); /* Set audio render port definition */ /* Set up the number/size of buffers */ memset(¶m, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); param.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); param.nVersion.nVersion = OMX_VERSION; param.nPortIndex = 100; error = OMX_GetParameter(ILC_GET_HANDLE(st->audio_render), OMX_IndexParamPortDefinition, ¶m); assert(error == OMX_ErrorNone); param.nBufferSize = size; param.nBufferCountActual = num_buffers; error = OMX_SetParameter(ILC_GET_HANDLE(st->audio_render), OMX_IndexParamPortDefinition, ¶m); assert(error == OMX_ErrorNone); /* Set audio render PCM definition */ memset(&pcm, 0, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); pcm.nSize = sizeof(OMX_AUDIO_PARAM_PCMMODETYPE); pcm.nVersion.nVersion = OMX_VERSION; pcm.nPortIndex = 100; pcm.nChannels = num_channels; pcm.eNumData = OMX_NumericalDataSigned; //TODO pcm.eEndian = OMX_EndianLittle; pcm.nSamplingRate = sample_rate; pcm.bInterleaved = OMX_TRUE; pcm.nBitPerSample = bit_depth; pcm.ePCMMode = OMX_AUDIO_PCMModeLinear; switch(num_channels){ case 1: { pcm.eChannelMapping[0] = OMX_AUDIO_ChannelCF; break; } case 8: { /*TODO*/ pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF; pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF; pcm.eChannelMapping[2] = OMX_AUDIO_ChannelCF; pcm.eChannelMapping[3] = OMX_AUDIO_ChannelLFE; pcm.eChannelMapping[4] = OMX_AUDIO_ChannelLR; pcm.eChannelMapping[5] = OMX_AUDIO_ChannelRR; pcm.eChannelMapping[6] = OMX_AUDIO_ChannelLS; pcm.eChannelMapping[7] = OMX_AUDIO_ChannelRS; break; } case 4: { pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF; pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF; pcm.eChannelMapping[2] = OMX_AUDIO_ChannelLR; pcm.eChannelMapping[3] = OMX_AUDIO_ChannelRR; break; } case 2: { pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF; pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF; break; } } error = OMX_SetParameter(ILC_GET_HANDLE(st->audio_render), OMX_IndexParamAudioPcm, &pcm); assert(error == OMX_ErrorNone); /* Set audio reference clock */ OMX_CONFIG_BOOLEANTYPE ref_clock; memset(&ref_clock, 0, sizeof(OMX_CONFIG_BOOLEANTYPE)); param.nSize = sizeof(OMX_CONFIG_BOOLEANTYPE); param.nVersion.nVersion = OMX_VERSION; param.bEnabled = OMX_FALSE; error = OMX_SetConfig(ILC_GET_HANDLE(st->audio_render), OMX_IndexConfigBrcmClockReferenceSource, &ref_clock); assert(error == OMX_ErrorNone); /* Enable audio render */ ilclient_change_component_state(st->audio_render, OMX_StateIdle); if(ilclient_enable_port_buffers(st->audio_render, 100, NULL, NULL, NULL) < 0){ /* Error situation */ ilclient_change_component_state(st->audio_render, OMX_StateLoaded); ilclient_cleanup_components(st->list); error = OMX_Deinit(); assert(error == OMX_ErrorNone); ilclient_destroy(st->client); sem_destroy(&st->sema); free(st); *handle = NULL; return -1; } ilclient_change_component_state(st->audio_render, OMX_StateExecuting); } return ret; }
/* ------------------------------------------------- / sx_video_sink_init() / /---------------------------------------------------*/ void sx_video_sink_init(void){ OMX_VIDEO_PARAM_PORTFORMATTYPE format; OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; int rc; /* Init compoent & tunnel */ memset(comp_list, 0, sizeof(comp_list)); memset(tunnel, 0, sizeof(tunnel)); /* Init Broadcom host */ bcm_host_init(); /* Init il client */ client = ilclient_init(); assert(client != NULL); /* Init OpenMax */ rc = OMX_Init(); assert(rc == OMX_ErrorNone); /* Create Decoder Component,beacuse enable input buffers,so in the end need to OMX_EmptyThisBuffer */ rc = ilclient_create_component( client, &video_decode, "video_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS); assert(rc == 0); comp_list[0] = video_decode; /* Create video render */ rc = ilclient_create_component( client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS); assert(rc == 0); comp_list[1] = video_render; /* Create clock */ rc = ilclient_create_component( client, &video_clock, "clock", ILCLIENT_DISABLE_ALL_PORTS); assert(rc == 0); comp_list[2] = video_clock; /* Configure clock */ memset(&cstate, 0, sizeof(cstate)); cstate.nSize = sizeof(cstate); cstate.nVersion.nVersion = OMX_VERSION; cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; cstate.nWaitMask = 1; rc = OMX_SetParameter(ILC_GET_HANDLE(video_clock), OMX_IndexConfigTimeClockState, &cstate); assert(rc == 0); /* Create video scheduler */ rc = ilclient_create_component( client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS); assert(rc == 0); comp_list[3] = video_scheduler; /* Set tunnels */ /* Connect decode to scheduler */ set_tunnel(tunnel, video_decode, 131, video_scheduler, 10); /* Connect scheduler to render */ set_tunnel(tunnel+1, video_scheduler, 11, video_render, 90); /* Connect clock to scheduler */ set_tunnel(tunnel+2, video_clock, 80, video_scheduler, 12); /* Setup clock tunnel first */ rc = ilclient_setup_tunnel(tunnel+2, 0, 0); assert(rc == 0); /* Kick start the clock */ ilclient_change_component_state(video_clock, OMX_StateExecuting); #define AUTO_FULLSCREEN #if 1 OMX_CONFIG_DISPLAYREGIONTYPE drt; memset(&drt, 0, sizeof(drt)); drt.nVersion.nVersion = OMX_VERSION; drt.nSize = sizeof(drt); drt.nPortIndex = 90; /* if not defined AUTO_FULLSCREEN it means that set other display region type */ #if 0 #if !defined(AUTO_FULLSCREEN) /*TODO*/ drt.src_rect.x_offset = 0; drt.src_rect.y_offset = 0; drt.src_rect.width = sx_mgmt_env_get(MGMT_ENV_VAR_SESSION_WIDTH); drt.src_rect.height = sx_mgmt_env_get(MGMT_ENV_VAR_SESSION_HEIGHT); drt.dest_rect.x_offset = -56; drt.dest_rect.y_offset = 0; drt.dest_rect.width = 1792; drt.dest_rect.height = 1050; #endif #endif #if !defined(AUTO_FULLSCREEN) drt.fullscreen = OMX_FALSE; #else /* define AUTO_FULLSCREEN */ drt.fullscreen = OMX_TRUE; #endif drt.noaspect = OMX_TRUE; drt.mode = OMX_DISPLAY_MODE_FILL; #if !defined(AUTO_FULLSCREEN) /*TODO*/ drt.set = (OMX_DISPLAYSETTYPE) ( OMX_DISPLAY_SET_SRC_RECT | OMX_DISPLAY_SET_DEST_RECT | OMX_DISPLAY_SET_FULLSCREEN | OMX_DISPLAY_SET_NOASPECT); #else drt.set = (OMX_DISPLAYSETTYPE) (OMX_DISPLAY_SET_FULLSCREEN | OMX_DISPLAY_SET_NOASPECT); #endif rc = OMX_SetConfig(ILC_GET_HANDLE(video_render), OMX_IndexConfigDisplayRegion, &drt); assert(rc==0); #endif /* Kick start video decoder */ ilclient_change_component_state(video_decode, OMX_StateIdle); /*TODO Configure decoder */ memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); format.nVersion.nVersion = OMX_VERSION; format.nPortIndex = 130; format.eCompressionFormat = OMX_VIDEO_CodingAVC; rc = OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format); assert(rc == 0); /* Enable video decode */ rc = ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL); assert(rc ==0); /* Kick start video decode */ ilclient_change_component_state(video_decode, OMX_StateExecuting); printf("decoder_hw: initialized"); }
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); }
static int brcm_omx_vc03_play_init(void) { OMX_ERRORTYPE error; OMX_PARAM_PORTDEFINITIONTYPE param; OMX_AUDIO_PARAM_PCMMODETYPE param1; int size; DEBUG("\n %lx:brcm_omx_vc03_play_init\n",jiffies); g_brcm_alsa_chip->pcm_ptr[0] = 0; // playback stuff memset(&st_play,0,sizeof(COMPONENT_T)); error = ilclient_create_component(client, &st_play, "audio_render", 0, 1, 1); ERROR_RETURN("ilclient_create_component",error); ilclient_disable_port(&st_play,101); // memset(¶m, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); param.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); param.nVersion.nVersion = OMX_VERSION; param.nPortIndex = 100; param.nBufferCountActual = 1; param.nBufferSize = g_brcm_alsa_chip->period_bytes[0];//20*AUDIO_SAMPLE*2; param.eDir = OMX_DirInput; param.eDomain = OMX_PortDomainAudio; param.format.audio.eEncoding = OMX_AUDIO_CodingPCM; error = OMX_SetParameter(st_play.comp, OMX_IndexParamPortDefinition, ¶m); ERROR_RETURN("OMX_SetParameter",error); // memset(¶m1, 0, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); param1.nSize = sizeof(OMX_AUDIO_PARAM_PCMMODETYPE); param1.nVersion.nVersion = OMX_VERSION; param1.nPortIndex = 100; param1.nChannels = 2; param1.eEndian = OMX_EndianLittle; param1.bInterleaved = OMX_TRUE; param1.nBitPerSample = 16; //32 param1.nSamplingRate = g_brcm_alsa_chip->rate[0];//8000;//44100; param1.eNumData = OMX_NumericalDataSigned; param1.ePCMMode = OMX_AUDIO_PCMModeLinear; error = OMX_SetParameter(st_play.comp, OMX_IndexParamAudioPcm, ¶m1); ERROR_RETURN("OMX_SetParameter",error); // error = OMX_SendCommand(st_play.comp, OMX_CommandStateSet, OMX_StateIdle, NULL); ERROR_RETURN("OMX_SendCommand",error); // size = g_brcm_alsa_chip->period_bytes[0]; //for(i=0; i<param.nBufferCountActual; i++) //is one enough? { error = OMX_UseBuffer(st_play.comp, &st_play.out_list, 100, st_play.out_list, size, NULL); ERROR_RETURN("OMX_UseBuffer",error); DEBUG("\n playback %lx:st.out_list=%x st.out_list->private=%x\n",jiffies, (int)st_play.out_list,(int)st_play.out_list->pAppPrivate); } // error = ilclient_wait_for_event(&st_play, OMX_EventCmdComplete, OMX_CommandStateSet, 0, OMX_StateIdle, 0, ILCLIENT_STATE_CHANGED, PLATFORM_EVENTGROUP_SUSPEND); ERROR_RETURN("ilclient_wait_for_event",error); // if (alsa_pcm_event & PCM_EVENT_PLAY_START ) { error = ilclient_change_component_state(&st_play, OMX_StateExecuting); ERROR_RETURN("ilclient_change_component_state",error); } return 0; }
// Modified function prototype to work with pthreads void *video_decode_test(void* arg) { const char* filename = "/opt/vc/src/hello_pi/hello_video/test.h264"; eglImage = arg; if (eglImage == 0) { printf("eglImage is null.\n"); exit(1); } OMX_VIDEO_PARAM_PORTFORMATTYPE format; OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; COMPONENT_T *video_decode = NULL, *video_scheduler = NULL, *clock = NULL; COMPONENT_T *list[5]; TUNNEL_T tunnel[4]; ILCLIENT_T *client; FILE *in; int status = 0; unsigned int data_len = 0; int packet_size = 80<<10; memset(list, 0, sizeof(list)); memset(tunnel, 0, sizeof(tunnel)); if((in = fopen(filename, "rb")) == NULL) return (void *)-2; if((client = ilclient_init()) == NULL) { fclose(in); return (void *)-3; } if(OMX_Init() != OMX_ErrorNone) { ilclient_destroy(client); fclose(in); return (void *)-4; } // callback ilclient_set_fill_buffer_done_callback(client, my_fill_buffer_done, 0); // create video_decode if(ilclient_create_component(client, &video_decode, "video_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0) status = -14; list[0] = video_decode; // create video_render //if(status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0) if(status == 0 && ilclient_create_component(client, &video_render, "egl_render", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_OUTPUT_BUFFERS) != 0) status = -14; list[1] = video_render; // create clock if(status == 0 && ilclient_create_component(client, &clock, "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0) status = -14; list[2] = clock; memset(&cstate, 0, sizeof(cstate)); cstate.nSize = sizeof(cstate); cstate.nVersion.nVersion = OMX_VERSION; cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; cstate.nWaitMask = 1; if(clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(clock), OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone) status = -13; // create video_scheduler if(status == 0 && ilclient_create_component(client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0) status = -14; list[3] = video_scheduler; set_tunnel(tunnel, video_decode, 131, video_scheduler, 10); //set_tunnel(tunnel+1, video_scheduler, 11, video_render, 90); set_tunnel(tunnel+1, video_scheduler, 11, video_render, 220); set_tunnel(tunnel+2, clock, 80, video_scheduler, 12); // setup clock tunnel first if(status == 0 && ilclient_setup_tunnel(tunnel+2, 0, 0) != 0) status = -15; else ilclient_change_component_state(clock, OMX_StateExecuting); if(status == 0) ilclient_change_component_state(video_decode, OMX_StateIdle); memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); format.nVersion.nVersion = OMX_VERSION; format.nPortIndex = 130; format.eCompressionFormat = OMX_VIDEO_CodingAVC; if(status == 0 && OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone && ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0) { OMX_BUFFERHEADERTYPE *buf; int port_settings_changed = 0; int first_packet = 1; ilclient_change_component_state(video_decode, OMX_StateExecuting); while((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL) { // feed data and wait until we get port settings changed unsigned char *dest = buf->pBuffer; // loop if at end if (feof(in)) rewind(in); data_len += fread(dest, 1, packet_size-data_len, in); if(port_settings_changed == 0 && ((data_len > 0 && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) || (data_len == 0 && ilclient_wait_for_event(video_decode, OMX_EventPortSettingsChanged, 131, 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_scheduler, OMX_StateExecuting); // now setup tunnel to video_render if(ilclient_setup_tunnel(tunnel+1, 0, 1000) != 0) { status = -12; break; } // Set egl_render to idle ilclient_change_component_state(video_render, OMX_StateIdle); // Enable the output port and tell egl_render to use the texture as a buffer //ilclient_enable_port(video_render, 221); THIS BLOCKS SO CANT BE USED if (OMX_SendCommand(ILC_GET_HANDLE(video_render), OMX_CommandPortEnable, 221, NULL) != OMX_ErrorNone) { printf("OMX_CommandPortEnable failed.\n"); exit(1); } if (OMX_UseEGLImage(ILC_GET_HANDLE(video_render), &eglBuffer, 221, NULL, eglImage) != OMX_ErrorNone) { printf("OMX_UseEGLImage failed.\n"); exit(1); } // Set egl_render to executing ilclient_change_component_state(video_render, OMX_StateExecuting); // Request egl_render to write data to the texture buffer if(OMX_FillThisBuffer(ILC_GET_HANDLE(video_render), eglBuffer) != OMX_ErrorNone) { printf("OMX_FillThisBuffer failed.\n"); exit(1); } } if(!data_len) break; buf->nFilledLen = data_len; data_len = 0; buf->nOffset = 0; if(first_packet) { buf->nFlags = OMX_BUFFERFLAG_STARTTIME; first_packet = 0; } else buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) { status = -6; break; } } buf->nFilledLen = 0; buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS; if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != 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); // need to flush the renderer to allow video_decode to disable its input port ilclient_flush_tunnels(tunnel, 0); ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL); } fclose(in); ilclient_disable_tunnel(tunnel); ilclient_disable_tunnel(tunnel+1); ilclient_disable_tunnel(tunnel+2); ilclient_teardown_tunnels(tunnel); ilclient_state_transition(list, OMX_StateIdle); ilclient_state_transition(list, OMX_StateLoaded); ilclient_cleanup_components(list); OMX_Deinit(); ilclient_destroy(client); return (void *)status; }
int32_t ilctts_create( TTSRENDER_STATE_T **component, uint32_t sample_rate, uint32_t num_channels, uint32_t bit_depth, uint32_t num_buffers, uint32_t buffer_size_ms, BUFFER_SIZE_TYPE_T buffer_size_type, uint32_t ringbuffer_length ) { ENTER(LOGLEVEL_1, "ilctts_create"); SHOW(LOGLEVEL_5, "Sample rate: %d", sample_rate); SHOW(LOGLEVEL_5, "Number of channels: %d", num_channels); SHOW(LOGLEVEL_5, "Bit depth: %d", bit_depth); SHOW(LOGLEVEL_5, "Number of buffers: %d", num_buffers); SHOW(LOGLEVEL_5, "Buffer size: %d", buffer_size_ms); SHOW(LOGLEVEL_5, "Ring buffer length: %d", ringbuffer_length); int32_t ret; uint32_t buffer_size; OMX_ERRORTYPE omx_err; TTSRENDER_STATE_T *st; *component = NULL; st = calloc(1, sizeof(TTSRENDER_STATE_T)); OMX_PARAM_PORTDEFINITIONTYPE param; OMX_AUDIO_PARAM_PCMMODETYPE pcm; int32_t s; *component = st; // create and start up everything // initialise buffer list semaphore s = sem_init(&st->buffer_list_sema, 0, 1); if (s < 0) { ERROR("sem_init returned error initializing buffer list semaphore in ilctts_create: %d", s); return -1; } // initial value of ringbuffer_empty_sema is 1 because at startup there is space s = sem_init(&st->ringbuffer_empty_sema, 0, 1); if (s < 0) { ERROR("sem_init returned error initializing ringbuffer_empty_sema in ilctts_create: %d", s); return -1; } // initial value of ringbuffer_data_sema is 0 because at startup there is no data s = sem_init(&st->ringbuffer_data_sema, 0, 0); if (s < 0) { ERROR("sem_init returned error initializing ringbuffer_data_sema in ilctts_create: %d", s); return -1; } // free_buffer mutex and cv pthread_mutex_init(&st->free_buffer_mutex, NULL); pthread_cond_init(&st->free_buffer_cv, NULL); // ringbuffer mutex pthread_mutex_init(&st->ringbuffer_mutex, NULL); //pthread_cond_init(&st->ringbuffer_cv, NULL); st->sample_rate = sample_rate; st->num_channels = num_channels; st->bit_depth = bit_depth; st->bytes_per_sample = (bit_depth * OUT_CHANNELS(num_channels)) >> 3; if (buffer_size_type == BS_MILLISECONDS) { // supplied buffer size was in milliseconds, calculate the byte size // note: calc_buffer_size_from_ms returns buffer size aligned for VCHI buffer_size = calc_buffer_size_from_ms(sample_rate, bit_depth, num_channels, buffer_size_ms, 1); } else { // supplied buffer size was in bytes // buffer size must be 16 byte aligned for VCHI buffer_size = (buffer_size_ms + 15) & ~15; } SHOW(LOGLEVEL_5, "Bytes per sample: %d", st->bytes_per_sample); SHOW(LOGLEVEL_5, "Calculated buffer size: %d", buffer_size); st->num_buffers = num_buffers; st->client = ilclient_init(); st->tts_stop = 0; st->tts_pause_state = TTS_PAUSE_OFF; st->ringbuffer = ringbuffer_init(ringbuffer_length); if (st->ringbuffer == NULL) { ERROR("ringbuffer_init failed in ilctts_create", ""); return -1; } // set up callbacks ilclient_set_empty_buffer_done_callback(st->client, input_buffer_callback, st); //ilclient_set_configchanged_callback(st->client, config_changed_callback, st); //ilclient_set_port_settings_callback(st->client, port_settings_changed_callback, st); ret = ilclient_create_component(st->client, &st->audio_render, "audio_render", ILCLIENT_ENABLE_INPUT_BUFFERS | ILCLIENT_DISABLE_ALL_PORTS); if (ret == -1) { ERROR("ilclcient_create_component returned error in ilctts_create: %d", ret); return ret; } st->list[0] = st->audio_render; // set up the number/size of buffers OMX_INIT_STRUCTURE(param); param.nPortIndex = 100; omx_err = OMX_GetParameter(ILC_GET_HANDLE(st->audio_render), OMX_IndexParamPortDefinition, ¶m); if (omx_err != OMX_ErrorNone) { ERROR("OMX_GetParameter returned error in ilctts_create: %d", omx_err); return -1; } // set the buffer size to the requested size, or the minimum size returned, whichever is greater st->buffer_size = max(buffer_size, param.nBufferSize); SHOW(LOGLEVEL_3, "Buffer size set to: %d", st->buffer_size); param.nBufferSize = st->buffer_size; param.nBufferCountActual = max(st->buffer_count, param.nBufferCountMin); omx_err = OMX_SetParameter(ILC_GET_HANDLE(st->audio_render), OMX_IndexParamPortDefinition, ¶m); if (omx_err != OMX_ErrorNone) { ERROR("OMX_SetParameter returned error in ilctts_create: %d", omx_err); return -1; } // set the pcm parameters OMX_INIT_STRUCTURE(pcm); pcm.nPortIndex = 100; pcm.nChannels = OUT_CHANNELS(num_channels); pcm.eNumData = OMX_NumericalDataSigned; pcm.eEndian = OMX_EndianLittle; pcm.nSamplingRate = sample_rate; pcm.bInterleaved = OMX_TRUE; pcm.nBitPerSample = bit_depth; pcm.ePCMMode = OMX_AUDIO_PCMModeLinear; switch(st->num_channels) { case 1: pcm.eChannelMapping[0] = OMX_AUDIO_ChannelCF; break; case 3: pcm.eChannelMapping[2] = OMX_AUDIO_ChannelCF; pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF; pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF; break; case 8: pcm.eChannelMapping[7] = OMX_AUDIO_ChannelRS; case 7: pcm.eChannelMapping[6] = OMX_AUDIO_ChannelLS; case 6: pcm.eChannelMapping[5] = OMX_AUDIO_ChannelRR; case 5: pcm.eChannelMapping[4] = OMX_AUDIO_ChannelLR; case 4: pcm.eChannelMapping[3] = OMX_AUDIO_ChannelLFE; pcm.eChannelMapping[2] = OMX_AUDIO_ChannelCF; case 2: pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF; pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF; break; } omx_err = OMX_SetParameter(ILC_GET_HANDLE(st->audio_render), OMX_IndexParamAudioPcm, &pcm); if (omx_err != OMX_ErrorNone) { ERROR("OMX_SetParameter returned error in ilctts_create: %d", omx_err); return -1; } // this function waits for the command to complete ret = ilclient_change_component_state(st->audio_render, OMX_StateIdle); if (ret < 0) { ERROR("ilctts_change_component_state returned error in ilctts_create: %d", ret); return -1; } ret = ilclient_enable_port_buffers(st->audio_render, 100, NULL, NULL, NULL); if (ret < 0) { ERROR("ilclient_enable_port_buffers returned error in ilctts_create: %d", ret); ilclient_change_component_state(st->audio_render, OMX_StateLoaded); ilclient_cleanup_components(st->list); omx_err = OMX_Deinit(); ilclient_destroy(st->client); destroy_semaphores(st); destroy_mutexes(st); ringbuffer_destroy(st->ringbuffer); // need to destroy and free other stuff here? free(st); *component = NULL; return -1; } INFO(LOGLEVEL_1, "Setting state to executing in ilctts_create"); return ilclient_change_component_state(st->audio_render, OMX_StateExecuting); } // end ilctts_create