ffmpeg 播放 AVI 视频的速度比录制视频的速度快

ffmpeg 播放 AVI 视频的速度比录制视频的速度快

我正在使用嵌入式 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.

相关内容