IPU displaying a decoded frame from VPU results in green color image

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IPU displaying a decoded frame from VPU results in green color image

915 Views
jorisguisson
Contributor I

I have been trying to display some VC1 video decoded with the VPU using the IPU on an imx6q.

This works perfectly when I take the decoded video from the VPU, copy it into a userspace buffer, and then copy that into a buffer allocated by IPU_ALLOC. If I then setup a IPU task to do a colorspace conversion from YUV_420P to RGB32, and use the framebuffer as the physical output address, I get a nice picture displayed on screen with the correct colors.

Obviously this isn't very efficient with all those copies going on. So I decided to use the physical address of the VPU buffer as input physical address for the IPU. The IPU task is configured completely the same way as above, only the physical input address now points to the VPU buffer's physical address. According to several code examples I found, this should work. However, it doesn't, I get an image which is green. You can see the shape of things in the image, but all the color is green, so it looks like the Y plane is taken into account during the conversion but the U and V planes aren't. The fact that it is green, probably means that 0 is used as a default value for the U and V values.

This doesn't make any sense at all. If the IPU couldn't access the VPU buffer, then you would see nothing, but only the Y plane seems to be read from the VPU buffer.

Has anybody got an idea what I could be doing wrong ?

Labels (4)
0 Kudos
3 Replies

643 Views
jorisguisson
Contributor I

Never mind, found out what the problem had accidentally set height to width when allocating the VPU buffers

0 Kudos

643 Views
joepsycho
Contributor II

Can you give the code example about how you use ipu to draw on framebuffer? thanks

0 Kudos

643 Views
jorisguisson
Contributor I

Basically you use the physical address of the framebuffer as output address of the ipu task:

          

           struct fb_fix_screeninfo info;

            ioctl(m_frame_buffer_fd, FBIOGET_FSCREENINFO, &info);

            struct fb_var_screeninfo vinfo;

            ioctl(m_frame_buffer_fd, FBIOGET_VSCREENINFO, &vinfo);

            struct ipu_task m_task;

            memset(&m_task, 0, sizeof(ipu_task));

            m_task.input.width = input_width;
            m_task.input.height = input_height;
            m_task.input.format = IPU_PIX_FMT_YUV420P;

            m_task.output.width = vinfo.xres;
            m_task.output.height = vinfo.yres;
            switch(vinfo.bits_per_pixel)
            {
            case 32:
                m_task.output.format = IPU_PIX_FMT_RGB32;
                break;
            case 24:
                m_task.output.format = IPU_PIX_FMT_RGB24;
                break;
            case 16:
                m_task.output.format = IPU_PIX_FMT_RGB565; // This might actually be the wrong output format
                break;
            }

            m_task.output.rotate = IPU_ROTATE_NONE;
            m_task.output.crop.w = m_geometry.getWidth();
            m_task.output.crop.h = m_geometry.getHeight();
            m_task.output.crop.pos.x = m_geometry.getOffsetX();
            m_task.output.crop.pos.y = m_geometry.getOffsetY();

            m_task.output.paddr = info.smem_start; // Use the framebuffer's address as output address

            m_task.input.paddr = physical_address_of_vpu_buffer_containing_decoded_frame;

            ioctl(m_ipu_fd, IPU_QUEUE_TASK, &m_task);

0 Kudos