Die ersten Live-Übertragungen der Szene wurden vor fast 70 Jahren in Russland ausgestrahlt und von einem mobilen Fernsehsender (PTS) ausgestrahlt, der wie ein Obus aussah und es Ihnen ermöglichte, von außerhalb des Studios zu senden. Und noch vor drei Jahren durfte Periscope ein Mobiltelefon anstelle eines „Obus“ verwenden.
Diese Anwendung hatte jedoch eine Reihe von Problemen, die beispielsweise mit Verzögerungen bei der Ausstrahlung, der Unfähigkeit, Sendungen in hoher Qualität anzusehen, usw. verbunden waren.

Sechs Monate später, im Sommer 2016, startete Odnoklassniki seine mobile OK Live Streaming-Anwendung, mit der versucht wurde, diese Probleme zu lösen.
Alexander Tobol ist für den technischen Teil des Videos in Odnoklassniki verantwortlich und sprach bei Highload ++ 2017 darüber, wie Sie Ihr UDP-Protokoll schreiben und warum dies möglicherweise erforderlich ist.
Aus der Abschrift seines Berichts erfahren Sie alles über andere Video-Streaming-Protokolle, welche Nuancen es gibt und welche Tricks manchmal erforderlich sind.
Sie sagen, wir sollten immer mit Architektur und TK beginnen - angeblich ist das ohne das nicht möglich! Also lass es uns tun.
Architektur und TK
Auf der Folie unten sehen Sie das Architekturdiagramm eines Streaming-Dienstes: Das
Video wird dem Eingang zugeführt, konvertiert und zum Ausgang übertragen . Wir haben dieser Architektur etwas mehr Anforderungen hinzugefügt: Das Video sollte von Desktops und Mobiltelefonen geliefert werden, und die Ausgabe sollte an dieselben Desktops, Mobiltelefone, SmartTV, Chromcast, AppleTV und andere Geräte gehen - das gesamte Video kann abgespielt werden.

Als nächstes fahren wir mit der Leistungsbeschreibung fort. Wenn Sie einen Kunden haben, haben Sie TK. Wenn Sie ein soziales Netzwerk sind, haben Sie keine TK. Wie macht man das?
Sie können natürlich Benutzer interviewen und alles herausfinden, was sie wollen. Aber es wird eine ganze Reihe von Wünschen geben, die nicht mit dem korrelieren, was die Menschen wirklich brauchen.
Wir haben uns für den umgekehrten Weg entschieden und gesehen, was Benutzer vom Rundfunkdienst NICHT sehen wollten.
- Das erste, was der Benutzer nicht möchte, ist, die Verzögerung zu Beginn der Sendung zu sehen .
- Der Benutzer möchte kein Stream-Bild mit geringer Qualität sehen .
- Wenn die Sendung interaktiv ist, wenn der Benutzer mit seinem Publikum kommuniziert (entgegenkommende Live-Sendungen, Anrufe usw.), möchte er die Verzögerung zwischen dem Streamer und dem Betrachter nicht sehen .
So sieht ein normaler Streaming-Dienst aus. Mal sehen, was getan werden kann, um einen regulären Streaming-Dienst anstelle des üblichen durchzuführen.

Sie können sich zunächst alle Streaming-Protokolle ansehen, die interessantesten auswählen und vergleichen. Aber wir haben es anders gemacht.
Was haben Wettbewerber?
Wir haben zunächst die Dienstleistungen von Wettbewerbern untersucht.
Open Periscope - was haben sie?Hauptsache ist wie immer die Architektur.

Sara Hyder, Periscopes leitende Ingenieurin, schreibt, dass sie Wowza für das Backend verwenden. Wenn wir ein wenig mehr Artikel lesen, werden wir sehen, was sie mit dem
RTMP- Protokoll streamen, und es entweder in RTMP oder in HLS verteilen. Mal sehen, was diese Protokolle sind und wie sie funktionieren.
Wir testen Periscope auf unsere drei Hauptanforderungen.

Sie haben eine akzeptable
Startgeschwindigkeit (weniger als eine Sekunde in guten Netzwerken), eine konstante
Qualität von etwa 600 px (nicht HD) und gleichzeitig können
Verzögerungen bis zu 12 Sekunden betragen .
Wie kann man übrigens die Verzögerung des Rundfunks messen?

Dies ist ein Foto einer Verzögerungsmessung. Es gibt ein Handy mit Timer. Wir schalten die Sendung ein und sehen das Bild dieses Telefons auf dem Bildschirm. Für 0,15 Millisekunden fiel das Bild auf den Sensor der Kamera und wurde aus dem Videospeicher auf den Telefonbildschirm entfernt. Danach schalten wir den Browser ein und schauen uns die Sendung an.
Autsch! Sie ist etwas zurück - ungefähr 12 Sekunden.
Um die Gründe für die Verzögerung zu finden, stellen wir Video-Streaming vor.

Es gibt also ein Mobiltelefon, das Video geht von der Kamera und tritt in den Videopuffer ein. Hier sind die Verzögerungen minimal (~ 0,15 ms). Dann codiert der Codierer das Signal, packt es in ein Paket und sendet es an den Socket-Puffer. Es fliegt alles ins Web. Außerdem passiert dasselbe auf dem Empfangsgerät.
Grundsätzlich sind zwei Hauptprobleme zu berücksichtigen:
- Videokodierung / -decodierung;
- Netzwerkprotokolle .
Videokodierung / -decodierung
Ich werde ein wenig über das Codieren erzählen. Sie werden es trotzdem antreffen, wenn Sie Live-Streaming mit geringer Latenz durchführen.

Was ist ein Video? Dies ist eine Reihe von Frames, aber nicht ganz einfach. Es gibt drei Arten von Rahmen: I-, P- und B-Rahmen:
- I-Frame ist nur JPG. In der Tat ist dies ein Referenzrahmen, er hängt von niemandem ab und enthält ein klares Bild.
- P-Frame hängt ausschließlich von vorherigen Frames ab.
- Der knifflige B-Frame kann von der Zukunft abhängen. Dies bedeutet, dass zur Berechnung des B-Frames auch zukünftige Frames von der Kamera stammen müssen. Nur dann kann ein B-Frame mit einer gewissen Verzögerung decodiert werden.
Dies zeigt, dass
B- Frames schädlich sind . Versuchen wir, sie zu entfernen.
- Wenn Sie von einem mobilen Gerät streamen, können Sie versuchen , das Basisprofil zu aktivieren . Dadurch wird der B-Frame deaktiviert.
- Sie können versuchen, den Codec zu konfigurieren und die Verzögerung für zukünftige Frames zu verringern, damit Frames schneller eintreffen.
- Eine weitere wichtige Sache bei der Optimierung des Codecs ist die Einbeziehung von CBR (konstante Bitrate).

Wie Codecs funktionieren, ist in der obigen Folie dargestellt. In diesem Beispiel ist das Video ein statisches Bild, dessen Codierung Speicherplatz spart, weil Dort ändert sich fast nichts und die Videobitrate ist niedrig. Änderungen finden statt - die Entropie wächst, die Videobitrate wächst - es ist großartig, sie auf der Festplatte zu speichern.
Aber in dem Moment, in dem die aktiven Änderungen begannen und die Bitrate zunahm, würden sich höchstwahrscheinlich nicht alle Daten in das Netzwerk einschleichen. Dies ist genau das, was passiert, wenn Sie einen Videoanruf tätigen und sich umdrehen und Ihr Abonnent das Bild verlangsamt. Dies liegt an der Tatsache, dass das Netzwerk keine Zeit hat, sich an die Änderung der Bitrate anzupassen.
Man muss CBR einschließen . Nicht alle Android-Codecs werden es korrekt unterstützen, aber sie werden danach streben. Das heißt, Sie müssen verstehen, dass Sie mit CBR nicht das perfekte Bild der Welt erhalten, wie im unteren Bild, aber es lohnt sich trotzdem, es einzuschalten.
4. Und im Backend müssen Sie H264 den
Nullcatency- Codec hinzufügen.
Dadurch können Sie für die Zukunft keine Abhängigkeiten in Frames herstellen.
Videoübertragungsprotokolle
Überlegen Sie, welche Streaming-Protokolle die Branche anbietet. Ich habe sie bedingt in zwei Typen unterteilt:
- Streaming-Protokolle;
- Segmentprotokolle.
Streaming-Protokolle sind Protokolle aus der Welt der P2P-Aufrufe:
RTMP, webRTC, RTSP / RTP . Sie unterscheiden sich darin, dass Benutzer sich über den Kanal einig sind und die Codec-Bitrate entsprechend dem Kanal auswählen. Und sie haben auch zusätzliche Teams dieser Art, wie zum Beispiel "Gib mir einen Referenzschuss". Wenn Sie einen Frame verloren haben, können Sie ihn in diesen Protokollen erneut anfordern.
Der Unterschied zwischen
Segmentprotokollen besteht darin, dass niemand mit jemandem verhandelt. Sie schneiden Videos in Segmente, speichern jedes Segment in verschiedenen Qualitäten und der Kunde kann auswählen, welches Segment er ansehen möchte. Jedes Segment beginnt mit einem Referenzrahmen.
Betrachten Sie die Protokolle genauer. Beginnen wir mit Streaming-Protokollen und finden heraus, auf welche Probleme wir stoßen können, wenn wir Streaming-Protokolle für Broadcast-Streaming verwenden.
Streaming-Protokolle
Periscope verwendet RTMP. Dieses Protokoll wurde 2009 veröffentlicht und von Adobe zunächst nicht vollständig spezifiziert. Dann hatte er eine gewisse Schwierigkeit damit, dass Adobe ausschließlich seinen Server verkaufen wollte. Das heißt, RTMP entwickelte sich ziemlich schwierig. Sein Hauptproblem ist, dass
er TCP verwendet , aber aus irgendeinem Grund hat Periscope ihn ausgewählt.

Wenn Sie ausführlich lesen, stellt sich heraus, dass Periscope RTMP verwendet, um mit einer kleinen Anzahl von Zuschauern zu senden. Gerade solche Sendungen, wenn Sie einen unzureichenden Kanal haben, können Sie höchstwahrscheinlich nicht sehen.

Betrachten Sie ein bestimmtes Beispiel. Es gibt einen Benutzer mit einem engen Kommunikationskanal, der Ihre Sendung sieht. Sie stimmen ihm bei RTMP bezüglich der niedrigen Bitrate zu und beginnen, für ihn persönlich zu streamen.
Ein Benutzer mit coolem Internet kommt zu Ihnen, Sie haben auch cooles Internet, aber Sie haben sich bereits auf eine schlechte Qualität mit jemandem geeinigt, und es stellt sich heraus, dass dieser dritte Benutzer mit coolem Internet einen Stream in schlechter Qualität sieht, obwohl dies möglich ist gut aussehen
Wir haben uns entschlossen, dieses Problem zu beheben. Wir haben es möglich gemacht, dass RTMP für jeden Client einzeln abgeschnitten wird, dh, Streamer verhandeln mit dem Server, streamen mit der höchstmöglichen Qualität und jeder Client erhält die Qualität, die das Netzwerk zulässt.
Wow!
Trotzdem haben wir RTMP über TCP und niemand hat uns versichert, den Beginn der Warteschlange zu blockieren.

Dies ist in der Abbildung dargestellt: Wir empfangen Audio- und Videobilder, RTMP packt sie, vielleicht mischen sie sie irgendwie und sie fliegen zum Netzwerk.
Angenommen, wir verlieren ein Paket. Es ist möglich, dass dasselbe gelbe verlorene Paket - dies ist im Allgemeinen ein P-Frame von einem vorherigen - verworfen wurde. Vielleicht könnte man zumindest Audio abspielen. TCP gibt uns jedoch nicht den Rest der Pakete, da es
die Zustellung und die Reihenfolge der Pakete garantiert . Wir müssen irgendwie damit umgehen.

Es gibt ein weiteres Problem bei der Verwendung des TCP-Protokolls beim Streaming.
Nehmen wir an, wir haben einen Puffer und eine hohe Netzwerkbandbreite. Dort generieren wir aus unserem Codec hochauflösende Pakete. Dann - op! - Das Netzwerk begann schlechter zu funktionieren. Im Codec haben wir bereits angegeben, dass die Bitrate gesenkt werden muss, aber fertige Pakete befinden sich bereits in der Warteschlange und
Sie können sie in keiner Weise
von dort entfernen . TCP ist verzweifelt daran interessiert, HD-Pakete durch unser 3G zu übertragen.
Wir haben keine Pufferverwaltung, keine Priorisierung, daher ist
TCP für das Streaming äußerst ungeeignet .

Werfen wir jetzt einen Blick auf Mobilfunknetze. Für die Einwohner der Hauptstädte mag es überraschend sein, aber unser durchschnittliches Mobilfunknetz sieht ungefähr so aus:
- 1,1 Mbit / s Verkehr;
- 0,1% Paketverlust;
- 300 ms durchschnittliche RTT.
Wenn Sie sich einige Regionen und bestimmte Betreiber ansehen, haben sie einen
durchschnittlichen täglichen Paketverlust von mehr als 3% , und eine RTT von 600 ms ist normal.
TCP ist einerseits ein cooles Protokoll - es ist sehr schwierig, einem Auto das Fahren auf Autobahnen und im Gelände beizubringen. Aber es war sehr schwierig, ihr dann auch das Fliegen über drahtlose Netzwerke beizubringen.

Der Verlust von sogar 0,001% der Pakete führt zu einer Reduzierung des Durchsatzes um 30%. Das heißt, unser Benutzer nutzt den Kanal aufgrund der Ineffizienz des TCP-Protokolls in Netzwerken mit zufälligem Paketverlust nicht zu 30%.
In bestimmten Regionen erreicht der Paketverlust 1%, dann hat der Benutzer ungefähr 10% Prozent der Bandbreite.
Daher werden
wir kein TCP durchführen .
Mal sehen, was es sonst noch in der Welt des Streaming von UDP gibt.
Das WebRTC-Protokoll hat bei P2P-Aufrufen sehr gut funktioniert. Auf sehr beliebten Websites schreiben sie, dass es sehr cool ist, es für Anrufe zu verwenden, aber für die Bereitstellung von Video und Musik ist es nicht gut.
Sein Hauptproblem ist, dass er
Verluste vernachlässigt . Bei all den seltsamen Situationen lässt er sich einfach fallen.
Es gibt immer noch ein Problem in seiner Bindung an Anrufe, Tatsache ist, dass er alles verschlüsselt. Wenn Sie also Broadcasts senden und nicht den gesamten Audio- / Videostream durch Starten von WebRTC verschlüsseln müssen, wird Ihr Prozessor trotzdem belastet. Möglicherweise benötigen Sie dies nicht.
RTP-Streaming ist das Basisprotokoll für die Datenübertragung über UDP. Unten auf der Folie rechts finden Sie eine Reihe von Erweiterungen und RFCs, die in WebRTC implementiert werden mussten, um dieses Protokoll für Anrufe anzupassen. Im Prinzip können Sie versuchen, so etwas zu tun: Wählen Sie eine Reihe von Nebenstellen für RTP und erhalten Sie UDP-Streaming.
Aber es ist sehr schwierig .
Das zweite Problem ist, dass das Protokoll nicht funktioniert, wenn einer Ihrer Clients keine Erweiterung unterstützt.

Segmentprotokolle
Ein gutes Beispiel für ein segmentiertes Videoprotokoll ist
MPEG-Dash . Es besteht aus einer Manifest-Datei, die Sie auf Ihrem Portal veröffentlichen. Es enthält Links zu Dateien in verschiedenen Qualitäten. Am Anfang der Datei befindet sich ein Index, der angibt, an welcher Stelle der Datei welches Segment beginnt.

Das gesamte Video ist in Segmente unterteilt, z. B. 3 Sekunden lang, wobei jedes Segment mit einem Referenzrahmen beginnt. Wenn Sie sich ein solches Video ansehen und sich Ihre Bitrate ändert, beginnen Sie nur auf der Clientseite, das Segment der Qualität zu übernehmen, das Sie benötigen.
Ein weiteres Beispiel für segmentiertes Streaming ist
HLS .
MPEG-Dash ist eine Lösung von Google, funktioniert gut in Android und die Apple-Lösung ist älter und weist eine Reihe bestimmter Nachteile auf.

Das erste ist, dass das Hauptmanifest Links zu sekundären Manifesten enthält, die sekundären Manifeste für jede bestimmte Qualität Links zu jedem einzelnen Segment enthalten und jedes einzelne Segment durch eine separate Datei dargestellt wird.
Wenn Sie noch genauer hinschauen, befindet sich in jedem Segment MPEG2-TS. Dieses Protokoll wurde auch für den Satelliten erstellt, seine Paketgröße beträgt
188 Bytes . Es ist sehr unpraktisch, Videos in dieser Größe zu packen, insbesondere weil Sie sie ständig mit einem kleinen Header versehen.
Tatsächlich ist dies nicht nur für Server schwierig, die zur Verarbeitung von 40 GB Datenverkehr
26 Millionen Pakete sammeln müssen, sondern auch für den Client. Daher haben wir beim Umschreiben des iOS-Players auf MPEG-Dash sogar einige Leistungssteigerungen festgestellt.

Aber Apple steht nicht still. 2016 gaben sie schließlich bekannt, dass sie die Möglichkeit haben, ein Fragment von MPEG4 in HLS zu verschieben. Dann versprachen sie, dies nur für Entwickler hinzuzufügen, aber es scheint, dass jetzt Unterstützung für MacOS und iOS erscheinen sollte.
Das heißt, es scheint, dass Fragment-Streaming praktisch ist - kommen Sie, nehmen Sie das gewünschte Fragment, beginnen Sie mit dem Referenzrahmen - es funktioniert.
Minus: Es ist klar, dass der Referenzrahmen, von dem aus Sie gestartet haben, nicht der Rahmen ist, den derjenige, der ihn jetzt streamt, hat. Daher
gibt es immer eine Verzögerung .
Im Allgemeinen ist es möglich, HLS mit Verzögerungen in der Größenordnung von 5 Sekunden zu beenden. Jemand sagt, er habe es geschafft, 4 zu erhalten, aber im Prinzip ist die
Entscheidung, Fragment-Streaming für die Übersetzung zu verwenden, nicht sehr gut .

Schwierigkeit gegen Verzögerung
Schauen wir uns alle verfügbaren Protokolle an und sortieren sie nach zwei Parametern:
- die Latenz, die sie zwischen der Sendung und dem Zuschauer geben;
- Komplexität
Je kürzer die vom Protokoll garantierte Verzögerung ist, desto komplexer ist es.

Was wollen wir
Wir möchten ein UDP-Protokoll für das Streaming von 1 nach N mit einer Verzögerung erstellen, die mit der P2P-Kommunikation vergleichbar ist, mit der Option der optionalen Verschlüsselung von Paketen, je nachdem, ob es sich um eine private oder eine öffentliche Sendung handelt.
Welche anderen Möglichkeiten gibt es? Sie können beispielsweise warten, bis Google sein QUIC veröffentlicht.
Ich werde Ihnen ein wenig sagen, was es ist. Google positioniert Google QUIC als Ersatz für TCP - eine Art TCP 2.0. Es wurde seit 2013 entwickelt, hat jetzt keine Spezifikation, ist aber in Google Chrome vollständig verfügbar, und es scheint mir, dass sie es manchmal für einige Benutzer aktivieren, um zu sehen, wie es funktioniert. Im Prinzip können Sie in die Einstellungen gehen, QUIC aktivieren, zu einer beliebigen Google-Site gehen und diese Ressource über UDP abrufen.
Wir haben uns entschlossen, nicht zu warten, bis alle angegeben sind, und unsere Entscheidung einzureichen.
Protokollanforderungen:
- Multithreading , das heißt, wir haben mehrere Streams - Steuerung, Video, Audio.
- Eine optionale Liefergarantie - der Kontrollstrom hat eine 100% ige Garantie, das Video, das wir am wenigsten benötigen - wir können den Frame dort ablegen, wir möchten immer noch Audio.
- Priorisierung von Streams - damit das Audio vorwärts geht und der Manager im Allgemeinen fliegt.
- Optionale Verschlüsselung : entweder alle Daten oder nur Header und kritische Daten.

Dies ist ein Standarddreieck: Wenn ein gutes Netzwerk, dann hohe Qualität und geringe Latenz. Sobald ein instabiles Netzwerk auftritt und Pakete verschwinden, gleichen wir Qualität und Verzögerung aus. Wir haben die Wahl: entweder warten, bis das Netzwerk besser wird, und alles senden, was sich angesammelt hat, oder absteigen und irgendwie damit leben.
Wenn Sie die Protokolle nach diesem Prinzip sortieren, ist klar, dass
die Qualität umso
schlechter ist, je
kürzer die Wartezeit ist - eine ziemlich einfache Schlussfolgerung.
Wir wollen unser Protokoll in die Zone keilen, in der die Verzögerungen in der Nähe von WebRTC liegen, aber gleichzeitig in der Lage sein, es ein wenig zu pushen, weil wir schließlich keine Anrufe haben, sondern Sendungen. Der Benutzer möchte letztendlich einen Qualitätsstrom erhalten.
Entwicklung
Beginnen wir mit dem Schreiben des UDP-Protokolls, aber schauen wir uns zuerst die Statistiken an.

Dies sind unsere Statistiken zu Mobilfunknetzen. Es ist ersichtlich, dass das durchschnittliche Internet etwas mehr als Megabit beträgt, ein Paketverlust von etwa 1% normal ist und RTT im Bereich von 600 ms - bei 3G sind dies nur Durchschnittswerte.
Wir werden uns beim Schreiben des Protokolls darauf konzentrieren - lass uns gehen!
UDP-Protokoll
Wir öffnen Socket UDP, wir nehmen die Daten weg, wir packen, wir senden. Wir nehmen das zweite Paket aus dem Codec, den wir noch senden. Alles scheint großartig zu sein!

Wir erhalten jedoch das folgende Bild: Wenn wir anfangen, UDP-Pakete zufällig an den Socket zu senden, beträgt die Wahrscheinlichkeit, dass es bis zum 21. Paket erreicht wird, laut Statistik nur 85%. Das heißt, der Paketverlust beträgt bereits 15%, was nicht gut ist. Dies muss behoben werden.

Dies ist standardmäßig festgelegt. Die Abbildung zeigt das Leben ohne Pacer und das Leben mit
Pacer .
Pacer ist so etwas, das Pakete rechtzeitig verbreitet und ihren Verlust kontrolliert. Es wird untersucht, was der Paketverlust jetzt ist, abhängig davon passt es sich an die Kanalgeschwindigkeit an.
Wie wir uns erinnern, ist bei Mobilfunknetzen ein Paketverlust von 1 bis 3% die Norm. Dementsprechend müssen wir irgendwie damit arbeiten. Was ist, wenn wir Pakete verlieren?
Erneut übertragen

Wie Sie wissen, gibt es in TCP einen schnellen Neuübertragungsalgorithmus: Wir senden ein Paket, das zweite, wenn das Paket verloren geht, und nach einer Weile (Neuübertragungsperiode) senden wir dasselbe Paket.
Was sind die Vorteile? Keine Probleme, keine Redundanz, aber es gibt ein Minus - eine gewisse
Zeit für die erneute Übertragung .

Es scheint sehr einfach zu sein: Nach einiger Zeit müssen Sie das Paket wiederholen, wenn Sie keine Bestätigung erhalten haben. Logischerweise kann dies eine Zeit sein, die der Ping-Zeit entspricht. ping — , RTT time , , .
, , , , jitter: ping-. , , 46 . jitter — 50.

. RTT , , acknowledge . , RFC6298, TCP , .
jitter. jitter ping 15%. , retransmit period , , 20% , RTT.

retransmit. acknowledge . , , . retransmit period, . , .
, retransmit . , , packet loss 5%, 400 , 400 1 packet-drop, , retransmit period , .
, . , , acknowledge . , — , , speculative retransmit .
retransmit, .
. ,
Forward Error Correction ? , , XOR. , , .

Wow! round trip, .
, , ? XOR — , Reed-Solomon, Fountain codes .. : K , N , N .
!
, , , Forward Error Correction negative acknowledgement.
NACK

, parity protection ( ) , .
NACK:
- , negative acknowledgement, .
- FEC.
, :
- , FEC + NACK;
- , Fast retransmit.
, .

, , ( ). , , 11 , 60-80 . , , .
6 .

, , . , . , Wi-Fi 22 5 , 3G 34 8 .

: , 90% packet loss 10 , gap 25 , — FEC + NACK Fast retransmit?
, , , Google, QUIC 2013 , Forward Error Correction , , . 2015 .
FEC + NACK, .
, .

, , c :
- 1 / ;
- 1% packet loss;
- 300 RTT;
- 1 000 — ;
- 1 000 .
10 . packet loss 1% 1 000 10. — 100 1 — , 2 , .
, . 500- , 10 .
:
- 500 Forward Error Correction. , .
- NACK, , .
- Fast Retransmit, .
Forward Error Correction , — gap 200-300 .
Fast Retransmit
: , 10 , , , retransmit period , .

, retransmit period 350 , packet gap — 25-30 , 100. , , retransmit , .
, .
Zusätzliche Optionen
UDP , .

, , p/b-. . , .
, , , , , , 0,5 .
, , , , p/b, , , .
MTU
Da wir das Protokoll selbst schreiben, müssen wir uns mit der IP-Fragmentierung befassen. Ich denke, viele Leute wissen davon, aber nur für den Fall, ich werde es Ihnen kurz sagen.

Wir haben einen Server, der einige Pakete an das Netzwerk sendet, sie kommen zum Router und auf seiner Ebene wird die MTU (maximale Übertragungseinheit) niedriger als die Größe des angekommenen Pakets. Es teilt das Paket in große und kleine (hier 1100 und 400 Bytes) und sendet.
Im Prinzip gibt es kein Problem, alles sammelt sich auf dem Client und funktioniert. Wenn wir jedoch 1 Paket verlieren, verwerfen wir alle Pakete und erhalten zusätzliche Kosten für Paket-Header. Wenn Sie Ihr Protokoll schreiben, ist es daher ideal, in der Menge an MTU zu arbeiten.
Wie zählt man es?Tatsächlich kümmert sich Google nicht darum, fügt ungefähr 1200 Bytes in sein QUIC ein und wählt es nicht aus, da dann die IP-Fragmentierung alle Pakete sammelt.

Wir machen genau das Gleiche - zuerst legen wir eine Standardgröße fest und beginnen mit dem Senden von Paketen - lassen Sie sie fragmentieren.
Führen Sie parallel einen separaten Thread aus und erstellen Sie einen Socket mit dem Fragmentierungsverbotsflag für alle Pakete. Wenn der Router auf ein solches Paket stößt und diese Daten nicht fragmentieren kann, wird das Paket verworfen und Sie möglicherweise per ICMP darüber informiert, dass Probleme vorliegen. Höchstwahrscheinlich wird ICMP jedoch geschlossen, und dies geschieht nicht. Daher versuchen wir beispielsweise einfach dreimal, in einem bestimmten Intervall ein Paket einer bestimmten Größe zu senden. Wenn es nicht erreicht wird, glauben wir, dass die MTU überschritten wird und reduzieren sie weiter.
Mit der MTU der Internetschnittstelle auf dem Gerät und einer minimalen MTU wählen wir einfach die richtige MTU durch eindimensionale Suche aus. Danach passen wir die Paketgröße im Protokoll an.
Tatsächlich ändert es sich manchmal. Wir waren überrascht, aber beim Umschalten von Wi-Fi usw. ändert sich die MTU. Es ist besser, diesen parallelen Prozess nicht zu stoppen und die MTU von Zeit zu Zeit zu korrigieren.

Höhere MTU-Verteilung in der Welt. Wir haben ungefähr 1100 Bytes auf dem Portal.
Verschlüsselung
Wir haben gesagt, dass wir optional die Verschlüsselung verwalten möchten. Wir machen die einfachste Option - Diffie-Hellman auf elliptischen Kurven. Wir tun dies optional - wir verschlüsseln nur die Steuerpakete und Header, damit Man-in-the-Middle den Broadcast-Schlüssel nicht empfangen, abfangen und so weiter kann.

Wenn die Sendung privat ist, können wir auch die Verschlüsselung aller Daten hinzufügen.
Pakete werden unabhängig mit AES-256 verschlüsselt, sodass der Paketverlust die weitere Paketverschlüsselung nicht beeinträchtigt.
Priorisierung
Denken Sie daran, wir wollten mehr Priorisierung aus dem Protokoll.

Wir haben Metadaten, Audio- und Videobilder, die wir erfolgreich an das Netzwerk senden. Dann brennt unser Netzwerk in der Hölle nieder und funktioniert lange Zeit nicht - wir verstehen, dass wir Pakete verwerfen müssen.
Wir verwerfen hauptsächlich Videopakete, versuchen dann, Audio zu verwerfen und berühren niemals Steuerpakete, da Daten wie Auflösungsänderungen und andere wichtige Probleme diese durchlaufen können.
Zusätzliches Brötchen über UDP
Wenn Sie Ihr UDP-Protokoll beispielsweise mit bidirektionaler Kommunikation schreiben, müssen Sie verstehen, dass NAT Unbinding besteht und dass Sie den Client möglicherweise nicht vom Server zurückfinden.

Auf der Folie gab es Zeiten, in denen es nicht möglich war, den Client vom Server über UDP zu erreichen.
Viele Skeptiker sagen, dass Router so konzipiert sind, dass NAT Unbinding in erster Linie UDP-Routen verdrängt. Das Obige zeigt jedoch, dass es mit einer Wahrscheinlichkeit von 99% möglich ist, den Client zu erreichen, wenn Keep-Alive oder Ping weniger als 30 Sekunden beträgt.
UDP-Verfügbarkeit auf Mobilgeräten weltweit

Google sagt 6%, aber es stellte sich heraus, dass
7% der mobilen Benutzer UDP nicht verwenden können . In diesem Fall verlassen wir unser schönes Protokoll mit Priorisierung, Verschlüsselung und allem, nur auf TCP.
Unter UDP funktioniert VOIP jetzt unter WebRTC, Google QUIC und viele Spiele unter UDP. Daher würde ich nicht glauben, dass UDP auf mobilen Geräten geschlossen wird.
Als Ergebnis:
- Die Verzögerung zwischen dem Streamer und dem Watcher wurde auf 1 s reduziert.
- Wir haben den kumulativen Effekt in den Puffern beseitigt, dh die Sendung bleibt nicht zurück.
- Die Anzahl der Stände im Publikum hat abgenommen .
- Sie konnten Streaming auf Mobilgeräten FullHD unterstützen.

- Die Verzögerung in unserer mobilen OK Live-Anwendung ist 25 ms - 10 ms länger als der Kamerascanner, aber nicht so beängstigend.
- Webcasting zeigt eine Verzögerung von nur 690 ms - Speicherplatz!
Was kann man sonst noch auf Odnoklassniki streamen

- Akzeptiert unser OKMP-Protokoll von Mobilgeräten.
- kann RTMP und WebRTC akzeptieren;
- gibt HLS, MPEG-Dash usw. aus.
Wenn Sie vorsichtig waren, haben Sie bemerkt, dass ich gesagt habe, wir können beispielsweise WebRTC vom Benutzer nehmen und in RTMP konvertieren.

Es gibt eine Nuance. Tatsächlich ist WebRTC ein paketorientiertes Protokoll und verwendet den OPUS-Audiocodec. Sie können OPUS nicht in RTMP verwenden.
Auf Backend-Servern verwenden wir RTMP überall. Daher mussten wir einige Korrekturen in FF MPEG vornehmen, die es uns ermöglichen, OPUS in RTMP zu verschieben, es in AAC zu konvertieren und es Benutzern zu geben, die bereits in HLS oder etwas anderem sind.
Wie sieht es in uns aus?

- Benutzer, die eines der Protokolle verwenden, laden das Originalvideo auf unseren Upload-Server hoch.
- Dort setzen wir das Protokoll ein.
- Wir senden RTMP an einen der Videotransformationsserver.
- Das Original wird immer in einem verteilten Speicher gespeichert, damit nichts verloren geht.
- Danach gehen alle Videos zum Verteilungsserver.
Für Eisen haben wir Folgendes:

Ich erzähle Ihnen etwas mehr über Fehlertoleranz:
- Upload-Server sind in verschiedenen Rechenzentren verteilt und stehen hinter verschiedenen IPs.
- Benutzer kommen, erhalten IP auf DNS.
- Der Upload-Server sendet das Video an die Slicing-Server, die sie schneiden und an die Verteilungsserver weitergeben.
- Für populärere Sendungen fügen wir eine größere Anzahl von Verteilungsservern hinzu.
- Wir speichern alles, was vom Benutzer kam, im Repository, damit wir später ein Broadcast-Archiv erstellen und nichts verlieren können.
- Fehlertoleranter Speicher, verteilt auf drei Rechenzentren.
Um festzustellen, welcher Server derzeit für die Übersetzung verantwortlich ist, verwenden wir
ZooKeeper . Für jede Übersetzung speichern wir einen Knoten und erstellen kurzlebige Knoten für jeden Server. Tatsächlich ermöglicht dies einem Stream, eine Warteschlange von Servern zu erstellen, die verarbeitet werden. Immer ist der aktuelle Marktführer in dieser Zeile mit der Stream-Verarbeitung beschäftigt.
Wir werden die Fehlertoleranz schnell testen. Wir beginnen sofort mit dem Verschwinden des gesamten Rechenzentrums.
Was wird passieren?- Der DNS-Benutzer übernimmt die nächste IP eines anderen Upload-Servers.
- Zu diesem Zeitpunkt wird ZooKeeper verstehen, dass der Server in diesem Rechenzentrum gestorben ist, und den Slicing-Server für einen anderen auswählen.
- Download-Server werden herausfinden, wer jetzt für die Transformation dieses Streams verantwortlich ist, und ihn verteilen.
Im Prinzip geschieht dies alles mit minimalen Verzögerungen.
Verwendung des Protokolls im Produkt
Wir haben die OK Live Streaming Mobile App erstellt. Es ist vollständig in das Portal integriert. Dort können Benutzer kommunizieren, Live-Sendungen durchführen, es gibt eine Karte mit Sendungen, eine Liste mit beliebten Sendungen - im Allgemeinen alles, was Sie wollen.

Wir haben auch die Möglichkeit hinzugefügt, in FullHD zu senden. Sie können eine Action-Kamera unter Android mit einem Android-Gerät verbinden.

Jetzt haben wir einen Mechanismus, der Live-Übertragungen ermöglicht. Zum Beispiel haben wir über OK Live eine direkte Verbindung zum Präsidenten hergestellt und diese im
ganzen Land ausgestrahlt . Benutzer sahen zu und konnten über den entgegenkommenden Stream auf Sendung gehen und ihre Fragen stellen.
Das heißt, zwei entgegenkommende Streams mit einer minimalen Verzögerung bieten ein bestimmtes Format für öffentliche Konferenzen.
Tatsächlich haben wir uns in 2 Sekunden irgendwo getroffen - eine Sekunde dort und eine Sekunde zurück. Denken Sie an den „Wagen“, über den ich am Anfang des Artikels gesprochen habe - jetzt sieht es aus wie zwei riesige Lastwagen. Bei Fernsehsendungen ist es völlig normal, von der Kamera zu entfernen und alles mit einer Verzögerung von ca. 1-2 s zu mischen.
Tatsächlich ist es uns gelungen, etwas zu reproduzieren, das mit dem aktuellen modernen TCP vergleichbar ist.

Live-Übertragungen sind der aktuelle Trend. In den letzten anderthalb Jahren haben sie sich auf dem OK-Portal verdreifacht (nicht ohne die Hilfe der OK Live-Anwendung).

Alle Sendungen werden standardmäßig aufgezeichnet. Wir haben ungefähr 50.000 Streams pro Tag, dies generiert ungefähr 17 Terabyte Verkehr pro Tag, aber im Allgemeinen generiert das gesamte Video auf dem Portal ungefähr ein Petabyte Daten pro Monat.

Was haben wir bekommen:
- Könnte die Dauer der Verzögerung zwischen dem Streamer und dem Publikum garantieren.
- Wir haben die erste mobile FullHD-Anwendung für das Streaming auf einem sich dynamisch ändernden mobilen Internetkanal entwickelt.
- Wir haben die Möglichkeit, Rechenzentren zu verlieren und gleichzeitig die Übertragung nicht zu unterbrechen
Was hast du gelernt:
- Was ist Video und wie kann man es streamen?
- Dass Sie Ihr UDP-Protokoll schreiben können, wenn Sie sicher sind, dass Sie eine ganz bestimmte Aufgabe und bestimmte Benutzer haben.
- Informationen zur Architektur eines Streaming-Dienstes - Video wird eingegeben, konvertiert und beendet.
Bei Highload ++ Siberia verspricht Alexander Tobol, über den OK- Anrufdienst zu sprechen. Es wird interessant sein zu wissen, was aus dem, was in diesem Artikel besprochen wurde, angewendet werden konnte und was vollständig neu implementiert werden musste.
Im selben Abschnitt sind Berichte zu hochspezialisierten Themen geplant:
- Eugene Rossinsky (ivi) über das System zur Erfassung detaillierter Statistiken über den Betrieb von CDN-Knoten.
- Anton Rusakova (Badoo) über die Integration von Zahlungssystemen ohne eigene Abrechnung.