Video Streaming & DirectShow



  • Ich hätte ein paar Fragen zu Video Streaming & DirectShow. Ich soll in nächster Zeit ein Projekt mit Live Video Streaming realisieren, und da das für mich auch z.T. Neuland ist, hätte ich da einige Fragen. Wenn ihr mir einige davon beantworten könnt, bzw. mir nen Tipp geben wo man da nachlesen könnte, wäre das toll 🙂

    1. Welche Container-Formate könnte man für Live Streams empfehlen? Codec sollte erstmal H.264 sein, evtl. aber auch MJPEG oder einfach MPEG 4 ASP. MPEG 2 TRANSPORT sollte für H.264 gehen - gibt's da irgendwelche Probleme/Schwächen über die man sich im klaren sein sollte? Achja: toll wäre es wenn keine fixe Framerate eingehalten werden müsste, also wenn der Container einfach für jedes Frame einen Timestamp mitschickt und fertig. Dann müsste ich mich nicht besonders um dropped Frames oder das "Driften" zwischen verschiedenen Clocks kümmern.

    2. Wie funktioniert das bei Streaming überhaupt? Gibt es Container Formate wo man einfach bei einem x-beliebigen Byte anfangen kann zu übertragen, und der Client sucht dann einen passenden Startpunkt (Anfang eines "Samples"/Paketes/...), und fängt an zu dekodieren sobald er das erste I-Frame gefunden hat? Oder muss man da den Muxer des entsprechenden Container-Formates nach einem möglichen Startpunkt fragen?

    3. Kennt ihr Seiten wo Streaming mit DirectShow erklärt wird? Oder Sourcen wo man mal reingucken könnte? Ich müsste beide Seiten implementieren, also Server und Client. Ich möchte das mit dem geringst möglichen Aufwand machen, und so flexibel wie möglich halten (Priorität erstmal: wenig Aufwand wichtiger als flexibel), also wäre toll wenn das mit DirectShow gehen würde.

    4. Angenommen es wäre halbwegs einfach möglich mit DirectShow einen Streaming Server hinzubekommen ... habt ihr eine Ahnung wie das funktioniert wenn die Netzwerkbandbreite zu gering wird (z.B. Übertragungsrate bricht plötzlich ein, Videostream würde mehr KB/s benötigen als zur Verfügung stehen)? Kann man davon ausgehen dass das der DirectShow Filter Graph bzw. die darin enthaltenen Filter irgendwie mitbekommen, und selbständig anfangen Frames zu droppen oder etwas in der Art? Oder müsste man das von aussen irgendwie erkennen und steuern?

    4.1) Was wenn ich einen Graphen bastele mit einem T-Filter drinnen, und das Video an mehrere Clients gleichzeitig übertrage? Wo sollte der T-Filter dann sitzen? Und muss ich dann davon ausgehen dass alle Clients die angehängt sind Probleme bekommen bloss weil z.B. ein Client seine Leitung mit was anderem so zumacht dass fast nixmehr drüber geht?

    p.S.: erstmal wird die Source ein YUYV Video-Signal sein, also unkomprimiert, d.h. es hängt ein Encoder im Graph der das zu H.264 oder MPEG 4 komprimiert.

    p.p.S.: geringe Latenzzeit ist erstmal nicht wirklich wichtig.

    Danke für eure Zeit



  • Also ich hab ein halbes Jahr mal mit DirectShow in einem Praxissemester zu tun gehabt. Ist aber nun auch wieder etwas länger her und ich weiß da leider vieles nicht mehr 😞 Zudem hatte ich nie was mit Streaming (und Netzwerk) zu tun, sondern hab "normale" DirectShow-Filter (Transoform- aber auch Renderer-Filter) geschrieben, welche im Bildverarbeitungsbereich eingesetzt wurden.

    Zu Punkt 4): Da fängts schon an, ich verstehe z.B. nicht wie du MIT DirectShow einen StreamingSERVER hinbekommen willst? Wäre es nicht so, dass vom Server einfach ein Multimedia-Stream an den Client geschickt wird, und dann der Client eben DirectShow benutzen muss, um diesen zu decodieren? D.h. du müsstest hier halt zuerst einen Source-Filter schreiben. Und Source-Filter sind ja so designt, dass sie unabhängig von der Lokation der Quelle sind (d.h. z.B. Festplatte, Internet, Videokamera, etc.).
    Oder willst du das Video im Server bereits durch einen DirectShow-Graphen jagen, und dann den ausgehenden Stream an Clients übertragen? (So verstehe ich das wie du es unter Punkt 4.1 nennst).
    Und wegen Performanz-Blockierungen (falls ein Client sehr lahm sein sollte): Ich denke mal, dass es davon abhängt wie du das implementierst. Ohne groß nachzudenken (und ganz pragmatisch) könnte ich mir z.b. vorstellen, dass du im Server, deinen Graph dynamisch hast, d.h. dass du ne Art Muxer hast, an den du bei jedem neuen Client immer wieder eine neue T-Filter-Instanz dranhängst die dann dem neuen Client zugewiesen wird. Ich meine mich zu erinnern, dass man in der Hinsicht den Filtergraph dynamisch erweitern kann. Aber vielleicht verstehe ich das ganze grade auch total falsch.
    Falls du einfach nur nen Stream vom Server lieferst (d.h. ohne DShow-Filter aufm Server), dann ist das ja eh kein Problem.

    Und nochmal Zu 4. wegen Frame-Droppen: Es wird nichts automatisch gedroppt (da bin ich mir wieder relativ sicher, da ich so ein ähnliches Problem auch mal hatte). Es wird alles nur dementsprechend langsam. Du kannst aber von "außen" (also im Code deines Filters) selbst eingreifen, und einfach Frames ignorieren.

    Zu 2.): Verstehe die Frage jetzt nicht so ganz, aber prinzipiell funktioniert Streaming allgemein so:
    Ein Sourcefilter liest irgendeine Multimedia-Quelle ein (in einem propretären Format). Der SourceFilter kennt das Format ja, und weiß wie er es zu lesen hat. Er wandelt dieses Format dann um, so dass man am Ende dafür einfach nur noch die Farbwerte in einem Byte-Array hat (also z.B. RGB oder YUV). Ein Source-Filter überträgt dann immer ein Frame, d.h. die nachfolgende Verarbeitung (Transformfilter) findet immer frameweise statt. Ein Transform-Filter kriegt ein Frame, stellt damit irgendwas an, und reicht es dann an den nächsten Filter weiter. Da das ganze (intern) immer als Byte-Array übertragen wird, hast du selbst die Wahl, was du von so nem Frame übertragen willst, d.h. du könntest einfach auch immer nur die ersten 10 Pixel übertragen wenn du lustig bist. Der nachfolgende Filter würde dann nur diese 10 Pixel bekommen und weiterverarbeiten. Das wäre dann für Ihn eben das Frame das er bekommt. Wichtig ist aber, dass du in Transformfiltern, immer ein Frame auf einmal kriegst, und auch immer nur ein Frame auf einmal wieder weiterschicken kannst. (Obwohl man da meines Wissens auch tricksen kann).

    Zu 3.): Also an Literatur/Tutorials gibts nichts groß. Ich hab damals auch danach gesucht, und bin nicht wirklich fündig geworden. Es gibt halt die SDK Dokumentation (MSDN) und die ist eigentlich schon ganz brauchbar. Insbesondere die BaseClasses solltest du dir da anschauen, da du viel mit denen arbeiten wirst. Gibt auch paar Sample-Filter die mitgeliefert werden, aber das wars. Ansonsten gibts noch ein Buch von so nem Microsoft-Typie, aber davon würd ich die Finger lassen. Da steht auch nicht mehr wie in der Doku drinnen, nur dass noch zusätzlich paar Fehler drinnen sind 😉
    Wo du noch schauen könntest ist Soruceforge. Vielleicht gibts da was, was deinem Vorhaben ähnelt. Ich habe damals auch auf Sourceforge gesucht, und es gibt da schon ein paar DShow-Projekte (bin aber bei meiner speziellen Suche nicht fündig geworden 😉 )
    DShow musst du eher selbst rumprobieren 😃 Und da wünsche ich dir schon mal viel Spaß dabei, vor allem beim Compilieren und Linken 😃 Als Tipp würde ich dir da raten: Immer schrittweise vorgehen und erst mal einen Minimalst DShow-Filter ohne Funktionalität zu kompilieren (der aber schon alles richtige an Einstellungen hat).
    Achja wegen Client: Wenn ich es richtig verstehe, musst du clientseitig eigentlich nur die entsprechenden Filter programmieren (dürften dann wohl hauptsächlich der Sourcefilter und evtl. noch ein Transform-Filter sein). Um den Graphen zusammenzubauen kannst du GraphEdit (Tool von Microsoft) oder noch besser Media Player Classic benutzen (damit kannst du dir auch selbst deine DShow-Filter zu nem Graphen verknüpfen).



  • Verklickt



  • Ich habe mal einen Audio Streaming Sourcefilter samt Splitter (push-Betrieb) implementiert.

    Um Frames zu Droppen musst du entweder den Splitterfilter selber schreiben oder einen Filter kennen der es kann (ich hab schon für Audio nix gefunden also kannst du das vergessen). Wenn du den Splitter selber schreibst dann wirst du die Spezifikation vom Container benötigen, für nen Elementary MPEG Audiostream war das schon komplex genug, MPEG4 mit Video mag ich mir garnet ausmahlen ;(. Dazu kommt noch das es nur ein Buch dazu von Microsoft gibt was Source und Splitterfilter kein bisschen beschreibt. Es wird viel COM eingesetzt. Seit neuestem ist DirectShow im PlatformSDK und nichtmehr im DirectX SDK.

    Einen Sourcefilter der Streams (URLs) lesen kann gibt es auch nicht in Windows zumindestens arbeitet der nicht mit den meisten Splittern und Decodern. Windows Mediaplayer hat zB einen fest integriert anstatt den Standardfilter zu verwenden.

    Bei h264 wirst du einen performanten Server brauchen um das in Live zu Streamen. Bin mir aber nicht sicher ob du wirklich Live willst, denke eher du hast eine Datei und überträgst sie über HTTP 1.1 da gibt es es Sprungmöglichkeiten über Byte-Range (was du dann wiederum im Source/Splitterfilter implementieren musst) etc...



  • Hallo!

    Ich implementiere auch gerade einen Push-Filter. (HTTP, RTSP/RTP Source&Renderer)

    ad 1) Prinzipiell gibt es hier derzeit 2 interessante Verfahren: HTTP progressive streaming und RTSP/RTP streaming. (Im Falle vom RTP/H.264 wäre das RFC 3984). Ich persönlich favoriere RTSP/RTP, weil standardisiert.

    ad 2) Ja das geht. Sowohl HTTP als auch RTSP

    ad 3) Einige Infos findest du im MSDN Directshow forum. Es gibt auch noch ein Buch namens: Programming Directshow for Digital Video and Television.

    ad 4) nein. Als Push Source müsstest du das selbst hinkriegen.

    ad 5) das denk ich nicht. Hängt natürlich sehr vom verwendeten Streaming Protokoll ab und der Signalisierung dahinter.

    ad PS) Wenn du erstmal YUV komprimieren willst und an deine Partizipanten schicken willst, dann brauchst du einen Netzwerk Renderer. Der Graph hängt von den in 1) genannten Richtung ab. Aber prinzipiell mal Source->Compress->(Mux für Http)->NetRender(mit participant add/remove)



  • Ok, danke für eure Antworten!

    @WeaponX2007: Nur weil du schreibst du implementierst auch gerade einen Push-Filter - ich möchte so wenig wie möglich Filter selbst implementieren 🙂 Wir haben z.B. das SDK von Mainconcept welches wir einsetzen können - evtl. könnten wir auch andere Filter zukaufen bzw. lizensieren wenn es Sinn macht und der Preis halbwegs stimmt.

    Wenn ich HTTP Streaming richtig verstehe ist das ein normaler HTTP Download. Wenn das Video "live" ist, d.h. auch die Länge nicht vorab feststeht, müsste man hier wohl das HTTP "Feature" verwenden wo die Länge implizit durch das "graceful shutdown" des Sockets signalisiert wird, und das einfach nicht machen (d.h. dem Client überlassen einfach "aufzulegen" wenn er nichtmehr zugucken will).

    Ich habe mal mit den Mainconcept Filtern rumexperimentiert und es zumindest zusammengebracht einen Stream mit H.264 in einem MPEG 2 TS Container zu streamen, allerdings hat das mit den Clocks noch nicht so hingehaut. Der Server hat mit ~250fps gesendet weil ich einfach ein .avi als Source verwendet habe (live re-encoded als H.264), und keine Clock im Graph war die sich zuständig gefühlt hätte da die Geschwindigkeit zu regeln. Der Client hat aber anstatt öfter mal nach vorne zu springen (oder auch mit 250fps zu spielen) alles gepuffert und mit der original Framerate abgespielt.

    Auf jeden Fall noch eine Frage: kannst du mir einem Tip geben wer gute DirectShow Filter anbietet die sich für sowas einsetzen liessen?

    @DaRpH:

    Bei h264 wirst du einen performanten Server brauchen um das in Live zu Streamen. Bin mir aber nicht sicher ob du wirklich Live willst, denke eher du hast eine Datei und überträgst sie über HTTP 1.1

    Jo, H.264, und ich weiss dass das (leider) aufwändig zu codieren ist. Allerdings hoffe ich darauf dass man die Encoder Filter soweit runterschrauben kann dass sie nicht allzuviel Zeit mit "Suchen, Raten und Ausprobieren" verbraten, sondern ggf. einfach ne etwas höhere Bitrate verwenden.
    Und ja, live, so wie in "Bild von einer Camera" 😉 Bzw. mehreren Cameras.



  • Hallo,

    Du kannst Dir auch

    http://www.cs.wustl.edu/~schmidt/av.html

    mal anschauen. Ich selbst habe den audio/ video streaming service noch nicht benutzt, habe aber nur gutes darüber gelesen.
    Und so wie ich die TAO Implementierung kennengelernt habe wird er auch ziemlich performant sein.

    Gruß
    Paddy



  • Neben MainConcept fällt mir noch Mpegable (teuer) (www.mpegable.com), Elecard (www.elecard.com), Streamcoders (www.streamcoders.com) und Hymeloff Labs ein.



  • Ich habe damals die Codecs von Ahead/Nero genutzt man kann sich diese Nero Digital Codecs auch lizensieren, die waren teilweise gut denkmal inzwischen sind sie besser.


Anmelden zum Antworten