Flush & Latency Problem mit fragmentierter MP4-Erstellung in FFMPEG

8

Ich erstelle einen fragmentierten mp4 für html5-streaming mit dem folgenden Befehl:

%Vor%
  1. "- i rtsp: //172.20.28.52: 554 / h264" weil die Quelle h264 im rtp-Paketstrom von einer IP-Kamera ist. Aus Gründen des Testens wird die Kamera mit GOP von 1 gesetzt (d. H. Alle Frames sind Keyframes)
  2. "- vcodec copy", weil ich keine Transcodierung benötige, sondern nur eine Remuxfunktion für mp4.
  3. "- movflags empty_moov + default_base_moof + frag_keyframe" zum Erstellen eines fragmentierten mp4 gemäß der Media Source Extensions-Spezifikation.
  4. "-" am Ende, um mp4 auf stdout auszugeben. Ich nehme die Ausgabe und schicke sie über Web-Sockets an den Webclient.

Alles funktioniert gut, erwarte ein Latenzproblem, das ich versuche zu lösen. Wenn ich jedes Mal logge, wenn Daten von stdout kommen, mit dem Zeitstempel der Ankunft, bekomme ich diese Ausgabe:

  

16.06.2015 15: 40: 45.239 hat Datengröße = 24

     

16.06.2015 15: 40: 45.240 hat Datengröße = 7197

     

16.06.2015 15: 40: 45.241 hat Datengröße = 32768

     

16.06.2015 15: 40: 45.241 hat Datengröße = 4941

     

16.06.2015 15: 40: 45.241 hat Datengröße = 12606

     

16.06.2015 15: 40: 45.241 hat Datengröße = 6345

     

16.06.2015 15: 40: 45.241 hat Datengröße = 6339

     

16.06.2015 15: 40: 45.242 hat Datengröße = 6336

     

16.06.2015 15: 40: 45.242 hat Datengröße = 6361

     

16.06.2015 15: 40: 45.242 hat Datengröße = 6337

     

16.06.2015 15: 40: 45.242 hat Datengröße = 6331

     

16.06.2015 15: 40: 45.242 hat Datengröße = 6359

     

16.06.2015 15: 40: 45.243 hat Datengröße = 6346

     

16.06.2015 15: 40: 45.243 hat Datengröße = 6336

     

16.06.2015 15: 40: 45.243 hat Datengröße = 6338

     

16.06.2015 15: 40: 45.243 hat Datengröße = 6357

     

16.06.2015 15: 40: 45.243 hat Datengröße = 6357

     

16.06.2015 15: 40: 45.243 hat Datengröße = 6322

     

16.06.2015 15: 40: 45.243 hat Datengröße = 6359

     

16.06.2015 15: 40: 45.244 hat Datengröße = 6349

     

16.06.2015 15: 40: 45.244 hat Datengröße = 6353

     

16.06.2015 15: 40: 45.244 hat Datengröße = 6382

     

16.06.2015 15: 40: 45.244 hat Datengröße = 6403

     

16.06.2015 15: 40: 45.304 hat Datengröße = 6393

     

16.06.2015 15: 40: 45.371 hat Datengröße = 6372

     

16.06.2015 15: 40: 45.437 hat Datengröße = 6345

     

16.06.2015 15: 40: 45.504 hat Datengröße = 6352

     

16.06.2015 15: 40: 45.571 hat Datengröße = 6340

     

16.06.2015 15: 40: 45,637 hat Datengröße = 6331

     

16.06.2015 15: 40: 45.704 hat Datengröße = 6326

     

16.06.2015 15: 40: 45.771 hat Datengröße = 6360

     

16.06.2015 15: 40: 45.838 hat Datengröße = 6294

     

16.06.2015 15: 40: 45.904 hat Datengröße = 6328

     

16.06.2015 15: 40: 45.971 hat Datengröße = 6326

     

16.06.2015 15: 40: 46.038 hat Datengröße = 6326

     

16.06.2015 15: 40: 46.105 hat Datengröße = 6340

     

16.06.2015 15: 40: 46.171 hat Datengröße = 6341

     

16.06.2015 15: 40: 46.238 hat Datengröße = 6332

Wie Sie sehen können, werden die ersten 23 Zeilen (die Daten von etwa 1,5 Sekunden Video enthalten) fast augenblicklich ankommen, und dann ist die Verzögerung zwischen jeweils 2 aufeinanderfolgenden Zeilen ~ 70 ms, was sinnvoll ist, weil das Video 15 Bilder pro ist sek. Dieses Verhalten führt zu einer Wartezeit von ca. 1,5 Sekunden.

Es sieht aus wie ein Flush-Problem, weil ich keinen Grund sehe, warum ffmpeg die ersten 23 Frames im Speicher halten müsste, besonders da jedes Frame ein eigenes Fragment in mp4 ist. Ich konnte jedoch keine Methode finden, die ffmpeg veranlassen würde, diese Daten schneller zu löschen.

Hat jemand einen Vorschlag?

Ich möchte darauf hinweisen, dass dies eine Folgefrage zu diesem Thema ist: Live-Streaming-Dash-Inhalt mit mp4box

    
galbarm 16.06.2015, 13:23
quelle

3 Antworten

4

Der Schlüssel zum Entfernen der Verzögerung ist die Verwendung des Arguments -probesize:

  

probesize Ganzzahl (Eingabe)

     

Stellen Sie die Prüfgröße in Bytes ein, also die Größe von   die zu analysierenden Daten, um Strominformationen zu erhalten. Ein höherer Wert wird   Aktivieren Sie die Erkennung von mehr Informationen für den Fall, dass es in die verstreut ist   streamen, wird aber die Latenz erhöhen. Muss eine Ganzzahl nicht kleiner als sein   32. Es ist 5000000 standardmäßig.

Standardmäßig ist der Wert 5.000.000 Bytes, was ~ 1.5 Sekunden Video entspricht. Ich konnte die Verzögerung fast vollständig eliminieren, indem ich den Wert auf 200.000 reduzierte.

    
galbarm 30.09.2015, 07:49
quelle
0

Ich habe das Latenzproblem gelöst, indem ich die Anzahl der Frames in der Gruppe mit der Option -g festgelegt habe. In meinem Fall habe ich -g 2 verwendet. Ich vermute, dass das Fragment entweder wartet, bis die Quelle das Schlüsselbild bereitstellt, oder verwendet einen wirklich großen Standardwert, um das Schlüsselbild zu generieren, bevor das Fragment geschlossen und in stdout abgelegt wird.

    
Brian Adams 30.07.2015 05:14
quelle
0

Normalerweise ist die Pufferung für stdout im Falle einer Konsolenausgabe deaktiviert. Wenn Sie ffmpeg aus dem Code ausführen, ist die Pufferung aktiviert, so dass Sie Ihre Daten nur erhalten, wenn der Puffer voll ist oder der Befehl endet.

Sie müssen die Pufferung der Standardausgabe Ihres Betriebssystems beseitigen. Auf Windows ist es unmöglich imo, aber auf Ubuntu für ex. Es gibt Ссылка

    
curtiss 26.08.2015 06:33
quelle