# How to write/display video frame into /dev/fb1 with open('/dev/fb1', 'rb+')?

I am trying to write a video frame into Linux framebuffer fb1. My code is

cap = cv2.VideoCapture(0)
while cap.is_Opened():
with open('/dev/fb1', 'rb+') as buf:
buf.write(frame)
cap.release()


so now i can display my video frame on framebuffer fb1, but is not clean please see the output video frame in below picture. I am also open to suggestion if any better(or efficient) way to do it.

1. I already used mmap.mmap to write into the frame buffer 1, but it is giving me the same output.
2. I also tried using os.environ['SDL_FBDEV'] = '/dev/fb1' in a different thread so that i can use two framebuffers at a same time. (here I can get a clear image but I can use only one framebuffer which I do not want to do)
3. I have also tried converting video frame into bytearray()

this is my one of the ideas to solve my problem working with two framebuffers simultaneously. the black area will be used for display GUI by framebuffer 0 by os.environ['SDL_FBDEV'] = '/dev/fb0'for more information please see my old question https://stackoverflow.com/questions/5...

edit retag close merge delete

1

you should try to find out the required pixel format for your framebuffer (from here it looks, like it expects 32bit instead of the 24bits, that come from the VideoCapture)

frame32 = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)


might help

( 2018-12-02 08:52:06 -0500 )edit

Sort by » oldest newest most voted

Other than the pixel format (as suggested by @berak) you also need to consider the size of the framebuffer. If you write the raw data, it won't jump to new line at the second row of the image.

One solution would be to resize the image to the framebuffer size, and copy it to the framebuffer. It will give a full-screen image.

ret, frame = cap.read()
frame32 = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)
fbframe = cv2.resize(frame32, (1920,1080))
with open('/dev/fb1', 'rb+') as buf:
buf.write(fbframe)


The second solution is to fill the rest of every line with black pixels:

ret, frame = cap.read()
frame32 = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)
lineend=np.zeros(stride-4*frame.cols)
with open('/dev/fb1', 'rb+') as buf:
for row in frame32:
buf.write(row)
buf.write(lineend)


Probably you'll have to combine the two solutions; the first won't work well if the ratio of the image side is not the same as your screen; the second will still be problematic if the image is larger than the framebuffer.

You can get the framebuffer resolution from the /sys/class/graphics/fb0/modes file, and the stride from the /sys/class/graphics/fb0/stride file.

The code above is untested, so it might have bugs and need adjustments.

more

Official site

GitHub

Wiki

Documentation