Hello Community,
I want to resize a picture (twice: 1/2 and 1/4) which is captured by a camera using the IPU. I'm working on a Linuxkernel (freescale) and I'm using the IPU-HL Libs. (mxc_ipu_hl_lib.h)
The IPU does not resize, its cropping my picture when I'm doing following:
- captured image is grayscale
- size 1280 x 1024
Whats wrong with my code? Thank's for help :smileyhappy:
1) "Main-function" - in constructor of "ImageDisplay" [startIPU] is called
void ImageDisplay::setImage(void* buffer, int CamPitch)
{
cv::Mat m_lastImage;
//size of picture is 1280 x 1024
int x = 1280/2;
int y = 1024/2;
//copy captured picture to buffer
memcpy(buf[1],buffer,test_handle.input.width * test_handle.input.height);
updateIPU(&test_handle, x, y);
//saving image using OpenCV
m_lastImage = cv::Mat(y, x, CV_8UC1, buf[1], CamPitch);
cv::imwrite("img05.bmp", m_lastImage );
x/=2;
y/=2;
memcpy(buf[1],buffer,test_handle.input.width * test_handle.input.height);
updateIPU(&test_handle, x, y);
m_lastImage = cv::Mat(y, x, CV_8UC1, buf[1], CamPitch);
cv::imwrite("img025.bmp", m_lastImage );
}
2. Initialisation of IPU
int ImageDisplay::startIPU(ipu_test_handle_t * test_handle)
{
if ((fd_fb = open("/dev/fb0", O_RDWR, 0)) < 0)
{
printf("Unable to open /dev/fb0\n");
ret = -1;
}
if ( ioctl(fd_fb, FBIOGET_VSCREENINFO, &fb_var) < 0)
{
printf("Get FB var info failed!\n");
ret = -1;
}
if ( ioctl(fd_fb, FBIOGET_FSCREENINFO, &fb_fix) < 0)
{
printf("Get FB fix info failed!\n");
ret = -1;
}
if(fb_var.yres_virtual != 3*fb_var.yres)
{
fb_var.yres_virtual = 3*fb_var.yres;
if ( ioctl(fd_fb, FBIOPUT_VSCREENINFO, &fb_var) < 0)
{
printf("Get FB var info failed!\n");
ret = -1;
}
}
screen_size = fb_var.yres * fb_fix.line_length;
fb[0] = mmap(NULL, 3 * screen_size, PROT_READ | PROT_WRITE, MAP_SHARED,
fd_fb, 0);
if (fb[0] == MAP_FAILED)
{
printf("fb buf0 mmap failed, errno %d!\n", errno);
ret = -1;
}
fb[1] = (void *)((char *)fb[0]);
fb[0] = (void *)((char *)fb[1] + screen_size);
fb[2] = (void *)((char *)fb[1] + 2*screen_size);
/* use I420 input format as fix*/
test_handle->mode = OP_STREAM_MODE;
test_handle->input.width = 1280;
test_handle->input.height = 1024;
test_handle->input.fmt = v4l2_fourcc('I', '4', '2', '0');
if (fb_var.bits_per_pixel == 24)
test_handle->output.fmt = v4l2_fourcc('B', 'G', 'R', '3');
else
test_handle->output.fmt = v4l2_fourcc('R', 'G', 'B', 'P');
test_handle->output.width = fb_var.xres;
test_handle->output.height = fb_var.yres;
size = test_handle->input.width * test_handle->input.height * 3;
ret = dma_memory_alloc(size, BUF_CNT, paddr, buf);
if ( ret < 0) {
printf("dma_memory_alloc failed\n");
}
test_handle->input.user_def_paddr[0] = paddr[0];
test_handle->input.user_def_paddr[1] = paddr[1];
//init buffer (writing values)
gen_fill_pattern((char*)buf[0], test_handle->input.width, test_handle->input.height);
gen_fill_pattern((char*)buf[1], test_handle->input.width, test_handle->input.height);
ret = mxc_ipu_lib_task_init(&(test_handle->input), NULL, &(test_handle->output), test_handle->mode, test_handle->ipu_handle);
if (ret < 0)
{
printf("mxc_ipu_lib_task_init failed!\n");
}
return 0;
}
3.) Finally calling the update function
int ImageDisplay::updateIPU(ipu_test_handle_t * test_handle, int x, int y)
{
test_handle->output.width = x;
test_handle->output.height = y;
if(mxc_ipu_lib_task_buf_update(test_handle->ipu_handle, paddr[1], 0, 0, NULL, NULL) < 0)
return -1;
else
return 0;
}
Solved! Go to Solution.
Hi Markus,
I don't know if it helps, but you can take a look on this rotation code:
https://github.com/rogeriorps/ipu-examples/blob/master/mx5/rotation/example1/rot_ex1.c
Take off the rotation part (or run with rotation=0) and change the output size to the desired image size changing the following lines:
test_handle.output.width = fb_var.xres;
test_handle.output.height = fb_var.yres;
Rgds
Rogerio
Hello,
as I assumend its not working with gstreamer.
Can anybody provide a code-snippet for resizing pics with IPU and HL-Libs (mxc_ipu_hl_lib.c) ?
Thx,
Markus
Hi Markus,
I don't know if it helps, but you can take a look on this rotation code:
https://github.com/rogeriorps/ipu-examples/blob/master/mx5/rotation/example1/rot_ex1.c
Take off the rotation part (or run with rotation=0) and change the output size to the desired image size changing the following lines:
test_handle.output.width = fb_var.xres;
test_handle.output.height = fb_var.yres;
Rgds
Rogerio
Hello Kirill,
thanks for your reply.
I'm not using v4linux. So I'm not sure if gstreamer(+plugin) is working for me. My cam-driver (closed source) is running as a service and is providing a void* field in memory by an API. I want to copy this field in DMA and IPU should resize it. The Camera is connected by USB.
In the .patch-file a file/folder "src/video/ipu_csc/src/mfw_gst_ipu_csc.c" is mentioned. I can't find this file in my toolchain directory...
Can you tell me where I can find "src/mfw_gst_ipu_csc.c". Maybe you can also post a little code-example....
Many thanks,
Markus
Hello, Markus!
You can find full source in gst-fsl-plugin-2.0.3/src/video/ipu_csc/src/mfw_gst_ipu_csc.c.