g2d_blit() returns empty image, no errors, on iMX.6 yocto

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

g2d_blit() returns empty image, no errors, on iMX.6 yocto

Jump to solution
1,630 Views
dmitryponv
Contributor II

Good afternoon,

I'm following the examples in i.MX_6_G2D_API_User's Guide

My issue is that g2d_blit conversion works, but the returned image is all 0's

All error values for g2d functions are 0, indicating there was no errors

My code is shown below:

If I replace

ExportBmp((uint8_t*)(dst.planes[0]), width, height);

with

ExportBmp((uint8_t*)(src.planes[0]), width, height);

I get the correct image saved,

If I keep it the way it is, I get an image that is all black

My width = 240, height = 180

This API has very little documentation, and it does not mention whether it needs continuous physical memory address, or an array that may be fragmented in memory

I have tried both approaches, and both approaches returned a blank image.

The continuous memory addresses (for the source and destination images) I was able to allocate with ioctl in the IPU

Is there something wrong with the G2D API?

What could be causing this?

Thanks.

    void* handle;

    g2d_open(&handle);

    src.planes[0] = (int)source;

    src.left = 0;

    src.top = 0;

    src.right = width;

    src.bottom = height;

    src.stride = width*2;

    src.width = width;

    src.height = height;

    src.rot = G2D_ROTATION_0;

    src.format = G2D_RGBA8888;

    dst.planes[0] = (int)dest;

    dst.left = 0;

    dst.top = 0;

    dst.right = width;

    dst.bottom = height;

    dst.stride = width;

    dst.width = width;

    dst.height = height;

    dst.rot = G2D_ROTATION_0;

    dst.format = G2D_RGBA8888;

    error =g2d_blit(handle, &src, &dst);

    error =g2d_finish(handle);

    error =g2d_close(handle);

    ExportBmp((uint8_t*)(dst.planes[0]), width, height);

0 Kudos
Reply
1 Solution
1,151 Views
dmitryponv
Contributor II

Resolved:

Using a Continuously allocated buffer was the correct way to do it, however I was passing to the function a virtual pointer created for the application, whereas it required a physical pointer.

I cannot post the full code here, however in order to allocate physical memory in the IPU, you need to:

Do this Twice to obtain a virtualAddr and physAddr for Source and Destination

   int* virtualAddr;

   int bufferSize = width*height*bytesperpixel;

   int physAddr = bufferSize;

   int ipuHandle = open("/dev/mxc_ipu", O_RDWR, 0);

   ioctl(ipuHandle, IPU_ALLOC, physAddr); //the ioctl function for some reason requires the size of the buffer that it changes to the physical address in memory.

   virtualAddr = (int*)mmap(0, bufferSize, PROT_READ | PROT_WRITE,  MAP_SHARED, ipuHandle, physAddr);

Then

    void* handle;

    g2d_open(&handle);

    src.planes[0] = physAddrSource;

    src.left = 0;

    src.top = 0;

    src.right = width;

    src.bottom = height;

    src.stride = width*2;

    src.width = width;

    src.height = height;

    src.rot = G2D_ROTATION_0;

    src.format = G2D_RGBA8888;

    dst.planes[0] = physAddrDest;

    dst.left = 0;

    dst.top = 0;

    dst.right = width;

    dst.bottom = height;

    dst.stride = width;

    dst.width = width;

    dst.height = height;

    dst.rot = G2D_ROTATION_0;

    dst.format = G2D_RGBA8888;

    error =g2d_blit(handle, &src, &dst);

    error =g2d_finish(handle);

    error =g2d_close(handle);

    ExportBmp(virtualAddrDest, width, height);

View solution in original post

0 Kudos
Reply
1 Reply
1,152 Views
dmitryponv
Contributor II

Resolved:

Using a Continuously allocated buffer was the correct way to do it, however I was passing to the function a virtual pointer created for the application, whereas it required a physical pointer.

I cannot post the full code here, however in order to allocate physical memory in the IPU, you need to:

Do this Twice to obtain a virtualAddr and physAddr for Source and Destination

   int* virtualAddr;

   int bufferSize = width*height*bytesperpixel;

   int physAddr = bufferSize;

   int ipuHandle = open("/dev/mxc_ipu", O_RDWR, 0);

   ioctl(ipuHandle, IPU_ALLOC, physAddr); //the ioctl function for some reason requires the size of the buffer that it changes to the physical address in memory.

   virtualAddr = (int*)mmap(0, bufferSize, PROT_READ | PROT_WRITE,  MAP_SHARED, ipuHandle, physAddr);

Then

    void* handle;

    g2d_open(&handle);

    src.planes[0] = physAddrSource;

    src.left = 0;

    src.top = 0;

    src.right = width;

    src.bottom = height;

    src.stride = width*2;

    src.width = width;

    src.height = height;

    src.rot = G2D_ROTATION_0;

    src.format = G2D_RGBA8888;

    dst.planes[0] = physAddrDest;

    dst.left = 0;

    dst.top = 0;

    dst.right = width;

    dst.bottom = height;

    dst.stride = width;

    dst.width = width;

    dst.height = height;

    dst.rot = G2D_ROTATION_0;

    dst.format = G2D_RGBA8888;

    error =g2d_blit(handle, &src, &dst);

    error =g2d_finish(handle);

    error =g2d_close(handle);

    ExportBmp(virtualAddrDest, width, height);

0 Kudos
Reply