![ffmpeg 视频录制在“处理输入时发现无效数据”后冻结](https://linux22.com/image/1485528/ffmpeg%20%E8%A7%86%E9%A2%91%E5%BD%95%E5%88%B6%E5%9C%A8%E2%80%9C%E5%A4%84%E7%90%86%E8%BE%93%E5%85%A5%E6%97%B6%E5%8F%91%E7%8E%B0%E6%97%A0%E6%95%88%E6%95%B0%E6%8D%AE%E2%80%9D%E5%90%8E%E5%86%BB%E7%BB%93.png)
我正在尝试使用 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