1

I write a video using cv2.VideoWriter with fps=5; VLC plays it back at 5fps; and ffprobe reports tbr=5.

I write it with fps=4.5; VLC plays it back at 4.5fps; but ffprobe reports tbr=9.

How can I detect 4.5 fps?

EDIT: BTW the metadata shown in windows file manager and using cv2 get(cv2.CAP_PROP_FPS) is 600fps.

EDIT2: Turns out the issue is only on Raspberry pi. Looks like cv2 does not write the metadata correctly as rpi/ffprobe works fine on a file created on laptop. However even the rpi created file plays fine so there must be a way VLC detects fps.

import cv2
source = "test.avi"
reader = cv2.VideoCapture(source)
writer = cv2.VideoWriter("temp.avi", cv2.VideoWriter_fourcc(*'DIVX'), 4.5, (800, 600))
while True:
    res, img = reader.read()
    if not res:
        break
    writer.write(img)
reader.release()
writer.release()
simon
  • 2,561
  • 16
  • 26
  • Possibly related: https://stackoverflow.com/a/9400527/2864740 – user2864740 May 24 '21 at 18:46
  • thanks that is useful. however the frame rate is 4.5 and tbr is estimated as 9 which is quite a poor estimate. Two other issues....cv2.videowriter has an FPS parameter whose sole purpose is to be written to metadata but it seems it isn't. secondly vlc somehow manages to play the video at the correct rate so how does it determine it? – simon May 24 '21 at 20:00
  • 1
    I can't reproduce the problem. Can you please post the code you are using for writing the video (post a code sample that writes a synthetic video file). Please give more relevant information like OpenCV version, your Operation System... – Rotem May 24 '21 at 20:59
  • `tbr` is NOT equal to frame rate. please read the documentation of ffmpeg to find out what `tbr` actually means. – Christoph Rackwitz May 25 '21 at 10:02
  • @Rotem I too could not replicate on my laptop so it turns out it is an issue on raspeberry pi. updated the post with example code. – simon May 25 '21 at 11:04
  • 1
    @simon It looks like a bug in OpenCV (or in a library that used by OpenCV). In case you want to debug it, you can execute: `ffprobe -show_packets temp.avi`. The delta between two sequential `pts_time` (and also `dts_time`) should be `1/4.5` second. You can also [fix the framerate without reencoding](https://stackoverflow.com/questions/45462731/using-ffmpeg-to-change-framerate). Use `setpts=N/4.5/TB` – Rotem May 25 '21 at 20:24
  • 1
    @simon You may also use FFmpeg instead of OpenCV. Check my [answer](https://stackoverflow.com/questions/61260182/how-to-output-x265-compressed-video-with-cv2-videowriter). – Rotem May 25 '21 at 20:27

0 Answers0