LINUX.ORG.RU

ffmpeg: бьётся мультикаст

 , ,


0

2

Здравствуй, достопочтенный All! Я сейчас, наверное, опять идиотские вопросы буду задавать... :( Есть очень простая задачка. Надо взять файл и завещать его в мультикаст (udp) с помощью ffmpeg. Только формат на MPEG2TS сменить. Казалось бы, чего проще?

ffmpeg -re -i file.mp4 -codec copy -f mpegts udp://234.2.2.70:1234

Но не тут-то было. Когда пытаюсь этот мультикаст просмотреть, вижу свинское месиво пикселей или причудливых вертикальных полос. При этом ни в какие ресурсы не упираемся, операция ведь пустяковая, проц почти не задействован. Смотрел как сдампленный multicat'ом кусок, так и сам мультикаст, проброшенный через udpxy. И multicat, и udpxy запускались на той же самой машине, т.е. мультикасту вроде некуда теряться... Но VLC-плеер при просмотре гадит в логи вот таким:

...
ts debug: skipping 32 bytes of garbage
ts warning: discontinuity received 0xf instead of 0xd (pid=256)
ts warning: lost synchro
ts debug: skipping 32 bytes of garbage
ts warning: discontinuity received 0x7 instead of 0x5 (pid=256)
ts error: libdvbpsi error (PSI decoder): TS discontinuity (received 5, expected 4) for PID 0
ts debug: PATCallBack called
ts error: libdvbpsi error (PSI decoder): TS discontinuity (received 5, expected 4) for PID 4096
ts debug: PMTCallBack called
ts warning: lost synchro
ts debug: skipping 32 bytes of garbage
ts warning: discontinuity received 0xd instead of 0xb (pid=256)
...
и таким:
...
[h264 @ 037eabc0] Reference 3 >= 3
[h264 @ 037eabc0] error while decoding MB 8 1, bytestream 28465
[h264 @ 03155ac0] top block unavailable for requested intra4x4 mode -1 at 21 0
[h264 @ 03155ac0] error while decoding MB 21 0, bytestream 28715
[h264 @ 037ea7c0] Reference 2 >= 2
[h264 @ 037ea7c0] error while decoding MB 58 1, bytestream 21391
[h264 @ 037eabc0] top block unavailable for requested intra4x4 mode -1 at 18 0
[h264 @ 037eabc0] error while decoding MB 18 0, bytestream 133199
[h264 @ 03155ac0] top block unavailable for requested intra mode at 42 0
[h264 @ 03155ac0] error while decoding MB 42 0, bytestream 97706
[h264 @ 037ea7c0] Reference 3 >= 2
...

При этом если сконвертировать файл в MPEGTS

ffmpeg -re -i file.mp4 -codec copy -f mpegts file.ts
то он прекрасно проигрывается, т.е. проблем в исходном файле нет. Но когда пытаешься завещать мультикаст из файла *.ts, то результат - тот же. Месиво.

Вот исходный файл:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'file1.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp42mp41
    creation_time   : 2014-10-24T15:28:57.000000Z
  Duration: 00:03:15.05, start: 0.000000, bitrate: 19783 kb/s
    Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv), 1920x1080 [SAR 1:1 DAR 16:9], 19469 kb/s, 25 fps, 25 tbr, 25k tbn, 50 tbc (default)
    Metadata:
      creation_time   : 2014-10-24T15:28:57.000000Z
      handler_name    : Alias Data Handler
      encoder         : AVC Coding
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 317 kb/s (default)
    Metadata:
      creation_time   : 2014-10-24T15:28:57.000000Z
      handler_name    : Alias Data Handler

Вроде никакого криминала нет... Где же могут быть грабли? Я могу, конечно, явным образом задать нужные параметры кодирования и, наверное, это улучшит ситуацию. Но мне хочется понять, почему не получается простая перепаковка.

Да, забыл сказать. ffmpeg 3.2.2, собран руками:

ffmpeg version 3.2.2 Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 4.2.1 (GCC) 20070831 patched [FreeBSD]
configuration: --enable-shared --enable-gpl --enable-postproc --enable-avfilter --enable-avresample --enable-pthreads --disable-libsoxr --cc=cc --extra-cflags='-I/usr/local/include/vorbis -I/usr/local/include' --extra-ldflags='-L/usr/local/lib ' --extra-libs=-lpthread --enable-memalign-hack --disable-indev=alsa --disable-outdev=alsa --disable-libopencore-amrnb --disable-libopencore-amrwb --enable-libass --disable-libbs2b --disable-libcaca --disable-libcdio --disable-libcelt --disable-libdc1394 --disable-stripping --enable-htmlpages --enable-libfdk-aac --enable-ffserver --disable-libflite --disable-fontconfig --enable-libfreetype --enable-frei0r --disable-libfribidi --disable-libgme --disable-libgsm --enable-iconv --enable-libilbc --disable-indev=jack --disable-libkvazaar --disable-ladspa --enable-libmp3lame --disable-libbluray --enable-mmx --disable-libmodplug --disable-openal --disable-indev=openal --disable-opencl --enable-libopencv --disable-opengl --enable-libopenh264 --disable-libopenjpeg --disable-libopus --disable-libpulse --disable-indev=pulse --disable-outdev=pulse --enable-runtime-cpudetect --disable-librtmp --enable-libschroedinger --disable-ffplay --disable-outdev=sdl --enable-libsmbclient --disable-libsnappy --disable-libspeex --disable-sse --disable-libssh --enable-libtheora --disable-libtwolame --disable-libv4l2 --disable-indev=v4l2 --disable-outdev=v4l2 --disable-vaapi --disable-vdpau --enable-libvidstab --enable-libvorbis --disable-libvo-amrwbenc --enable-libvpx --disable-libwavpack --disable-libwebp --disable-x11grab --enable-libx264 --disable-libx265 --disable-libxcb --enable-libxvid --disable-outdev=xv --disable-libzmq --disable-libzvbi --enable-gnutls --disable-openssl --enable-version3 --enable-nonfree
libavutil      55. 34.100 / 55. 34.100
libavcodec     57. 64.101 / 57. 64.101
libavformat    57. 56.100 / 57. 56.100
libavdevice    57.  1.100 / 57.  1.100
libavfilter     6. 65.100 /  6. 65.100
libavresample   3.  1.  0 /  3.  1.  0
libswscale      4.  2.100 /  4.  2.100
libswresample   2.  3.100 /  2.  3.100
libpostproc    54.  1.100 / 54.  1.100

Если пытаюсь кодировать явным образом, напр., так:

ffmpeg -hide_banner -re -i file1.mp4 \
-c:v libx264 -aspect 16:9 -profile:v main -preset:v slow -x264opts force-cfr:subme=7:ref=4 -threads 0 -r 25 -b:v 5120k -maxrate 5120k -bufsize 4096k -g 250 -keyint_min 75 -crf 28 \
-c:a copy \
-f mpegts udp://234.2.2.70:1234
то получаю немеряную простыню ошибок в консоли от ffmpeg:
...
[h264 @ 0x80b449310] concealing 6776 DC, 6776 AC, 6776 MV errors in B frame
[h264 @ 0x80b447a10] Reference 2 >= 2
[h264 @ 0x80b447a10] error while decoding MB 93 4, bytestream 92910
[h264 @ 0x80b447a10] concealing 7636 DC, 7636 AC, 7636 MV errors in B frame
[h264 @ 0x80b447f10] concealing 3817 DC, 3817 AC, 3817 MV errors in B frame
[h264 @ 0x80b448410] Reference 2 >= 2242kB time=00:00:03.20 bitrate= 619.0kbits/s speed=0.38x
[h264 @ 0x80b448410] error while decoding MB 7 9, bytestream 87255
[h264 @ 0x80b448410] concealing 7122 DC, 7122 AC, 7122 MV errors in B frame
[h264 @ 0x80b448e10] concealing 7650 DC, 7650 AC, 7650 MV errors in B frame
[h264 @ 0x80b449310] concealing 6097 DC, 6097 AC, 6097 MV errors in B frame
[h264 @ 0x80b447510] Reference 4 >= 2
[h264 @ 0x80b447510] error while decoding MB 21 6, bytestream 89234
[h264 @ 0x80b447510] concealing 7468 DC, 7468 AC, 7468 MV errors in B frame
...

Abyrvalg
() автор топика

У вас скорее всего рассинхронизация параметров кодирования / декодирования на сервере (ffmpeg) и в клиенте (vlc). Дело в том что при малтикасте нету в потоке нету никаких параметров стрима и клиент при подхвате потока не может правельно выбрать / настроить кодек в результате вы получаете шум всместо картинки. Нужно четко прописать все параметры кодека на сервере и кленте чтоб VLC пытался декодировать именно то что закодировано а не чтото другое ...

zaz ★★★★
()
Ответ на: комментарий от zaz

То есть, вместо -c copy надо в сущности проводить перекодирование? Или речь идёт о том, чтобы приписать потоку некие атрибуты? Буду признателен, если подскажете поточнее :)

Кстати, попробовал завещать тот же file1.mp4 на старенькой машине с Виндой, прости господи.

ffmpeg version N-81664-g6f062eb Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 5.4.0 (GCC)
И там даже очень прилично получилось, никаких рассыпаний. Правда, скорость вещания болталась в районе 0,3-0,4x.

Abyrvalg
() автор топика

выглядит, как будто не хватает буферов udp, см. ss -u -a

добить в sysctl

net.core.rmem_max = 1048576
net.core.rmem_default=1048576
net.ipv4.udp_mem = 8388608 12582912 16777216

посмотреть кто еще трогает udp за хидеры, фаерволы всякие

hizel ★★★★★
()
Ответ на: комментарий от hizel

Да, у меня то же подозрение... Насчёт ss и прочего затруднительно - у меня FreeBSD... Впрочем, попробовал вот что:

$ sudo netstat -s -p udp
udp:
        131645542 datagrams received
        0 with incomplete header
        0 with bad data length field
        0 with bad checksum
        40689583 with no checksum
        541 dropped due to no socket
        91209111 broadcast/multicast datagrams undelivered
        135229 dropped due to full socket buffers
        0 not for hashed pcb
        40300661 delivered
        77337154 datagrams output
        0 times multicast source filter matched
И через некоторое время - то же самое:
$ sudo netstat -s -p udp
udp:
        131688316 datagrams received
        0 with incomplete header
        0 with bad data length field
        0 with bad checksum
        40689583 with no checksum
        541 dropped due to no socket
        91251871 broadcast/multicast datagrams undelivered
        135229 dropped due to full socket buffers
        0 not for hashed pcb
        40300675 delivered
        77379922 datagrams output
        0 times multicast source filter matched
Вижу, что дофига не дошло...

Abyrvalg
() автор топика
Ответ на: комментарий от Abyrvalg
ffmpeg -re -i FIA_GALA_2006.avi -fflags +genpts -c:v libx264 -profile:v high -b:v 2000K -g 25 -c:a copy -f mpegts udp://10.1.3.9:1234

ffplay udp://10.1.3.9:1234

Все запускалось на одной машине (10.1.3.9) - советую вам попробовать тоже самое (в качестве клиента брать именно ffplay из тойже поставки что и ffmpeg) чтобы исключить сетевые проблемы + не согласованость кодеков в ffmpeg - vlc

zaz ★★★★
()

Обычный h.264 рассчитан на хранение в файлах. Для вещания его надо преобразовать в h.264 annex B.

ffmpeg -re -i file.mp4 -codec copy -bsf h264_mp4toannexb -f mpegts udp://234.2.2.70:1234

fopen ★★
()
Ответ на: комментарий от fopen

Всем снова привет!

Большое спасибо zaz и fopen за рекомендации.

Я не обратил сразу внимания, что исходный файл слишком жирный - с битрейтом около 20M. Немудрено, что буфера переполняются, а транскодирование адово тормозит. Поэтому я, скомбинировав обе рекомендации, сперва перевёл его в файл MPEG TS с более щадящим битрейтом, а затем уже этот файл без особых проблем завещал в мультикаст с копированием кодеков.

А всякая хрень с concealing... error... - это проблемы сборки свежих версий ffmpeg на FreeBSD. Лечится.

Abyrvalg
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.