ffmpeg 视频录制在“处理输入时发现无效数据”后冻结

ffmpeg 视频录制在“处理输入时发现无效数据”后冻结

我正在尝试使用 USB 视频捕获设备和以下命令录制我的旧 VHS 磁带:

ffmpeg -f alsa -ac 2 -i default -f v4l2 -standard pal -i /dev/video0 -c:v libx264 -qp 0 -preset fast -strict -2 zzz.mp4

但有时,在录制过程中,ffmpeg 会意外地冻结视频的录制并停留在最后一帧(音频继续录制)。错误消息如下:

[video4linux2,v4l2 @ 0x23e51a0] Dequeued v4l2 buffer contains 414720 bytes, but 829440 were expected. Flags: 0x00002005. 
/dev/video0: Invalid data found when processing input

我在网上几乎找不到关于此问题的任何信息。我​​发现这个问题被描述为功能请求:https://trac.ffmpeg.org/ticket/4795

另外,在这个错误出现之前,我遇到了一条警告信息,这似乎与视频录制无关,而且似乎也不会影响视频录制,但我也想知道这意味着什么:

[video4linux2,v4l2 @ 0x23e51a0] Thread message queue blocking; consider raising the thread_queue_size option (current value: 8)
[alsa @ 0x23cc360] Thread message queue blocking; consider raising the thread_queue_size option (current value: 8)

通过反复试验,似乎当我设置 -f v4l2 -thread_queue_size 32和时警告就消失了-f alsa -thread_queue_size 2048。我不知道为什么。当我增加视频输入的线程队列大小(例如增加到 512)时,我没有收到警告,但丢帧了。

我希望我可以使用 ffmpeg 进行录制。VLC 录制没有问题,但我对参数也有点困惑,我还没有充分研究它们。如果有人可以建议使用 vlc 的替代命令来无损录制,我会改用 vlc...

ffmpeg 的完整输出是:

$ ffmpeg -f alsa -ac 2 -i default -f v4l2 -standard pal -i /dev/video0 -c:v libx264 -qp 0 -preset fast -strict -2 zzz.mp4
ffmpeg version 2.7.6-0ubuntu0.15.10.1 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 5.2.1 (Ubuntu 5.2.1-22ubuntu2) 20151010
  configuration: --prefix=/usr --extra-version=0ubuntu0.15.10.1 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --enable-shared --disable-stripping --enable-avresample --enable-avisynth --enable-frei0r --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-openal --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libxvid --enable-libzvbi --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-libssh --enable-libsoxr --enable-libx264 --enable-libopencv --enable-libx265
  libavutil      54. 27.100 / 54. 27.100
  libavcodec     56. 41.100 / 56. 41.100
  libavformat    56. 36.100 / 56. 36.100
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 16.101 /  5. 16.101
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.100 /  1.  2.100
  libpostproc    53.  3.100 / 53.  3.100
Guessed Channel Layout for  Input Stream #0.0 : stereo
Input #0, alsa, from 'default':
  Duration: N/A, start: 1457422230.571465, bitrate: 1536 kb/s
    Stream #0:0: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
Input #1, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 4454.267377, bitrate: 165888 kb/s
    Stream #1:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 720x576, 165888 kb/s, 25 fps, 25 tbr, 1000k tbn, 1000k tbc
File 'zzz.mp4' already exists. Overwrite ? [y/N] y
No pixel format specified, yuv422p for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.                                
[libx264 @ 0x231cd00] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 LZCNT
[libx264 @ 0x231cd00] profile High 4:4:4 Predictive, level 3.0, 4:2:2 8-bit
[libx264 @ 0x231cd00] 264 - core 146 r2555 0c21480 - H.264/MPEG-4 AVC codec - Copyleft 2003-2015 - http://www.videolan.org/x264.html - options: cabac=1 ref=2 deblock=1:0:0 analyse=0x1:0x111 me=hex subme=6 psy=0 mixed_ref=1 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=1 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, mp4, to 'zzz.mp4':
  Metadata:
    encoder         : Lavf56.36.100
    Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv422p, 720x576, q=-1--1, 25 fps, 12800 tbn, 25 tbc
    Metadata:
      encoder         : Lavc56.41.100 libx264
    Stream #0:1: Audio: aac ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s
    Metadata:
      encoder         : Lavc56.41.100 aac
Stream mapping:
  Stream #1:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
  Stream #0:0 -> #0:1 (pcm_s16le (native) -> aac (native))
Press [q] to stop, [?] for help
[video4linux2,v4l2 @ 0x231a180] Thread message queue blocking; consider raising the thread_queue_size option (current value: 8)
[alsa @ 0x2301360] Thread message queue blocking; consider raising the thread_queue_size option (current value: 8)
[video4linux2,v4l2 @ 0x231a180] Dequeued v4l2 buffer contains 414720 bytes, but 829440 were expected. Flags: 0x00002005.
/dev/video0: Invalid data found when processing input
frame= 1962 fps= 17 q=-1.0 Lsize=  409086kB time=00:01:53.53 bitrate=29516.7kbits/s    
video:407234kB audio:1777kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.018333%
[libx264 @ 0x231cd00] frame I:346   Avg QP: 0.00  size:186290
[libx264 @ 0x231cd00] frame P:1616  Avg QP: 0.00  size:218162
[libx264 @ 0x231cd00] mb I  I16..4: 92.3%  0.0%  7.7%
[libx264 @ 0x231cd00] mb P  I16..4: 76.1%  0.0% 22.8%  P16..4:  0.2%  0.5%  0.4%  0.0%  0.0%    skip: 0.0%
[libx264 @ 0x231cd00] 8x8 transform intra:0.0% inter:76.8%
[libx264 @ 0x231cd00] coded y,uvDC,uvAC intra: 100.0% 100.0% 100.0% inter: 100.0% 100.0% 100.0%
[libx264 @ 0x231cd00] i16 v,h,dc,p:  0% 100%  0%  0%
[libx264 @ 0x231cd00] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 10% 78%  3%  1%  2%  3%  1%  3%  1%
[libx264 @ 0x231cd00] i8c dc,h,v,p:  1% 98%  0%  0%
[libx264 @ 0x231cd00] Weighted P-Frames: Y:31.7% UV:20.6%
[libx264 @ 0x231cd00] ref P L0: 52.8% 47.2%
[libx264 @ 0x231cd00] kb/s:42508.35

答案1

这个问题在 FFmpeg v4.3 中已得到解决https://github.com/FFmpeg/FFmpeg/commit/b761ae072a169eb183abe0785a258b9787e267d3这会使该错误成为警告,并且似乎会跳过该帧。

v4.3 于6月15日发布。

答案2

我找不到这个 ffmpeg 问题的任何解决方案,最近我发现本文说:

看起来,stk1160 设备将这些损坏的帧发送到 v4l2 设备,一旦它们到达 ffmpeg,它就会阻塞并报告无效帧。虽然这是 ffmpeg “诚实”质量的一部分,但我认为这是这里的一个错误,因为它退出了转码过程,使 ffmpeg 不适合手头的任务。

因此,我开始使用 mencoder。此博客帮助我开始使用 mencoder:http://easycap.blogspot.com/p/command-line-tv.html

我使用以下源代码编译了 MPlayer(包含 mencoder):http://www.mplayerhq.hu

答案3

这仍然是 ffmpeg 3.3 中的一个错误。尽管 ffplay 可以在出现此错误后正确恢复(对我来说,这种情况发生在场景变化/快进时),但 ffmpeg 只是停止处理帧。我遇到了同样的问题设备,我无法让 mencoder 使用我想要的精确参数(尤其是关于去隔行),所以我使用了 mencoder(原始 AVI 到 stdout)和 ffmpeg(yadif 去隔行、映射音频、编码 x264 和 mux 到 mkv)的组合,效果很好。

您当然可以直接存储原始 AVI 数据,但由于速度约为 70GByte/h,我没有足够的空间来存储这些数据。

(部分摘自这里

mencoder -endpos 1:40:00 tv:// -tv device=/dev/video0:input=4:norm=PAL:width=720:height=576:alsa:adevice=hw.3:forceaudio:buffersize=128 -oac pcm -ovc copy -o - -really-quiet | ffmpeg -i - -vf yadif=mode=send_field:parity=tff -map_channel 0.1.1 -c:a flac -c:v libx264 -preset veryfast -crf 16 011.mkv

相关内容