int portSettingsChangedAgain(OPENMAX_JPEG_DECODER * decoder) { printf("Port settings changed again\n"); ilclient_disable_port(decoder->imageDecoder->component, decoder->imageDecoder->outPort); OMX_PARAM_PORTDEFINITIONTYPE portdef; // need to setup the input for the render with the output of the // decoder portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion.nVersion = OMX_VERSION; portdef.nPortIndex = decoder->imageDecoder->outPort; OMX_GetParameter(decoder->imageDecoder->handle, OMX_IndexParamPortDefinition, &portdef); // enable output of decoder and input of render (ie enable tunnel) ilclient_enable_port(decoder->imageDecoder->component, decoder->imageDecoder->outPort); // need to wait for this event ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventPortSettingsChanged, decoder->imageDecoder->outPort, 1, 0, 0, 0, TIMEOUT_MS); return OMXJPEG_OK; }
int startupImageRender(OPENMAX_JPEG_DECODER * decoder) { int ret; // We don't set any buffers - just change states // move to idle ilclient_change_component_state(decoder->imageRender->component, OMX_StateIdle); ret = ilclient_wait_for_event(decoder->imageRender->component, OMX_EventCmdComplete, OMX_StateIdle, 0, 0, 1, 0, TIMEOUT_MS); if (ret != 0) { fprintf(stderr, "Did not receive idle stat %d\n", ret); // return OMXJPEG_ERROR_EXECUTING; } else { printf("Render now in idle state\n"); } // start executing the render ret = OMX_SendCommand(decoder->imageRender->handle, OMX_CommandStateSet, OMX_StateExecuting, NULL); if (ret != 0) { fprintf(stderr, "Error starting image render %x\n", ret); return OMXJPEG_ERROR_EXECUTING; } ret = ilclient_wait_for_event(decoder->imageRender->component, OMX_EventCmdComplete, OMX_StateExecuting, 0, 0, 1, 0, TIMEOUT_MS); if (ret != 0) { fprintf(stderr, "Did not receive executing stat %d\n", ret); // return OMXJPEG_ERROR_EXECUTING; } else { printf("Render now in executing state\n"); } return OMXJPEG_OK; }
static int startupDecoder(JPEG_DECODER * decoder){ ilclient_change_component_state(decoder->component,OMX_StateIdle); OMX_IMAGE_PARAM_PORTFORMATTYPE imagePortFormat; memset(&imagePortFormat, 0, sizeof(OMX_IMAGE_PARAM_PORTFORMATTYPE)); imagePortFormat.nSize = sizeof(OMX_IMAGE_PARAM_PORTFORMATTYPE); imagePortFormat.nVersion.nVersion = OMX_VERSION; imagePortFormat.nPortIndex = decoder->inPort; imagePortFormat.eCompressionFormat = OMX_IMAGE_CodingJPEG; OMX_SetParameter(decoder->handle,OMX_IndexParamImagePortFormat, &imagePortFormat); OMX_PARAM_PORTDEFINITIONTYPE portdef; portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion.nVersion = OMX_VERSION; portdef.nPortIndex = decoder->inPort; OMX_GetParameter(decoder->handle,OMX_IndexParamPortDefinition, &portdef); portdef.nBufferCountActual = DECODER_BUFFER_NUM; OMX_SetParameter(decoder->handle,OMX_IndexParamPortDefinition, &portdef); OMX_SendCommand(decoder->handle, OMX_CommandPortEnable, decoder->inPort, NULL); int i; for (i = 0; i < DECODER_BUFFER_NUM; i++) { if (OMX_AllocateBuffer(decoder->handle, &(decoder->ppInputBufferHeader[i]), decoder->inPort, NULL, portdef.nBufferSize) != OMX_ErrorNone) { return OMX_IMAGE_ERROR_MEMORY; } } int ret = ilclient_wait_for_event(decoder->component, OMX_EventCmdComplete, OMX_CommandPortEnable, 0, decoder->inPort, 0, 0, TIMEOUT_MS); if (ret != 0) { return OMX_IMAGE_ERROR_PORTS; } ret = OMX_SendCommand(decoder->handle, OMX_CommandStateSet, OMX_StateExecuting, NULL); if (ret != OMX_ErrorNone) { return OMX_IMAGE_ERROR_EXECUTING; } return OMX_IMAGE_OK; }
// this function passed the jpeg image buffer in, and returns the decoded // image int decodeImage(OPENMAX_JPEG_DECODER * decoder, char *sourceImage, size_t imageSize) { char *sourceOffset = sourceImage; // we store a seperate // buffer ot image so we // can offset it size_t toread = 0; // bytes left to read from buffer toread += imageSize; int bFilled = 0; // have we filled our output // buffer bufferIndex = 0; while (toread > 0) { // get next buffer from array OMX_BUFFERHEADERTYPE *pBufHeader = decoder->ppInputBufferHeader[bufferIndex]; // step index and reset to 0 if required bufferIndex++; if (bufferIndex >= decoder->inputBufferHeaderCount) bufferIndex = 0; // work out the next chunk to load into the decoder if (toread > pBufHeader->nAllocLen) pBufHeader->nFilledLen = pBufHeader->nAllocLen; else pBufHeader->nFilledLen = toread; toread = toread - pBufHeader->nFilledLen; // pass the bytes to the buffer memcpy(pBufHeader->pBuffer, sourceOffset, pBufHeader->nFilledLen); printf("Read into buffer %d\n", pBufHeader->nFilledLen); // update the buffer pointer and set the input flags sourceOffset = sourceOffset + pBufHeader->nFilledLen; pBufHeader->nOffset = 0; pBufHeader->nFlags = 0; if (toread <= 0) { pBufHeader->nFlags = OMX_BUFFERFLAG_EOS; printf("Added EOS to last inout buffer\n"); } // empty the current buffer printf("Emptying buffer\n"); int ret = OMX_EmptyThisBuffer(decoder->imageDecoder->handle, pBufHeader); if (ret != OMX_ErrorNone) { perror("Empty input buffer"); fprintf(stderr, "return code %x\n", ret); return OMXJPEG_ERROR_MEMORY; } // wait for buffer to empty or port changed event int done = 0; while ((done == 0) || (decoder->pOutputBufferHeader == NULL)) { if (decoder->pOutputBufferHeader == NULL) { ret = ilclient_wait_for_event (decoder->imageDecoder->component, OMX_EventPortSettingsChanged, decoder->imageDecoder->outPort, 0, 0, 1, 0, 5); if (ret == 0) { portSettingsChanged(decoder); } } else { ret = ilclient_remove_event(decoder->imageDecoder->component, OMX_EventPortSettingsChanged, decoder->imageDecoder->outPort, 0, 0, 1); if (ret == 0) portSettingsChangedAgain(decoder); } // check to see if buffer is now empty if (pBufHeader->nFilledLen == 0) done = 1; if ((done == 0) || (decoder->pOutputBufferHeader == NULL)) { printf("Buffer is now size %d\n", pBufHeader->nFilledLen); sleep(1); } } // fill the buffer if we have created the buffer if (bFilled == 0) { if ((decoder->pOutputBufferHeader == NULL)) { portSettingsChanged(decoder); } OMX_PARAM_U32TYPE param; param.nSize = sizeof(OMX_PARAM_U32TYPE); param.nVersion.nVersion = OMX_VERSION; param.nPortIndex = decoder->imageDecoder->outPort; OMX_GetParameter(decoder->imageDecoder->handle, OMX_IndexParamActiveStream, ¶m); printf("Active stream %d\n", param.nU32); printf("Trying to fill output buffer\n"); printState(decoder->imageDecoder->handle); ret = OMX_FillThisBuffer(decoder->imageDecoder->handle, decoder->pOutputBufferHeader); if (ret != OMX_ErrorNone) { perror("Filling output buffer"); fprintf(stderr, "Error code %x\n", ret); return OMXJPEG_ERROR_MEMORY; } bFilled = 1; } } // wait for buffer to fill /* * while(pBufHeader->nFilledLen == 0) { sleep(5); } */ // wait for end of stream events int ret = ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventBufferFlag, decoder->imageDecoder->outPort, 1, OMX_BUFFERFLAG_EOS, 1, 0, 2); if (ret != 0) { fprintf(stderr, "No EOS event on image decoder %d\n", ret); } else { fprintf(stderr, "EOS event on image decoder %d\n", ret); } printf("Resized %d\n", decoder->pOutputBufferHeader->nFilledLen); FILE *fp = fopen("out", "w"); int n; for (n = 0; n < decoder->pOutputBufferHeader->nFilledLen; n++) { //fputc(decoder->pOutputBufferHeader->pBuffer[n], fp); fputc(decoder->ppRenderInputBufferHeader[0]->pBuffer[n], fp); } fclose(fp); printf("File written\n"); renderImage(decoder); return OMXJPEG_OK; }
int startupImageDecoder(OPENMAX_JPEG_DECODER * decoder) { // move to idle ilclient_change_component_state(decoder->imageDecoder->component, OMX_StateIdle); // set input image format OMX_IMAGE_PARAM_PORTFORMATTYPE imagePortFormat; memset(&imagePortFormat, 0, sizeof(OMX_IMAGE_PARAM_PORTFORMATTYPE)); imagePortFormat.nSize = sizeof(OMX_IMAGE_PARAM_PORTFORMATTYPE); imagePortFormat.nVersion.nVersion = OMX_VERSION; imagePortFormat.nPortIndex = decoder->imageDecoder->inPort; imagePortFormat.eCompressionFormat = OMX_IMAGE_CodingJPEG; OMX_SetParameter(decoder->imageDecoder->handle, OMX_IndexParamImagePortFormat, &imagePortFormat); // get buffer requirements OMX_PARAM_PORTDEFINITIONTYPE portdef; portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion.nVersion = OMX_VERSION; portdef.nPortIndex = decoder->imageDecoder->inPort; OMX_GetParameter(decoder->imageDecoder->handle, OMX_IndexParamPortDefinition, &portdef); // enable the port and setup the buffers OMX_SendCommand(decoder->imageDecoder->handle, OMX_CommandPortEnable, decoder->imageDecoder->inPort, NULL); decoder->inputBufferHeaderCount = portdef.nBufferCountActual; // allocate pointer array decoder->ppInputBufferHeader = (OMX_BUFFERHEADERTYPE **) malloc(sizeof(void) * decoder->inputBufferHeaderCount); // allocate each buffer int i; for (i = 0; i < decoder->inputBufferHeaderCount; i++) { if (OMX_AllocateBuffer(decoder->imageDecoder->handle, &decoder->ppInputBufferHeader[i], decoder->imageDecoder->inPort, (void *) i, portdef.nBufferSize) != OMX_ErrorNone) { perror("Allocate decode buffer"); return OMXJPEG_ERROR_MEMORY; } } // wait for port enable to complete - which it should once buffers are // assigned int ret = ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventCmdComplete, OMX_CommandPortEnable, 0, decoder->imageDecoder->inPort, 0, 0, TIMEOUT_MS); if (ret != 0) { fprintf(stderr, "Did not get port enable %d\n", ret); return OMXJPEG_ERROR_EXECUTING; } else { printf("Ddecoder input port enabled after buffers allocated\n"); } ret = ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventCmdComplete, OMX_StateIdle, 0, 0, 1, 0, TIMEOUT_MS); if (ret != 0) { fprintf(stderr, "Did not receive executing stat %d\n", ret); // return OMXJPEG_ERROR_EXECUTING; } else { printf("Decoder now in idle state\n"); } // start executing the decoder ret = OMX_SendCommand(decoder->imageDecoder->handle, OMX_CommandStateSet, OMX_StateExecuting, NULL); if (ret != 0) { fprintf(stderr, "Error starting image decoder %x\n", ret); return OMXJPEG_ERROR_EXECUTING; } ret = ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventCmdComplete, OMX_StateExecuting, 0, 0, 1, 0, TIMEOUT_MS); if (ret != 0) { fprintf(stderr, "Did not receive executing stat %d\n", ret); // return OMXJPEG_ERROR_EXECUTING; } return OMXJPEG_OK; }
int portSettingsChanged(OPENMAX_JPEG_DECODER * decoder) { OMX_PARAM_PORTDEFINITIONTYPE portdef, rportdef;; int ret; // CLEANUP printf("Pport settings changed\n"); // need to setup the input for the render with the output of the // decoder portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion.nVersion = OMX_VERSION; portdef.nPortIndex = decoder->imageDecoder->outPort; OMX_GetParameter(decoder->imageDecoder->handle, OMX_IndexParamPortDefinition, &portdef); // Get default values of render rportdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); rportdef.nVersion.nVersion = OMX_VERSION; rportdef.nPortIndex = decoder->imageRender->inPort; rportdef.nBufferSize = portdef.nBufferSize; ret = OMX_GetParameter(decoder->imageRender->handle, OMX_IndexParamPortDefinition, &rportdef); if (ret != OMX_ErrorNone) { fprintf(stderr, "Error getting render port params %s\n", err2str(ret)); return OMXJPEG_ERROR_MEMORY; } // 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; ret = OMX_SetParameter(decoder->imageRender->handle, OMX_IndexParamPortDefinition, &rportdef); if (ret != OMX_ErrorNone) { fprintf(stderr, "Error setting render port params %s\n", err2str(ret)); return OMXJPEG_ERROR_MEMORY; } else { printf("Render port params set up ok\n"); } unsigned int uWidth = (unsigned int) portdef.format.image.nFrameWidth; unsigned int uHeight = (unsigned int) portdef.format.image.nFrameHeight; printf ("Getting format Compression 0x%x Color Format: 0x%x\n", (unsigned int) portdef.format.image.eCompressionFormat, (unsigned int) portdef.format.image.eColorFormat); printColorFormat(portdef.format.image.eColorFormat); // enable ports OMX_SendCommand(decoder->imageDecoder->handle, OMX_CommandPortEnable, decoder->imageDecoder->outPort, NULL); // once the state changes, both ports should become enabled and the // render // output should generate a settings changed event ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventCmdComplete, OMX_CommandPortEnable, 1, decoder->imageDecoder->outPort, 1, 0, TIMEOUT_MS); printf("Decoder output port enabled\n"); OMX_SendCommand(decoder->imageRender->handle, OMX_CommandPortEnable, decoder->imageRender->inPort, NULL); // once the state changes, both ports should become enabled and the // render // output should generate a settings changed event ilclient_wait_for_event(decoder->imageRender->component, OMX_EventCmdComplete, OMX_CommandPortEnable, 1, decoder->imageRender->inPort, 1, 0, TIMEOUT_MS); printf("Render input port enabled\n"); ret = OMX_AllocateBuffer(decoder->imageDecoder->handle, &decoder->pOutputBufferHeader, decoder->imageDecoder-> outPort, NULL, portdef.nBufferSize); printf("Output port buffer allocated\n"); if (ret != OMX_ErrorNone) { perror("Eror allocating buffer"); return OMXJPEG_ERROR_MEMORY; } // and share it with the renderer // which has 3 default buffers, 2 minimum decoder->ppRenderInputBufferHeader = (OMX_BUFFERHEADERTYPE **) malloc(sizeof(void) * decoder->renderInputBufferHeaderCount); printState(decoder->imageRender->handle); decoder->imageRender->inPort, ret = OMX_UseBuffer(decoder->imageRender->handle, &decoder->ppRenderInputBufferHeader[0], decoder->imageRender->inPort, NULL, rportdef.nBufferSize, decoder->pOutputBufferHeader->pBuffer); if (ret != OMX_ErrorNone) { fprintf(stderr, "Eror sharing buffer %s\n", err2str(ret)); return OMXJPEG_ERROR_MEMORY; } decoder->ppRenderInputBufferHeader[0]->nAllocLen = decoder->pOutputBufferHeader->nAllocLen; int n; for (n = 1; n < decoder->renderInputBufferHeaderCount; n++) { printState(decoder->imageRender->handle); ret = OMX_UseBuffer(decoder->imageRender->handle, &decoder->ppRenderInputBufferHeader[n], decoder->imageRender->inPort, NULL, 0, NULL); if (ret != OMX_ErrorNone) { fprintf(stderr, "Eror sharing null buffer %s\n", err2str(ret)); return OMXJPEG_ERROR_MEMORY; } } ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventCmdComplete, OMX_CommandPortEnable, 1, decoder->imageDecoder->outPort, 1, 0, TIMEOUT_MS); printf("Decoder output port rnabled\n"); 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 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; }
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; }
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; }
static int doResize(OMX_RESIZER *resizer, IMAGE *inImage, IMAGE *outImage){ int retVal= OMX_IMAGE_OK; OMX_BUFFERHEADERTYPE *pBufHeader = resizer->pInputBufferHeader; pBufHeader->nFilledLen=inImage->nData; pBufHeader->nFlags = OMX_BUFFERFLAG_EOS; int ret = OMX_EmptyThisBuffer(resizer->handle, pBufHeader); if (ret != OMX_ErrorNone) { retVal |= OMX_IMAGE_ERROR_MEMORY; } if(ilclient_wait_for_event(resizer->component,OMX_EventPortSettingsChanged,resizer->outPort, 0, 0, 1, ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, TIMEOUT_MS) == 0){ destroyImage(inImage); retVal|= resizePortSettingsChanged(resizer, outImage); if(retVal == OMX_IMAGE_OK){ if (OMX_FillThisBuffer(resizer->handle, resizer->pOutputBufferHeader) != OMX_ErrorNone) { retVal|=OMX_IMAGE_ERROR_MEMORY; } } } if(ilclient_wait_for_event(resizer->component, OMX_EventBufferFlag, resizer->outPort, 0, OMX_BUFFERFLAG_EOS, 0, ILCLIENT_BUFFER_FLAG_EOS, TIMEOUT_MS) != 0){ retVal|= OMX_IMAGE_ERROR_NO_EOS; } ret= OMX_FreeBuffer(resizer->handle, resizer->inPort, resizer->pInputBufferHeader); if(ret!= OMX_ErrorNone){ retVal|=OMX_IMAGE_ERROR_MEMORY; } ret = OMX_SendCommand(resizer->handle, OMX_CommandPortDisable, resizer->inPort, NULL); if(ret!= OMX_ErrorNone){ retVal |= OMX_IMAGE_ERROR_PORTS; } ilclient_wait_for_event(resizer->component, OMX_EventCmdComplete, OMX_CommandPortDisable, 0, resizer->inPort, 0, ILCLIENT_PORT_DISABLED, TIMEOUT_MS); OMX_SendCommand(resizer->handle, OMX_CommandFlush, resizer->outPort, NULL); ilclient_wait_for_event(resizer->component,OMX_EventCmdComplete, OMX_CommandFlush, 0, resizer->outPort, 0, ILCLIENT_PORT_FLUSH ,TIMEOUT_MS); ret= OMX_FreeBuffer(resizer->handle, resizer->outPort, resizer->pOutputBufferHeader); if(ret!= OMX_ErrorNone){ retVal|=OMX_IMAGE_ERROR_MEMORY; } ret= OMX_SendCommand(resizer->handle, OMX_CommandPortDisable, resizer->outPort, NULL); if(ret!= OMX_ErrorNone){ retVal|=OMX_IMAGE_ERROR_PORTS; } ilclient_change_component_state(resizer->component, OMX_StateIdle); ilclient_change_component_state(resizer->component, OMX_StateLoaded); return retVal; }
static int decodeJpeg(JPEG_DECODER * decoder, FILE *sourceImage, IMAGE *jpeg){ char pSettingsChanged = 0, end = 0, eos = 0, bFilled = 0; int bufferIndex = 0; int retVal = OMX_IMAGE_OK; struct timespec wait; OMX_BUFFERHEADERTYPE *pBufHeader = decoder->ppInputBufferHeader[bufferIndex]; ilclient_set_empty_buffer_done_callback(decoder->client, emptyBufferDone, decoder); bufferIndex^=1; pBufHeader->nFilledLen = fread(pBufHeader->pBuffer, 1, pBufHeader->nAllocLen, sourceImage); pBufHeader->nOffset = 0; pBufHeader->nFlags = 0; if(feof(sourceImage)){ pBufHeader->nFlags = OMX_BUFFERFLAG_EOS; }else if( pBufHeader->nFilledLen != pBufHeader->nAllocLen){ retVal|=OMX_IMAGE_ERROR_READING; end=1; } pthread_mutex_init(&decoder->lock, NULL); pthread_cond_init(&decoder->cond, NULL); while(end == 0 && retVal == OMX_IMAGE_OK){ decoder->emptyBDone=0; // We've got an eos event early this usually means that we are done decoding if(ilclient_remove_event(decoder->component, OMX_EventBufferFlag, decoder->outPort, 0, OMX_BUFFERFLAG_EOS, 0 )==0){ eos=1; break; } int ret = OMX_EmptyThisBuffer(decoder->handle, pBufHeader); if (ret != OMX_ErrorNone) { retVal|=OMX_IMAGE_ERROR_MEMORY; break; } if(!feof(sourceImage)){ pBufHeader = decoder->ppInputBufferHeader[bufferIndex]; bufferIndex^=1; pBufHeader->nFilledLen = fread(pBufHeader->pBuffer, 1, pBufHeader->nAllocLen, sourceImage); pBufHeader->nOffset = 0; pBufHeader->nFlags = 0; if(feof(sourceImage)){ pBufHeader->nFlags = OMX_BUFFERFLAG_EOS; }else if( pBufHeader->nFilledLen != pBufHeader->nAllocLen){ retVal|=OMX_IMAGE_ERROR_READING; break; } }else{ end=1; } if(pSettingsChanged == 0 && ilclient_remove_event(decoder->component, OMX_EventPortSettingsChanged, decoder->outPort, 0, 0, 1 ) == 0){ pSettingsChanged=1; retVal|=portSettingsChanged(decoder, jpeg); } if(!decoder->emptyBDone){ clock_gettime(CLOCK_REALTIME, &wait); wait.tv_nsec += MAX_EMPTY_BUFFER_WAIT_MS*1000000L; wait.tv_sec += wait.tv_nsec/1000000000L; wait.tv_nsec %= 1000000000L; if(!decoder->emptyBDone){ decoder->emptyBDone=2; pthread_mutex_lock(&decoder->lock); pthread_cond_timedwait(&decoder->cond, &decoder->lock, &wait); pthread_mutex_unlock(&decoder->lock); } } if(pSettingsChanged == 0 && ilclient_wait_for_event(decoder->component, OMX_EventPortSettingsChanged,decoder->outPort, 0, 0, 1, ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 10) == 0){ pSettingsChanged=1; retVal|=portSettingsChanged(decoder, jpeg); } if (bFilled == 0 && pSettingsChanged==1 && retVal == OMX_IMAGE_OK) { ret = OMX_FillThisBuffer(decoder->handle, decoder->pOutputBufferHeader); if (ret != OMX_ErrorNone) { retVal|=OMX_IMAGE_ERROR_MEMORY; break; } bFilled = 1; } } ilclient_set_empty_buffer_done_callback(decoder->client, NULL, NULL); if( bFilled == 1 && !eos && ilclient_wait_for_event(decoder->component, OMX_EventBufferFlag, decoder->outPort, 0, OMX_BUFFERFLAG_EOS, 0, ILCLIENT_BUFFER_FLAG_EOS, TIMEOUT_MS) != 0 ){ retVal|=OMX_IMAGE_ERROR_NO_EOS; } pthread_mutex_destroy(&decoder->lock); pthread_cond_destroy(&decoder->cond); int i = 0; for (i = 0; i < DECODER_BUFFER_NUM; i++) { int ret = OMX_FreeBuffer(decoder->handle,decoder->inPort, decoder->ppInputBufferHeader[i]); if(ret!= OMX_ErrorNone){ retVal|=OMX_IMAGE_ERROR_MEMORY; } } int ret=OMX_SendCommand(decoder->handle, OMX_CommandPortDisable, decoder->inPort, NULL); if(ret!= OMX_ErrorNone){ retVal|=OMX_IMAGE_ERROR_PORTS; } ilclient_wait_for_event(decoder->component, OMX_EventCmdComplete, OMX_CommandPortDisable, 0, decoder->inPort, 0, ILCLIENT_PORT_DISABLED, TIMEOUT_MS); if(bFilled==1){ OMX_SendCommand(decoder->handle, OMX_CommandFlush, decoder->outPort, NULL); ilclient_wait_for_event(decoder->component,OMX_EventCmdComplete, OMX_CommandFlush, 0, decoder->outPort, 0, ILCLIENT_PORT_FLUSH ,TIMEOUT_MS); ret= OMX_FreeBuffer(decoder->handle, decoder->outPort, decoder->pOutputBufferHeader); if(ret!= OMX_ErrorNone){ retVal|=OMX_IMAGE_ERROR_MEMORY; } } if(pSettingsChanged==1){ ret= OMX_SendCommand(decoder->handle, OMX_CommandPortDisable, decoder->outPort, NULL); if(ret!= OMX_ErrorNone){ retVal|=OMX_IMAGE_ERROR_PORTS; } } ilclient_change_component_state(decoder->component, OMX_StateIdle); ilclient_change_component_state(decoder->component, OMX_StateLoaded); return retVal; }
int portSettingsChanged(OPENMAX_JPEG_DECODER * decoder) { OMX_PARAM_PORTDEFINITIONTYPE portdef; // need to setup the input for the resizer with the output of the // decoder portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion.nVersion = OMX_VERSION; portdef.nPortIndex = decoder->imageDecoder->outPort; OMX_GetParameter(decoder->imageDecoder->handle, OMX_IndexParamPortDefinition, &portdef); unsigned int uWidth = (unsigned int) portdef.format.image.nFrameWidth; unsigned int uHeight = (unsigned int) portdef.format.image.nFrameHeight; // tell resizer input what the decoder output will be providing portdef.nPortIndex = decoder->imageResizer->inPort; OMX_SetParameter(decoder->imageResizer->handle, OMX_IndexParamPortDefinition, &portdef); // establish tunnel between decoder output and resizer input OMX_SetupTunnel(decoder->imageDecoder->handle, decoder->imageDecoder->outPort, decoder->imageResizer->handle, decoder->imageResizer->inPort); // enable ports OMX_SendCommand(decoder->imageDecoder->handle, OMX_CommandPortEnable, decoder->imageDecoder->outPort, NULL); OMX_SendCommand(decoder->imageResizer->handle, OMX_CommandPortEnable, decoder->imageResizer->inPort, NULL); // put resizer in idle state (this allows the outport of the decoder // to become enabled) OMX_SendCommand(decoder->imageResizer->handle, OMX_CommandStateSet, OMX_StateIdle, NULL); // wait for state change complete ilclient_wait_for_event(decoder->imageResizer->component, OMX_EventCmdComplete, OMX_CommandStateSet, 1, OMX_StateIdle, 1, 0, TIMEOUT_MS); // once the state changes, both ports should become enabled and the // resizer // output should generate a settings changed event ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventCmdComplete, OMX_CommandPortEnable, 1, decoder->imageDecoder->outPort, 1, 0, TIMEOUT_MS); ilclient_wait_for_event(decoder->imageResizer->component, OMX_EventCmdComplete, OMX_CommandPortEnable, 1, decoder->imageResizer->inPort, 1, 0, TIMEOUT_MS); ilclient_wait_for_event(decoder->imageResizer->component, OMX_EventPortSettingsChanged, decoder->imageResizer->outPort, 1, 0, 1, 0, TIMEOUT_MS); ilclient_disable_port(decoder->imageResizer->component, decoder->imageResizer->outPort); // query output buffer requirements for resizer portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion.nVersion = OMX_VERSION; portdef.nPortIndex = decoder->imageResizer->outPort; OMX_GetParameter(decoder->imageResizer->handle, OMX_IndexParamPortDefinition, &portdef); // change output color format and dimensions to match input portdef.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused; portdef.format.image.eColorFormat = OMX_COLOR_Format32bitABGR8888; portdef.format.image.nFrameWidth = uWidth; portdef.format.image.nFrameHeight = uHeight; portdef.format.image.nStride = 0; portdef.format.image.nSliceHeight = 0; portdef.format.image.bFlagErrorConcealment = OMX_FALSE; OMX_SetParameter(decoder->imageResizer->handle, OMX_IndexParamPortDefinition, &portdef); // grab output requirements again to get actual buffer size // requirement (and buffer count requirement!) OMX_GetParameter(decoder->imageResizer->handle, OMX_IndexParamPortDefinition, &portdef); // move resizer into executing state ilclient_change_component_state(decoder->imageResizer->component, OMX_StateExecuting); // show some logging so user knows it's working printf ("Width: %u Height: %u Output Color Format: 0x%x Buffer Size: %u\n", (unsigned int) portdef.format.image.nFrameWidth, (unsigned int) portdef.format.image.nFrameHeight, (unsigned int) portdef.format.image.eColorFormat, (unsigned int) portdef.nBufferSize); fflush(stdout); // enable output port of resizer OMX_SendCommand(decoder->imageResizer->handle, OMX_CommandPortEnable, decoder->imageResizer->outPort, NULL); // allocate the buffer // void* outputBuffer = 0; // if (posix_memalign(&outputBuffer, portdef.nBufferAlignment, // portdef.nBufferSize) != 0) // { // perror("Allocating output buffer"); // return OMXJPEG_ERROR_MEMORY; // } // set the buffer // int ret = OMX_UseBuffer(decoder->imageResizer->handle, // &decoder->pOutputBufferHeader, // decoder->imageResizer->outPort, NULL, // portdef.nBufferSize, // (OMX_U8 *) outputBuffer); int ret = OMX_AllocateBuffer(decoder->imageResizer->handle, &decoder->pOutputBufferHeader, decoder->imageResizer-> outPort, NULL, portdef.nBufferSize); if (ret != OMX_ErrorNone) { perror("Eror allocating buffer"); fprintf(stderr, "OMX_AllocateBuffer returned 0x%x allocating buffer size 0x%x\n", ret, portdef.nBufferSize); return OMXJPEG_ERROR_MEMORY; } ilclient_wait_for_event(decoder->imageResizer->component, OMX_EventCmdComplete, OMX_CommandPortEnable, 1, decoder->imageResizer->outPort, 1, 0, TIMEOUT_MS); return OMXJPEG_OK; }
// this function passed the jpeg image buffer in, and returns the decoded // image int decodeImage(OPENMAX_JPEG_DECODER * decoder, char *sourceImage, size_t imageSize) { char *sourceOffset = sourceImage; // we store a seperate // buffer ot image so we // can offset it size_t toread = 0; // bytes left to read from buffer toread += imageSize; int bFilled = 0; // have we filled our output // buffer bufferIndex = 0; while (toread > 0) { // get next buffer from array OMX_BUFFERHEADERTYPE *pBufHeader = decoder->ppInputBufferHeader[bufferIndex]; // step index and reset to 0 if required bufferIndex++; if (bufferIndex >= decoder->inputBufferHeaderCount) bufferIndex = 0; // work out the next chunk to load into the decoder if (toread > pBufHeader->nAllocLen) pBufHeader->nFilledLen = pBufHeader->nAllocLen; else pBufHeader->nFilledLen = toread; toread = toread - pBufHeader->nFilledLen; // pass the bytes to the buffer memcpy(pBufHeader->pBuffer, sourceOffset, pBufHeader->nFilledLen); // update the buffer pointer and set the input flags sourceOffset = sourceOffset + pBufHeader->nFilledLen; pBufHeader->nOffset = 0; pBufHeader->nFlags = 0; if (toread <= 0) { pBufHeader->nFlags = OMX_BUFFERFLAG_EOS; } // empty the current buffer int ret = OMX_EmptyThisBuffer(decoder->imageDecoder->handle, pBufHeader); if (ret != OMX_ErrorNone) { perror("Empty input buffer"); fprintf(stderr, "return code %x\n", ret); return OMXJPEG_ERROR_MEMORY; } // wait for buffer to empty or port changed event int done = 0; while ((done == 0) && (decoder->pOutputBufferHeader == NULL)) { if (decoder->pOutputBufferHeader == NULL) { ret = ilclient_wait_for_event (decoder->imageDecoder->component, OMX_EventPortSettingsChanged, decoder->imageDecoder->outPort, 0, 0, 1, 0, 5); if (ret == 0) { ret = portSettingsChanged(decoder); if (ret != OMXJPEG_OK) return ret; } } else { ret = ilclient_remove_event(decoder->imageDecoder->component, OMX_EventPortSettingsChanged, decoder->imageDecoder->outPort, 0, 0, 1); if (ret == 0) portSettingsChangedAgain(decoder); } // check to see if buffer is now empty if (pBufHeader->nFilledLen == 0) done = 1; if ((done == 0) || (decoder->pOutputBufferHeader == NULL)) sleep(1); } // fill the buffer if we have created the buffer if ((bFilled == 0) && (decoder->pOutputBufferHeader != NULL)) { ret = OMX_FillThisBuffer(decoder->imageResizer->handle, decoder->pOutputBufferHeader); if (ret != OMX_ErrorNone) { perror("Filling output buffer"); fprintf(stderr, "Error code %x\n", ret); return OMXJPEG_ERROR_MEMORY; } bFilled = 1; } } // wait for buffer to fill /* * while(pBufHeader->nFilledLen == 0) { sleep(5); } */ // wait for end of stream events int ret = ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventBufferFlag, decoder->imageDecoder->outPort, 1, OMX_BUFFERFLAG_EOS, 1, 0, 2); if (ret != 0) { fprintf(stderr, "No EOS event on image decoder %d\n", ret); } ret = ilclient_wait_for_event(decoder->imageResizer->component, OMX_EventBufferFlag, decoder->imageResizer->outPort, 1, OMX_BUFFERFLAG_EOS, 1, 0, 2); if (ret != 0) { fprintf(stderr, "No EOS event on image resizer %d\n", ret); } return OMXJPEG_OK; }
// this function cleans up the decoder. void cleanup(OPENMAX_JPEG_DECODER * decoder) { // flush everything through OMX_SendCommand(decoder->imageDecoder->handle, OMX_CommandFlush, decoder->imageDecoder->outPort, NULL); ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventCmdComplete, OMX_CommandFlush, 0, decoder->imageDecoder->outPort, 0, 0, TIMEOUT_MS); OMX_SendCommand(decoder->imageDecoder->handle, OMX_CommandPortDisable, decoder->imageDecoder->inPort, NULL); ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventCmdComplete, OMX_CommandPortDisable, 0, decoder->imageDecoder->outPort, 0, 0, TIMEOUT_MS); int i = 0; for (i = 0; i < decoder->inputBufferHeaderCount; i++) { OMX_BUFFERHEADERTYPE *vpBufHeader = decoder->ppInputBufferHeader[i]; OMX_FreeBuffer(decoder->imageDecoder->handle, decoder->imageDecoder->inPort, vpBufHeader); } ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventCmdComplete, OMX_CommandPortDisable, 0, decoder->imageDecoder->inPort, 0, 0, TIMEOUT_MS); OMX_FreeBuffer(decoder->imageDecoder->handle, decoder->imageDecoder->outPort, decoder->pOutputBufferHeader); ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventCmdComplete, OMX_CommandPortDisable, 0, decoder->imageDecoder->outPort, 0, 0, TIMEOUT_MS); ilclient_change_component_state(decoder->imageDecoder->component, OMX_StateIdle); ilclient_change_component_state(decoder->imageDecoder->component, OMX_StateLoaded); ilclient_wait_for_event(decoder->imageDecoder->component, OMX_EventCmdComplete, OMX_CommandStateSet, 0, OMX_StateLoaded, 0, 0, TIMEOUT_MS); OMX_Deinit(); if (decoder->client != NULL) { ilclient_destroy(decoder->client); } }
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); }
// 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; }
// 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; }