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

-rman ffmpegに基づいて話す

入力オプションでファイルに保存されているタイムスタンプを無視し、代わりに一定のフレームレートfpsを想定してタイムスタンプを作成します。これは、image2やv4l2などの一部の入力形式で使用される-framerateオプションとは異なります(以前のバージョンのFFmpegでも同じでした)。疑わしい場合は、-rオプションを入力する代わりに-framerateを使用してください。

つまり、言うffmpegは、入力フレームのフレームレートが30fpsであることを示します。しかし、彼らはそうではありませんでした。 FFmpegは実際のフレームレートに興味がなく、取得するフレームだけをエンコードし、ユーザーが指定したフレームレートをファイルに保存します。

再生時に録画終了時に30フレームを取得するのに実際にかかる時間に関係なく、毎秒30フレームが再生されます。

つまり、-rまったく使用せず、自分がしていることを本当に知っている場合にのみ使用してください-framerate

関連情報