我正在使用嵌入式 Linux 系统(kerne-5.10.24)。
现在我正在测试视频录制和播放。
我用命令录制了视频,
ffmpeg -f v4l2 -s 640x480 -r 30 -vcodec mjpeg -i /dev/video3 -b:v 1000k -an /tmp/videocap.avi
然后,我用 ffmpeg 播放视频,如下所示,
ffmpeg -i /tmp/videocap.avi -pix_fmt bgra -f fbdev /dev/fb0
我发现视频播放速度比录制速度快得多,如下所示,
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
Input #0, avi, from '/tmp/videocap.avi':
Metadata:
encoder : Lavf58.29.100
Duration: 00:00:10.33, start: 0.000000, bitrate: 1036 kb/s
Stream #0:0: Video: mpeg4 (Simple Profile) (FMP4 / 0x34504D46), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 1029 kb/s, 30 fps, 30 tbr, 30 tbn, 30 tbc
Stream mapping:
Stream #0:0 -> #0:0 (mpeg4 (native) -> rawvideo (native))
Press [q] to stop, [?] for help
[swscaler @ 0xbd87a0] No accelerated colorspace conversion found from yuv420p to bgra.
Output #0, fbdev, to '/dev/fb0':
Metadata:
encoder : Lavf58.29.100
Stream #0:0: Video: rawvideo (BGRA / 0x41524742), bgra, 640x480 [SAR 1:1 DAR 4:3], q=2-31, 294912 kb/s, 30 fps, 30 tbn, 30 tbc
Metadata:
encoder : Lavc58.54.100 rawvideo
frame=310 fps= 90 q=-0.0 Lsize=N/A time=00:00:10.33 bitrate=N/A speed=2.99x
video:372000kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
......speed=2.99x
我
也尝试过这样的命令,
# ffmpeg -i videocap.avi -vf "setpts=0.5*PTS" videocap2.avi
....
Output #0, avi, to 'videocap2.avi':
Metadata:
ISFT : Lavf58.29.100
Stream #0:0: Video: mpeg4 (FMP4 / 0x34504D46), yuv420p, 640x480 [SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 30 fps, 30 tbn, 30 tbc
Metadata:
encoder : Lavc58.54.100 mpeg4
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
frame= 156 fps= 35 q=24.8 Lsize=389kB time=00:00:05.20 bitrate= 612.5kbits/s dup=0 drop=154 speed=1.16x
video:379kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 2.467023%
但玩起来ffmpeg -i /tmp/videocap2.avi -pix_fmt bgra -f fbdev /dev/fb0
却得到了同样的结果,没有减慢速度。
那么如何以与录制时相同的速度(FPS)重播视频呢?
更改为使用-framerate。
ffmpeg -f v4l2 -s 640x480 -framerate 30 -vcodec mjpeg -i /dev/video3 -b:v 1000k /tmp/videocap.avi
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
Input #0, video4linux2,v4l2, from '/dev/video3':
Duration: N/A, start: 61.843846, bitrate: N/A
Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 640x480, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (mjpeg (native) -> mpeg4 (native))
Press [q] to stop, [?] for help
[swscaler @ 0x105f790] deprecated pixel format used, make sure you did set range correctly
Output #0, avi, to '/tmp/videocap.avi':
Metadata:
ISFT : Lavf58.29.100
Stream #0:0: Video: mpeg4 (FMP4 / 0x34504D46), yuv420p, 640x480, q=2-31, 1000 kb/s, 30 fps, 30 tbn, 30 tbc
Metadata:
encoder : Lavc58.54.100 mpeg4
Side data:
cpb: bitrate max/min/avg: 0/0/1000000 buffer size: 0 vbv_delay: -1
frame=99 fps=5.3 q=4.2 Lsize=852kB time=00:00:11.83 bitrate= 590.1kbits/s speed=0.634x
video:839kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.659792%
然后按如下方式播放 videocap.avi,
ffmpeg -i /tmp/videocap.avi -pix_fmt bgra -f fbdev /dev/fb0
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
Trailing options were found on the commandline.
Input #0, avi, from '/tmp/videocap.avi':
Metadata:
encoder : Lavf58.29.100
Duration: 00:00:11.83, start: 0.000000, bitrate: 590 kb/s
Stream #0:0: Video: mpeg4 (Simple Profile) (FMP4 / 0x34504D46), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 582 kb/s, 30 fps, 30 tbr, 30 tbn, 30 tbc
Stream mapping:
Stream #0:0 -> #0:0 (mpeg4 (native) -> rawvideo (native))
Press [q] to stop, [?] for help
[swscaler @ 0x1a1b6f0] No accelerated colorspace conversion found from yuv420p to bgra.
Output #0, fbdev, to '/dev/fb0':
Metadata:
encoder : Lavf58.29.100
Stream #0:0: Video: rawvideo (BGRA / 0x41524742), bgra, 640x480 [SAR 1:1 DAR 4:3], q=2-31, 294912 kb/s, 30 fps, 30 tbn, 30 tbc
Metadata:
encoder : Lavc58.54.100 rawvideo
frame= 99 fps= 82 q=-0.0 Lsize=N/A time=00:00:11.83 bitrate=N/A speed=9.77x
video:118800kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
答案1
-r
说,根据man ffmpeg
,
作为输入选项,忽略文件中存储的任何时间戳,而是在假定帧速率 fps 恒定的情况下生成时间戳。这与用于某些输入格式(如 image2 或 v4l2)的 -framerate 选项不同(它在旧版本的 FFmpeg 中曾经相同)。如果有疑问,请使用 -framerate 而不是输入选项 -r。
换句话说,你告诉ffmpeg 表明输入帧的帧率为 30 fps。但他们没有。 FFmpeg 不关心帧的实际速率,它只是对其获取的帧进行编码并将您告诉它的帧速率放入文件中。
播放时,每秒播放 30 帧,无论录制端实际获得 30 帧需要多长时间。
换句话说,-r
根本不要使用,只有当您真正知道自己在做什么时,才使用-framerate
.