user25378595
user25378595

Reputation: 1

Displaying a Video with Raspberry and OpenCV problems with Framebuffer

I am pretty new in this forum, so sorry in advance if I don't know some etiquette ;)

I want to loop two videos on two screens and they have to be in perfect sync.

I am following this person's approach: youtube git

and so far it is not too bad, at least I get videos in sync and loop, but really slow. so now I am trying to run a script for one video to troubleshoot that and have this code so far:

import cv2
import numpy as np
import time
import os
import fcntl

VIDEO_PATH = "rot.mp4"
FBIO_WAITFORVSYNC = 1074021920 # TODO: Make it nicer

def load_video(path):
    my_video = cv2.VideoCapture(path, cv2.CAP_FFMPEG)

    frameCount = int(my_video.get(cv2.CAP_PROP_FRAME_COUNT))
    frameWidth = int(my_video.get(cv2.CAP_PROP_FRAME_WIDTH))
    frameHeight = int(my_video.get(cv2.CAP_PROP_FRAME_HEIGHT))

    FPS = int(my_video.get(cv2.CAP_PROP_FPS))

    buf = np.empty((frameCount, frameHeight, frameWidth, 2), np.dtype('uint8'))

    cur_frame = 0
    ret = True

    print(f"Loading video: {path}")
    while cur_frame < frameCount and ret:
        ret, frame = my_video.read()
        cvt_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2BGR565)
        buf[cur_frame] = cvt_frame
        cur_frame += 1

    my_video.release()
    
    print(f"Video {path}, fully loaded\n")

    return buf, FPS

def main():
    video, FPS = load_video(VIDEO_PATH)

    os.system('sudo sh -c "TERM=linux setterm -foreground black -clear all > /dev/tty0"')

    fb_fd = os.open("/dev/fb0", os.O_RDWR)
    fb_map = np.memmap("/dev/fb0", dtype='uint8', mode='r+', shape=(1080, 1920, 2))

    current_frame = 0
    last_frame_ts = 0

    while True:
        fcntl.ioctl(fb_fd, FBIO_WAITFORVSYNC)
        fb_map[:] = video[current_frame]

        since_last = time.perf_counter() - last_frame_ts
        to_wait = (1/FPS) - since_last

        if to_wait > 0:
            time.sleep(to_wait)
        else:
            print(f"Player lagging behind by: {(to_wait * -1000):.2f}ms")

        last_frame_ts = time.perf_counter()

        current_frame += 1
        if current_frame == len(video):
            current_frame = 0

if __name__ == '__main__':
    main()

My terminal output is:

raspberry@raspberry:~ $ sudo python3 opencv_fb_1video.py
Loading video: rot.mp4
Video rot.mp4, fully loaded

Traceback (most recent call last):
  File "/home/raspberry/opencv_fb_1video.py", line 67, in <module>
    main()
  File "/home/raspberry/opencv_fb_1video.py", line 49, in main
    fcntl.ioctl(fb_fd, FBIO_WAITFORVSYNC)
OSError: [Errno 16] Device or resource busy

If someone has any clue I would be thrilled.

Also I am open to completely different solutions. I am working on a Raspberry Pi4 with 4GB and I am using two FHD Screens connected to the HDMI Ports.

Thank you in advance!!!

I am working on a Raspberry Pi4 with 4GB and I am using two FHD Screens connected to the HDMI Ports. I want to loop two videos on two screens and they have to be in perfect sync.

I am following this person's approach: youtube git

and so far it is not too bad, at least I get videos in sync and loop, but really slow. so now I am trying to run a script for one video to troubleshoot that and have this code so far:

Upvotes: 0

Views: 100

Answers (0)

Related Questions