I am trying to create h264 video from webcam image. My problem is when I read images from camera and send to ffmpeg by PIPE, I get to low framerate.
My code:
import cv2
import numpy as np
import subprocess as sp
import shlex
# 50 frames, resolution 1280x720, and 25 fps
width, height, n_frames, fps = 1280, 720, 50, 30
cameraObj = cv2.VideoCapture(0)
cameraObj.set(3, 1280)
cameraObj.set(4, 720)
output_filename = 'video.mp4'
sh = shlex.split(f'./ffmpeg -y -s {width}x{height} -pixel_format bgr24 -f rawvideo '
f'-r {fps} -i pipe: -vcodec cedrus264 '
f'-pix_fmt nv12 {output_filename}') # ffmpeg command with pipe: input
process = sp.Popen((sh), stdin=sp.PIPE)
lstImage = []
for i in range(0,200): # read 200 images save to lstImage
ret, img = cameraObj.read()
lstImage.append(img.tobytes())
for img in lstImage:
process.stdin.write(img) #send each image to ffmpeg
process.stdin.close()
process.wait()
process.terminate()
Result:
ffmpeg version git-2015-01-22-f86a076 Copyright (c) 2000-2014 the FFmpeg developers
built on Aug 17 2016 12:24:21 with gcc 4.8 (Ubuntu/Linaro 4.8.4-2ubuntu1~14.04.3)
configuration: --prefix=/usr --enable-nonfree --enable-gpl --enable-version3 --enable-vdpau --enable-libx264 --enable-libmp3lame --enable-libpulse --enable-libv4l2 --enable-cedrus264
libavutil 54. 6.100 / 54. 6.100
libavcodec 56. 0.101 / 56. 0.101
libavformat 56. 2.100 / 56. 2.100
libavdevice 56. 0.100 / 56. 0.100
libavfilter 5. 0.102 / 5. 0.102
libswscale 3. 0.100 / 3. 0.100
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 0.100 / 53. 0.100
Input #0, rawvideo, from 'pipe:':
Duration: N/A, start: 0.000000, bitrate: 442368 kb/s
Stream #0:0: Video: rawvideo (BGR[24] / 0x18524742), bgr24, 1280x720, 442368 kb/s, 20 tbr, 20 tbn, 20 tbc
[VDPAU SUNXI] VE version 0x1680 opened.
Output #0, mp4, to 'video.mp4':
Metadata:
encoder : Lavf56.2.100
Stream #0:0: Video: h264 (cedrus264) ([33][0][0][0] / 0x0021), nv12, 1280x720, q=2-31, 200 kb/s, 20 fps, 10240 tbn, 20 tbc
Metadata:
encoder : Lavc56.0.101 cedrus264
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (cedrus264))
frame= 200 fps=6.3 q=30.0 Lsize= 760kB time=00:00:10.00 bitrate= 622.8kbits/s
video:759kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.200271%
Frame rate just is 6.3 fps.
However when FFMPEG input is webcam device(/dev/video0) by command:
sudo ./ffmpeg -f v4l2 -channel 0 -video_size 1280x720 -i /dev/video0 -pix_fmt nv12 -r 30 -b:v 64k -c:v cedrus264 test.mp4
frame rate easy reach to 30 fps
Why is there this difference?