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.

관련 정보