Naprawianie opóźnienia ffmpeg narastającego w czasie

3

Mam ffmpeg / ffserver działający w następującej konfiguracji:

10.1.2.2 przechwytuje z kart przechwytywania wideo (16 kanałów) i przesyła je strumieniowo do serwera ffserver jako mpeg1video

10.1.1.1/10.1.2.1 (dwie karty sieciowe) obsługuje serwer ffserver i niektóre procesy, które konwertują strumienie mpeg1video na strumienie webm wraz z zoneminder (zasilający oryginalne strumienie ffmpeg). 10.1.2.2 i 10.1.2.1 są połączone kablem gigabitowym. Dyrektor / tmp jest zamontowany jako 128 MB pamięci RAM przez tmpfs.

Strumień mpeg1video jest zawsze opóźniony o 0,1-0,2 sekundy za strumieniem webm, co jest dla mnie całkowicie akceptowalne (ale wspominam o nim, ponieważ może być przydatny w rozwiązywaniu problemów).

Po ponownym uruchomieniu wszystkie strumienie są opóźnione o 3-5 sekund (chciałbym zmniejszyć to opóźnienie - mogę oglądać każdy pojedynczy strumień bezpośrednio z urządzenia wideo na żywo, więc być może otrzymuję je w niewłaściwym formacie, z wyjątkiem za opóźnienie złożone). Po uruchomieniu przez noc strumienie nadal pojawiają się „na żywo” (płynny ruch) zarówno w formatach mpeg1video, jak i webm, ale są wyraźnie opóźnione o 4-5 GODZIN (co widać po fakcie, że moje zdumienie zgasło, kiedy weszłam w to miejsce) rano i utrzymywałem ekrany obserwując je aż do 4-5 godzin po tym, jak ludzie zaczęli przychodzić tego ranka, zapaliły się światła [ale nie wszystkie razem, wydaje się, że również nie synchronizują się nawzajem]).

Oto procesy, których używam:

W dniu 10.1.2.2:

ffmpeg -f video4linux2 -standard ntsc -i /dev/video0 http://10.1.2.1:8090/0.ffm

W dniu 10.1.2.1/10.1.1.15:

ffserver -f /etc/ffserver.conf
ffmpeg -f mpegvideo -i http://localhost:8090/0.mpg -vcodec libvpx http://localhost:8090/0_webm.ffm

I fragment z /etc/ffserver.conf z 10.1.2.1/10.1.1.15:

Port 8090
MaxHTTPConnections 2000
MAXClients 100
MaxBandwidth 1000000
CustomLog /var/log/ffserver
NoDaemon

<Feed 0.ffm>
File /tmp/0.ffm
FileMaxSize 1M
ACL allow 10.1.2.2
</Feed>

<Feed 0_webm.ffm>
File /tmp/0_webm.ffm
FileMaxSize 1M
ACL allow localhost
</Feed>

<Stream 0.mpg>
Feed 0.ffm
Format mpeg1video
NoAudio
VideoFrameRate 29.97
VideoBitRate 512K
VideoSize 320x240
VideoBufferSize 40
VideoGopSize 12
#VideoIntraOnly
</Stream>

<Stream 0.webm>
Feed 0_webm.ffm
Format webm
NoAudio
VideoCodec libvpx
VideoSize 320x240
VideoFrameRate 29.97
AVOptionVideo flags +global_header
AVOptionVideo cpu-used 0
AVOptionVideo quality good
PreRoll 0
StartSendOnKey
VideoGopSize 12
VideoBitRate 256
</Stream>

Teraz 1 MB jest zdecydowanie za mały, aby pomieścić 4-5 godzin strumieniowego przesyłania wideo przy 29,97 klatkach na sekundę i rozdzielczości 320 x 240 w kolorze yuv420p - więc moje pytania brzmią: co się tutaj dzieje i jak to naprawić? Wydaje mi się, że coś dzieje się w początkowym procesie ffmpeg w 10.1.2.2, ale nie mogę się zorientować, czy ffmpeg używa własnego bufora, czy może istnieje polecenie, którego można użyć, aby zmusić go do usunięcia dowolnego nadmierne klatki podczas wyciągania z karty graficznej - to po prostu zrobić migawkę tak szybko, jak to możliwe i wysłać z bufora pojedynczego obrazu do ffserver, aby upewnić się, że to, co jest wysyłane, jest zawsze aktywne?

Moim celem jest transmisja na żywo do zonemindera i przesyłanie strumienia na żywo w formacie webm dla każdego z 16 kanałów (0-15) - więc jestem otwarty na każde rozwiązanie, ale wolałbym coś opartego na ffmpeg / ffserver, ponieważ wydają się być złotym standardem w Linuxie dla takich zadań.

Początkowe opóźnienie wynoszące 3-5 sekund i opóźnienie 4-5 godzin mogą być również różnymi problemami. Kiedy zabijam 10.1.2.2 poprzez „sudo restart”, poszczególne strumienie mpg / webm wycinają się z 10.1.1.15, więc wygląda na to, że wewnątrz ffserver zachodzi buforowanie, które wykracza poza zwykłe przekazywanie strumienie.

Edycja: próbowałem zredukować wszystkie kanały FileMaxSize do 30K, a 3-5 sekundowe opóźnienie nadal występuje we wszystkich strumieniach. To samo opóźnienie istnieje, niezależnie od tego, czy w 10.1.2.2 jest 16, czy tylko 1 proces ffmpeg.

Dane wyjściowe dziennika:

Serwer:

sudo ffserver -f /etc/ffserver.conf -d

ffserver version git-2013-03-15-cd5f50a Copyright (c) 2000-2013 the FFmpeg developers
  built on Mar 15 2013 14:03:16 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: --enable-gpl --enable-libass --enable-libfaac --enable-libfdk-aac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libspeex --enable-librtmp --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-version3
  libavutil      52. 19.100 / 52. 19.100
  libavcodec     55.  0.100 / 55.  0.100
  libavformat    55.  0.100 / 55.  0.100
  libavdevice    55.  0.100 / 55.  0.100
  libavfilter     3. 45.104 /  3. 45.104
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
Thu Mar 21 14:08:53 2013 FFserver started.
Thu Mar 21 14:08:57 2013 10.1.3.2 - - New connection: GET /15.ffm
Thu Mar 21 14:08:57 2013 10.1.3.2 - - [GET] "/15.ffm HTTP/1.1" 200 4175
Thu Mar 21 14:08:57 2013 10.1.3.2 - - New connection: POST /15.ffm
Thu Mar 21 14:09:03 2013 127.0.0.1 - - New connection: GET /15.mpg
Thu Mar 21 14:09:06 2013 127.0.0.1 - - New connection: GET /15_webm.ffm
Thu Mar 21 14:09:06 2013 127.0.0.1 - - [GET] "/15_webm.ffm HTTP/1.1" 200 4175

sudo ffmpeg -f video4linux2 -standard ntsc -i /dev/video7 http://10.1.3.1:8090/15.ffm

urządzenie wideo -> mpg

ffmpeg version git-2013-03-21-4331484 Copyright (c) 2000-2013 the FFmpeg developers
  built on Mar 20 2013 20:44:06 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: --enable-gpl --enable-libass --enable-libfaac --enable-libfdk-aac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libspeex --enable-librtmp --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-version3
  libavutil      52. 22.100 / 52. 22.100
  libavcodec     55.  1.100 / 55.  1.100
  libavformat    55.  0.100 / 55.  0.100
  libavdevice    55.  0.100 / 55.  0.100
  libavfilter     3. 48.100 /  3. 48.100
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
[video4linux2,v4l2 @ 0xa1d34c0] Estimating duration from bitrate, this may be inaccurate
Input #0, video4linux2,v4l2, from '/dev/video7':
  Duration: N/A, start: 1363889339.048888, bitrate: 27620 kb/s
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240, 27620 kb/s, 29.97 fps, 29.97 tbr, 1000k tbn, 1000k tbc
Output #0, ffm, to 'http://10.1.3.1:8090/15.ffm':
  Metadata:
    creation_time   : now
    encoder         : Lavf55.0.100
    Stream #0:0: Video: mpeg1video, yuv420p, 320x240, q=2-31, 512 kb/s, 1000k tbn, 29.97 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo -> mpeg1video)
Press [q] to stop, [?] for help
frame= 3552 fps= 30 q=5.5 size=    7644kB time=00:01:58.45 bitrate= 528.7kbits/s

ffmpeg -f mpegvideo -i http://localhost:8090/15.mpg -vcodec libvpx http://localhost:8090/15_webm.ffm

mpg -> webm

ffmpeg version git-2013-03-15-cd5f50a Copyright (c) 2000-2013 the FFmpeg developers
  built on Mar 15 2013 14:03:16 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: --enable-gpl --enable-libass --enable-libfaac --enable-libfdk-aac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libspeex --enable-librtmp --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-version3
  libavutil      52. 19.100 / 52. 19.100
  libavcodec     55.  0.100 / 55.  0.100
  libavformat    55.  0.100 / 55.  0.100
  libavdevice    55.  0.100 / 55.  0.100
  libavfilter     3. 45.104 /  3. 45.104
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
[mpeg1video @ 0x3901000] 0x0 is invalid
    Last message repeated 2 times
[mpegvideo @ 0x38f4f80] max_analyze_duration 5000000 reached at 5011633 microseconds
[mpegvideo @ 0x38f4f80] Estimating duration from bitrate, this may be inaccurate
Input #0, mpegvideo, from 'http://localhost:8090/15.mpg':
  Duration: N/A, bitrate: 1024 kb/s
    Stream #0:0: Video: mpeg1video, yuv420p, 320x240 [SAR 1:1 DAR 4:3], 1024 kb/s, 29.92 fps, 29.97 tbr, 1200k tbn, 29.97 tbc
[libvpx @ 0x39046a0] v1.2.0
Output #0, ffm, to 'http://localhost:8090/15_webm.ffm':
  Metadata:
    creation_time   : now
    encoder         : Lavf55.0.100
    Stream #0:0: Video: vp8, yuv420p, 320x240 [SAR 1:1 DAR 4:3], q=1-31, 128 kb/s, 1000k tbn, 29.97 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg1video -> libvpx)
Press [q] to stop, [?] for help
frame= 4845 fps= 31 q=0.0 size=    4192kB time=00:02:41.66 bitrate= 212.4kbits/s dup=4 drop=0

Dodanie większej wydajności na żądanie:

$v4l
No command 'v4l' found, did you mean:
 Command 'vl' from package 'atfs' (universe)
 Command 'dv4l' from package 'dv4l' (universe)
v4l: command not found

$v4l2
No command 'v4l2' found, did you mean:
 Command 'qv4l2' from package 'qv4l2' (universe)
v4l2: command not found

$ sudo ffprobe -show_streams -show_format -f video4linux2 /dev/video0
ffprobe version git-2013-03-16-c9a51c2 Copyright (c) 2007-2013 the FFmpeg developers
  built on Mar 16 2013 18:48:40 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: --enable-gpl --enable-libass --enable-libfaac --enable-libfdk-aac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libspeex --enable-librtmp --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-version3
  libavutil      52. 19.100 / 52. 19.100
  libavcodec     55.  0.100 / 55.  0.100
  libavformat    55.  0.100 / 55.  0.100
  libavdevice    55.  0.100 / 55.  0.100
  libavfilter     3. 47.100 /  3. 47.100
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
[video4linux2,v4l2 @ 0xb0a0540] Estimating duration from bitrate, this may be inaccurate
Input #0, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 1364261173.317100, bitrate: 27620 kb/s
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240, 27620 kb/s, 29.97 fps, 29.97 tbr, 1000k tbn, 1000k tbc
[STREAM]
index=0
codec_name=rawvideo
codec_long_name=raw video
profile=unknown
codec_type=video
codec_time_base=1/1000000
codec_tag_string=I420
codec_tag=0x30323449
width=320
height=240
has_b_frames=0
sample_aspect_ratio=0:1
display_aspect_ratio=0:1
pix_fmt=yuv420p
level=-99
timecode=N/A
id=N/A
r_frame_rate=30000/1001
avg_frame_rate=30000/1001
time_base=1/1000000
start_pts=1364261173317100
start_time=1364261173.317100
duration_ts=N/A
duration=N/A
bit_rate=27620379
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
[/STREAM]
[FORMAT]
filename=/dev/video0
nb_streams=1
format_name=video4linux2,v4l2
format_long_name=Video4Linux2 device grab
start_time=1364261173.317100
duration=N/A
size=N/A
bit_rate=27620379
[/FORMAT]

Obie karty przechwytywania wideo są 8-kanałowe bt878a przy użyciu sterownika bttv z konfiguracją /etc/modprobe.d/bttv.conf, zgodnie z instrukcją producenta na każdym z dwóch urządzeń zawierających karty:

options i2c-algo-bit_test=1
options bttv gbuffers=16 card=102,102,102,102,102,102,102,102 radio=0,0,0,0,0,0,0,0 tuner=4,4,4,4,4,4,4,4 chroma_agc=1 combfilter=2 full_luma_range=1 coring=1 autoload=0

Na lokalnych komputerach za pomocą:

ffplay -f video4linux2 -standard ntsc -i /dev/video0

Działa w czasie rzeczywistym i wydaje się, że nie powoduje opóźnień bez względu na to, jak długo działa.

CoryG
źródło
1
Czy wypróbowałeś opcję wiersza polecenia -r dla 10.1.2.2, np. ffmpeg -f video4linux2 -standard ntsc -i /dev/video0 -r 29.97 http://10.1.2.1:8090/0.ffm?
alldayremix
Tak, próbowałem -r -b -s i -vcodec, efekt był taki sam w każdym przypadku.
CoryG
1
Czy możesz uruchomić ffmpeg / ffserver z opcją -d (debugowanie) i opublikować tutaj wynik?
alldayremix
Właśnie je dodałem.
CoryG
1
Te wyglądają dobrze, więc zdobądźmy więcej informacji. Co robić v4l /dev/video0i ffprobe -show_streams -show_format -f video4linux2 /dev/video0dać?
alldayremix,