Привет! У меня есть два источника входящего видео и три источника входящего аудио. Надо взять все это добро и синхронно записать в один файл при помощи ffmpeg - видео объединяется в формате "картинка в картинке", аудио добавляется отдельными дорожками. Проблема в том что у источников у меня разный fps - /dev/video0 отдает 60 FPS , /dev/video1 - 30 FPS. Результирующий FPS ожидается 60. Так вот, если убрать 30-фпс'ный источник то проблем никаких. Если с обоих источников брать 30 и записывать результат в 30 - проблем никаких. Если добавить 30-fps-input после инпута на 60 и перед входящими аудиопотоками - аудио рассинхронивается с 60-фпсным потоком. Если добавить 30fps в самое начало или конец цепочки инпутов - оно получается несинхронным с другим видеопотоком.
Я перепробовал уже кучу вариантов async\vsync, экспериментировал с таймстампами, pts'ами и прочей этой лабудой. Это не дает вообще ничего. Самое классное что ffmpeg при запуске показывает что типа "есть поток 1, у него время запуска 10; а вот поток 2 - у него время запуска 15", и дальше у меня эти пять секунд расхождения стабильно присутствуют в видео. Советы типа "сделай оффсет" не подойдут - эта задержка каждый раз разная, и я понятия не имею чем она вызвана, потому что стоящий рядом mplayer\vlc открывают девайсы практически мгновенно, ffmpegу надо тупить по 10 секунд на каждый инпут. Какого хрена он сам не может засинхронить потоки, при том что знает какая разница между ними, я не могу понять.
В общем, прошу помощи, у меня сил воевать с этим больше нет, идеи кончились, я несколько дней уже туплю над этим и похоже сам не справлюсь. Ах, да, рядом стоящий OBS отлично справляется с задачей синхронизации инпутов вообще из коробки (но не делает некоторые важные штуки, которые может ffmpeg).
Текущий вариант запуска с логами (тут я подождал всего пять секунд, но не важно, оно и через полчаса абсолютно также работает):
$ ffmpeg -y -f v4l2 -thread_queue_size 512 -input_format yuyv422 -pix_fmt yuv420p -s 320x240 -framerate 30 -i /dev/video1 -f v4l2 -thread_queue_size 512 -input_format yuyv422 -pix_fmt yuv420p -s 1920x1080 -framerate 60 -i /dev/video0 -f pulse -guess_layout_max 0 -thread_queue_size 512 -channels 2 -i alsa_input.dev1.analog-stereo -f pulse -guess_layout_max 0 -thread_queue_size 512 -channels 2 -i alsa_input.dev2.analog-stereo -f pulse -guess_layout_max 0 -thread_queue_size 512 -channels 2 -i alsa_input.dev3.analog-stereo -filter_complex "[0:v]pad=height=ih+10:color=black[b]; [1:v][b]overlay=(main_w-overlay_w):main_h-overlay_h[o]" -c:a libfdk_aac -ac 2 -q:v 2 -c:v mjpeg -r 60 -muxdelay 0 -map [o] -map 2:a /tmp/output.mkv
ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 9 (Debian 9.2.1-28)
configuration: --disable-decoder=amrnb --disable-decoder=libopenjpeg --disable-gnutls --disable-libopencv --disable-podpages --disable-sndio --disable-stripping --enable-avfilter --enable-gcrypt --enable-gpl --enable-ladspa --enable-libaom --enable-libaribb24 --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libfdk-aac --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libjack --enable-libkvazaar --enable-liblensfun --enable-libmp3lame --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libwebp --enable-libzvbi --enable-lv2 --enable-nonfree --enable-openal --enable-opencl --enable-opengl --enable-openssl --enable-postproc --enable-pthreads --enable-shared --enable-version3 --incdir=/usr/include/x86_64-linux-gnu --libdir=/usr/lib/x86_64-linux-gnu --prefix=/usr --toolchain=hardened --enable-frei0r --enable-chromaprint --enable-libx264 --enable-libiec61883 --enable-libdc1394 --enable-vaapi --enable-libmfx --enable-libvmaf --disable-altivec --shlibdir=/usr/lib/x86_64-linux-gnu
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
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, video4linux2,v4l2, from '/dev/video1':
Duration: N/A, start: 21674.247421, bitrate: 36864 kb/s
Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 320x240, 36864 kb/s, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Input #1, video4linux2,v4l2, from '/dev/video0':
Duration: N/A, start: 21682.714085, bitrate: 1990656 kb/s
Stream #1:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1920x1080, 1990656 kb/s, 60 fps, 60 tbr, 1000k tbn, 1000k tbc
Input #2, pulse, from 'alsa_input.dev1.analog-stereo':
Duration: N/A, start: 1584448360.733878, bitrate: 1536 kb/s
Stream #2:0: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
Input #3, pulse, from 'alsa_input.dev2.analog-stereo':
Duration: N/A, start: 1584448361.639887, bitrate: 1536 kb/s
Stream #3:0: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
Input #4, pulse, from 'alsa_input.dev3.analog-stereo':
Duration: N/A, start: 1584448361.588144, bitrate: 1536 kb/s
Stream #4:0: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
Stream mapping:
Stream #0:0 (rawvideo) -> pad (graph 0)
Stream #1:0 (rawvideo) -> overlay:main (graph 0)
overlay (graph 0) -> Stream #0:0 (mjpeg)
Stream #2:0 -> #0:1 (pcm_s16le (native) -> aac (libfdk_aac))
Press [q] to stop, [?] for help
[swscaler @ 0x55d4e89e5b00] deprecated pixel format used, make sure you did set range correctly
Output #0, matroska, to '/tmp/output.mkv':
Metadata:
encoder : Lavf58.29.100
Stream #0:0: Video: mjpeg (MJPG / 0x47504A4D), yuvj420p(pc, progressive), 1920x1080, q=2-31, 200 kb/s, 60 fps, 1k tbn, 60 tbc (default)
Metadata:
encoder : Lavc58.54.100 mjpeg
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
Stream #0:1: Audio: aac (libfdk_aac) ([255][0][0][0] / 0x00FF), 48000 Hz, stereo, s16, 139 kb/s
Metadata:
encoder : Lavc58.54.100 libfdk_aac
[libfdk_aac @ 0x55d4e89ab380] Queue input is backward in time
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 149, current: 2; changing to 149. This may result in incorrect timestamps in the output file.
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 149, current: 24; changing to 149. This may result in incorrect timestamps in the output file.
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 149, current: 45; changing to 149. This may result in incorrect timestamps in the output file.
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 149, current: 66; changing to 149. This may result in incorrect timestamps in the output file.
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 149, current: 88; changing to 149. This may result in incorrect timestamps in the output file.
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 149, current: 109; changing to 149. This may result in incorrect timestamps in the output file.
[libfdk_aac @ 0x55d4e89ab380] Queue input is backward in time
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 149, current: 130; changing to 149. This may result in incorrect timestamps in the output file.
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 152, current: 71; changing to 152. This may result in incorrect timestamps in the output file.
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 152, current: 92; changing to 152. This may result in incorrect timestamps in the output file.
[libfdk_aac @ 0x55d4e89ab380] Queue input is backward in time
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 152, current: 114; changing to 152. This may result in incorrect timestamps in the output file.
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 152, current: 135; changing to 152. This may result in incorrect timestamps in the output file.
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 152, current: 124; changing to 152. This may result in incorrect timestamps in the output file.
[matroska @ 0x55d4e89a57c0] Non-monotonous DTS in output stream 0:1; previous: 152, current: 145; changing to 152. This may result in incorrect timestamps in the output file.
[libfdk_aac @ 0x55d4e89ab380] Queue input is backward in time
frame= 249 fps= 43 q=2.0 Lsize= 23060kB time=00:00:05.85 bitrate=32286.8kbits/s speed=1.01x
video:22942kB audio:105kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.059679%
UPD: Забыл сказать - я пробовал всякими способовами конвертить входящие 30 fps в 60 (через minterpolate например) - это получается какая-то бредовая жесть с дерганными кадрами (даже когда говоришь что нужно дублировать рядомстоящий такое ощущение что оно их дергает из всего потока). И все равно даже так синхронности не удалось добиться.
Очень надеюсь на вашу помощь! Заранее огромное спасибо!