I noticed that OpenCV reads video frames almost 2x faster than FFMPEG.
Why is that? I thought all OpenCV does is call FFMPEG under the hood, possibly adding its own overhead.
Here's the code I use to obtain these results
import cv2
import time
import numpy as np
cap = cv2.VideoCapture("BigBuckBunny.mp4", apiPreference=cv2.CAP_FFMPEG)
frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
start = time.perf_counter()
while True:
ret, frame = cap.read()
if ret is False:
break
assert frame.shape == (720, 1280, 3)
assert frame.dtype == np.uint8
end = time.perf_counter()
print(f"{frames/(end-start):.1f} frames per second")
# Output: 692.3 frames per second
cap.release()
For FFMPEG (using the python-ffmpeg
library:
import ffmpeg
import numpy as np
import time
vid_info = ffmpeg.probe("BigBuckBunny.mp4")['streams'][1]
frames = int(vid_info['nb_frames'])
process1 = (
ffmpeg
.input("BigBuckBunny.mp4")
.output('pipe:', format='rawvideo', pix_fmt='bgr24')
)
print(process1.compile())
# Output: ['ffmpeg', '-i', 'BigBuckBunny.mp4', '-f', 'rawvideo', '-pix_fmt', 'bgr24', 'pipe:']
process1 = process1.run_async(pipe_stdout=True)
start = time.perf_counter()
while True:
in_bytes = process1.stdout.read(1280 * 720 * 3)
if not in_bytes:
break
frame = np.frombuffer(in_bytes, np.uint8).reshape([720, 1280, 3])
end = time.perf_counter()
print(f"{frames/(end-start):.1f} frames per second")
# Output: 373.6 frames per second
process1.wait()
Here's information about the video (~10 minutes length)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'BigBuckBunny.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isomavc1mp42
creation_time : 2010-01-10T08:29:06.000000Z
Duration: 00:09:56.47, start: 0.000000, bitrate: 2119 kb/s
Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
Metadata:
creation_time : 2010-01-10T08:29:06.000000Z
handler_name : (C) 2007 Google Inc. v08.13.2007.
vendor_id : [0][0][0][0]
Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1991 kb/s, 24 fps, 24 tbr, 24k tbn, 48 tbc (default)
Metadata:
creation_time : 2010-01-10T08:29:06.000000Z
handler_name : (C) 2007 Google Inc. v08.13.2007.
vendor_id : [0][0][0][0]
And FFMPEG and OpenCV versions:
ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
opencv-python-headless 4.6.0.66