Dear all,
I'm having difficulty getting a simple use of the IPU to work. If I understand it right, the IPU can allocate an input and output buffer (if none is specified by the user) and perform a simple colour space conversion on the input buffer contents.
Below is some very simple code that sets up the IPU to do CSC conversion on a fixed array of 0xFF values. (The 0xFF value is not relevant, the problem happens with any value.)
When I run this, most of the time the IPU does *not* perform the CSC. The output buffer before and after the IPU task contains values of zero. BUT - occasionally it *does* work and the output buffer contains repeated correct non-zero characters.
The IPU always returns a value of zero, meaning it always thinks it was successful.
Does anyone have ideas why this mostly fails but occasionally works?
Many thanks
/******************************************************************************************
**
** IPU test
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <mxc_ipu_hl_lib.h>
int
main(int argc, char **argv)
{
int ret, test, i;
unsigned char *ptr;
ipu_lib_handle_t handle;
ipu_lib_input_param_t input;
ipu_lib_output_param_t output;
unsigned int w = 720, h = 576;
// run the IPU test 10 times
for (test = 0; test < 10; test++)
{
// setup the IPU input
memset(&input, 0x00, sizeof(input));
input.width = w;
input.height = h;
input.fmt = IPU_PIX_FMT_UYVY;
input.motion_sel = HIGH_MOTION;
input.input_crop_win.pos.x = 0;
input.input_crop_win.pos.y = 0;
input.input_crop_win.win_w = w;
input.input_crop_win.win_h = h;
input.user_def_paddr[0] = NULL;// NULL means that a buffer will be allocated
// setup the IPU output
memset(&output, 0x00, sizeof(output));
output.width = w;
output.height = h;
output.fmt = IPU_PIX_FMT_RGB565;
output.rot = IPU_ROTATE_NONE;
output.show_to_fb = 0;
output.fb_disp.pos.x = 0;
output.fb_disp.pos.y = 0;
output.fb_disp.fb_num = 0;
output.output_win.pos.x = 0;
output.output_win.pos.y = 0;
output.output_win.win_w = w;
output.output_win.win_h = h;
output.user_def_paddr[0] = NULL;// NULL means that a buffer will be allocated
memset(&handle, 0x00, sizeof(handle));
// initialise the IPU
ret = mxc_ipu_lib_task_init(&input, NULL, &output,
OP_NORMAL_MODE,
&handle);
// print the addresses and sizes of the buffers that the IPU allocated
printf("mxc_ipu_lib_task_init ret:%d"
" inbuf_start: 0x%X outbuf_start: 0x%X\n"
" ifr_size: %d ofr_size: %d\n",
ret,
(unsigned int)handle.inbuf_start[0], (unsigned int)handle.outbuf_start[0],
handle.ifr_size, handle.ofr_size);
// NOTE the printf above ALWAYS prints out (though addresses might change):
// "mxc_ipu_lib_task_init ret:0 inbuf_start: 0x2B6A0000 outbuf_start: 0x2B76B000"
// " ifr_size: 829440 ofr_size: 829440
if (ret == 0) // zero means the init worked
{
printf("DOING IPU TASK\n");
// set the IPU input buffer to all 0xFF
memset(handle.inbuf_start[0], 0xFF, handle.ifr_size);
// before executing the task, print some of the outbuffer contents
ptr = (unsigned char *)handle.outbuf_start[0];
printf("outbuf before: ");
for (i = 0; i < 10; i++, ptr++)
printf("%02X ", *ptr);
printf("\n");
// the printf above ALWAYS prints out:
// "outbuf before: 00 00 00 00 00 00 00 00 00 00"
// execute the task
ret = mxc_ipu_lib_task_buf_update(&handle, NULL, 0, 0, NULL, NULL);
printf("loop:%d, mxc_ipu_lib_task_buf_update returned:%d\n", loop, ret);
// now print some outbuf contents after the task
ptr = (unsigned char *)handle.outbuf_start[0];
if (*ptr)// check for any non-zero value in output
printf("************* IPU DID CONVERT *************\n");// very rarely prints this!
printf("outbuf after: ");
for (i = 0; i < 10; i++, ptr++)
printf("%02X ", *ptr);
printf("\n");
// almost every time, the contents of the outbuf here is printed as zero, which is wrong.
// sometimes, possibly once every 10 attempts, the outbuf contains
// sequences of 0xDF, 0xFB - which is a correct conversion
}
else
{
// NOTE: this never gets printed, so the task by implication is always OK
printf("mxc_ipu_lib_task_init FAILED:%d\n", ret);
return(0);
}
// close the task
mxc_ipu_lib_task_uninit(&handle);
}
return(0);
}