girijapretha
Posts: 4
Joined: Fri Aug 05, 2016 8:59 am

Getting the decoded data back from decoder

Fri Aug 12, 2016 10:42 am

Hi,

I am using the below program to get decoded data back from the decoder in RPI2. When I run this binary it is stuck after some iteration and I am not able to get the decoded data. Can anyone help me in fixing this and make this code work for getting the decoded data back.

Code: Select all

static void set_video_decoder_input_format(COMPONENT_T *component) {
	int err; 

	OMX_VIDEO_PARAM_PORTFORMATTYPE videoPortFormat;
	memset(&videoPortFormat, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
	videoPortFormat.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
	videoPortFormat.nVersion.nVersion = OMX_VERSION;

	videoPortFormat.nPortIndex = 130;
	videoPortFormat.eCompressionFormat = OMX_VIDEO_CodingAVC;
	OMX_SetParameter(ilclient_get_handle(component),
			OMX_IndexParamVideoPortFormat, &videoPortFormat);


}

OMX_ERRORTYPE read_into_buffer_and_empty(FILE *fp, COMPONENT_T *component,
		OMX_BUFFERHEADERTYPE *buff_header, int *toread) {
	OMX_ERRORTYPE r;

	int buff_size = buff_header->nAllocLen;
	int nread = fread(buff_header->pBuffer, 1, buff_size, fp);

	buff_header->nFilledLen = nread;
	*toread -= nread;

	if (*toread <= 0) {
		buff_header->nFlags |= OMX_BUFFERFLAG_EOS;
	}
	r = OMX_EmptyThisBuffer(ilclient_get_handle(component),
			buff_header);
	return r;
}

OMX_ERRORTYPE save_info_from_filled_buffer(COMPONENT_T *component,
		OMX_BUFFERHEADERTYPE * out) {
	OMX_ERRORTYPE r;
	int status;

	r = OMX_FillThisBuffer(ilclient_get_handle(component), 
			out); 
	return r;
}

#define IMG test.h264
int main(int argc, char** argv) {

	int i;
	char *componentName;
	int err;
	ILCLIENT_T  *handle;
	COMPONENT_T *component;
	FILE *fp = fopen(IMG, "r");
	FILE *outf;
	int toread = get_file_size(IMG);
	int count = 0;
	OMX_BUFFERHEADERTYPE *buff_header;
	OMX_BUFFERHEADERTYPE *output_header;

	componentName = "video_decode";
	
	bcm_host_init();

	handle = ilclient_init();
	if (handle == NULL) {
		exit(1);
	}

	if (OMX_Init() != OMX_ErrorNone) {
		ilclient_destroy(handle);
		exit(1);
	}


	err = ilclient_create_component(handle, &component, componentName,
			ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS |
			ILCLIENT_ENABLE_OUTPUT_BUFFERS
			);
	if (err == -1) {
		exit(1);
	}

	err = ilclient_change_component_state(component, OMX_StateIdle);
	if (err < 0) {
		exit(1);
	}

	set_video_decoder_input_format(component);

	ilclient_enable_port_buffers(component, 130, NULL, NULL, NULL);
	ilclient_enable_port(component, 130);

	err = ilclient_change_component_state(component, OMX_StateExecuting);
	if (err < 0) {
		exit(1);
	}

	int port_settings_changed = 0;
	while (!port_settings_changed) {
		buff_header = 
			ilclient_get_input_buffer(component, 130, 1 );
		if (buff_header != NULL) {
			read_into_buffer_and_empty(fp, component, buff_header,
					&toread);

		}

		// wait for first input block to set params for output port
		err = ilclient_wait_for_event(component, 
				OMX_EventPortSettingsChanged, 131, 0, 0, 1,
				ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 
				2000);
		if (err >= 0) {
			port_settings_changed = 1;
		}
		err = ilclient_remove_event(component, OMX_EventPortSettingsChanged, 131, 0, 0, 1);
		if (err >= 0) {
			port_settings_changed = 1;
		}
	}


	ilclient_enable_port_buffers(component, 131, NULL, NULL, NULL);
	ilclient_enable_port(component, 131);
	while (toread > 0) {

		OMX_ERRORTYPE r;

		buff_header = 
			ilclient_get_input_buffer(component, 130, 1 );
		if (buff_header != NULL) {
			read_into_buffer_and_empty(fp, component, buff_header, &toread);
		}
		count++;

		output_header = 
			ilclient_get_output_buffer(component, 131, 1 );
		if (output_header != NULL) {
			save_info_from_filled_buffer(component,
					output_header);
		} 
	}

	while (0) {
		output_header = 
			ilclient_get_output_buffer(component, 131, 1 );
		if (output_header != NULL) {
			save_info_from_filled_buffer(component,
					output_header);
		}
		count++;
	}
	
	exit(0);
}
Sorry for very lengthy code :(

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7026
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Getting the decoded data back from decoder

Fri Aug 12, 2016 10:55 am

You've made the invalid assumption that for every buffer you submit that you'll get one output frame.
As you're not framing the data as it comes in, each input buffer could contain a partial frame, 1 frame, or more than one frame. Each time you're pulling out one frame. Depeneding on which way the frame sizes go, you'll either just fill the video decoder input FIFO and it'll stop returning the input buffer, or you haven't given the decoder enough data to produce an output frame and you'll be sitting waiting for a frame that will never come.

If you tell ilclient_get_output_buffer and ilclient_get_input_buffer not to block (parameter 3), and then ensure you handle them not providing a buffer, then things should flow more smoothly. Ideally you should be waiting on events by using ilclient_set_fill_buffer_done_callback and ilclient_set_empty_buffer_done_callback to get the signals of when buffers are returned, otherwise you'll be spinning in a fairly tight loop.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

Return to “OpenMAX”