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;
}
Exemplo n.º 3
0
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, &param);
	    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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
static int image_decode_test(char *filename)
{

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

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

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

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

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

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

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


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

     //enable port
     ilclient_enable_port(image_read, 310);

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

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

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

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

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

#endif //image_read attempt


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

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

     ret = ilclient_change_component_state(image_decode, OMX_StateIdle);

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

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

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

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

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

     ret = ilclient_change_component_state(image_decode, OMX_StateExecuting);

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

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

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

	  }

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

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

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

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

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

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

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

     fclose(fin);

     ilclient_disable_tunnel(tunnel);
     ilclient_teardown_tunnels(tunnel);

      
     ret = ilclient_change_component_state(image_decode, OMX_StateIdle);
     ret = ilclient_change_component_state(image_decode, OMX_StateLoaded);
     
     ilclient_cleanup_components(list);
     OMX_Deinit();
     ilclient_destroy(client);
     return status;
}
Exemplo n.º 9
0
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(&param, 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, &param);
	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, &param);
	ERROR_RETURN("OMX_SetParameter record param",error);

	//
	memset(&param1, 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, &param1);
	ERROR_RETURN("OMX_GetParameter record param",error);

	param1.nSamplingRate = 16000;//support 16000 only?

	error = OMX_SetParameter(st_recd.comp, OMX_IndexParamAudioPcm, &param1);
	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;
}
Exemplo n.º 10
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(&param, 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, &param);
	ERROR_RETURN("OMX_SetParameter",error);
	//
	memset(&param1, 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, &param1);
	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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
// 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);
    }
}
Exemplo n.º 16
0
int main(int argc, char **argv)
{

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

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

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

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

    bcm_host_init();

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

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

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

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

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

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

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

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

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

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

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

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

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

    ilclient_enable_port(decodeComponent, 131);

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

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

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

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

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

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

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


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

    sleep(100);

    exit(0);
}
Exemplo n.º 17
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;
}
Exemplo n.º 18
0
// 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;
}