How to find the width of the frame for android?

I pick up the framebuffer on my Android device, but decoding does not work for the correct resolution.

I found that I can get bbp and screen resoution using:

ioctl -rl 28 /dev/graphics/fb0 17920 

This command returns:

return buf: f0 00 00 00 40 01 00 00 f0 00 00 00 80 02 00 00 00 00 00 00 00 00 00 00 20 00 00 00

In little-endian format, I have:

  • The last four bytes (20) is the number of bbp 32 .
  • The first four bytes - screen width 0xF0 = 240
  • Bytes 5 through 8 - screen height 0x0140 = 320

I tried to decode fb (Galaxy 5) using the following command:

 ./ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb32 -s 240x320 -i fb0 -f image2 -vcodec png image%d.png 

And I got this warning:

Invalid buffer size, packet size 40960 <expected length 307200 Error while decoding stream # 0: 0: Invalid argument

and these two images:

enter image description hereenter image description here

My raw file has 655.360 bytes, but the expected value is 614.400 bytes using this equation:

fileSize = xres * yres * bpp / 8 * numberOfFrames

fileSize = 240 * 320 * 32/8 * 2 (android uses a double framebuffer) = 614,400

For my surprise, I change the width size on ffmpeg to 256 to fit 655.360 bytes and it works (like, there are 16 additional images on the right side! I got the following images:

enter image description hereenter image description here

So my question is WHY I need to use a width of 256 if my screen resolution is 240. And how to open this magic number for other resolutions.

+4
source share
1 answer

To calculate the line size, you should use line_length .

 +-------------------------+----+ | | | | | | |<-------- XRES --------->| | = Xres is display resolution | | | | | | |<------- LINE LENGTH -------->| = Memory Size per line | | | | | | +-------------------------+----+ ^ ^ | | display on screen --+ +----> This is stride 

The right pad is called the "step" (stride = (line_length in pixel) - width). Many devices had this step in the framebuffer if the display resolution was not multiplied by 8.

So the formula is:

fileSize = line_length * yres * numberOfFrames

Do not multiply it by bpp / 8 , since the line length is the size of the memory (not the size of the pixel).

To extract line_length , you should use FBIOGET_FSCREENINFO (0x4602 - 17922) and not FBIOGET_VSCREENINFO (0x4600 - 17922) as follows:

ioctl -rl 50 / dev / graphics / fb0 17922

My Galaxy Nexus will return like this:

 return buf: 6f 6d 61 70 66 62 00 00 00 00 00 00 00 00 00 00 00 00 a0 ac 00 00 00 01 00 00 00 00 00 00 00 00 02 00 00 00 01 00 01 00 00 00 00 00 80 0b 00 00 00 00 ^_________^ 

My Galaxy Nexus has a line length: 2944 (0xb80).

+6
source

All Articles