VDR-Testreihe zum Frame-Detector - Bitte um Mithilfe!


  • Klingt vernünftig.


    Vom Standard her gibt es halt keine Verpflichtung, daß TS-Pakete einer bestimmten PID irgendwie gruppiert sein müßten...


    Interessanterweise handelt es sich hier um den alten Einsfestival-Transponder, der in DVB-S (nicht DVB-S2) sendet.


    Vielleicht geht es hier brandbreitenmäßig etwas knapp zu. Der Muxer im Sender muß schließlich eine ganze Menge Datenströme (Video + alle zugehörige Audiospuren, und das auch noch von mehreren Programmen) zusammenpacken, wobei bestimmte max. Pufferzeiten einzuhalten sind. Ich bezweifle, daß dabei nachgeschaut wird, was in einem TS-Paket drin steht. Da wird einfach zusammengerührt, und von Zeit zu Zeit werden dann eben die ersten beiden TS-Pakete eines I-Frame getrennt.


    CU
    Oliver

  • Ok, ich dachte das wäre quasi das schwarze Schaf, wenn andere den Standard auch verbiegen, muss natürlich eine Lösung auf Empfängerseite her.


    Der Standard wird da ja gar nicht "verbogen", das ist ja das Schlimme. Meiner (unmaßgeblichen ;) Meinung nach hätte es von Anfang an so spezifiziert werden sollen, daß man sowas Grundlegendes wie wann ein neuer Frame beginnt so einfach wie möglich erkennen kann. Da hätte ein einzelnes Bit im ersten TS-Paket gereicht.
    Aber warum einfach, wenn's auch kompliziert geht ;-).


    Klaus

  • Hallo!


    Ich glaube nicht, daß das was bringt, denn wir brauchen ja den Anfang des ersten PES-Pakets einer Payload, um den PTS zu ermitteln. Und dazu muß PUSI gesetzt sein.


    Ich werde mir das auch nochmal genauer anschauen, was da bei "WDR HD" anders ist als bei den anderen.

    Du hast recht, so geht es wohl nicht. Aber ich hab die Hoffnung noch nicht aufgegeben,
    dass man MIN_TS_PACKETS_FOR_FRAME_DETECTOR vielleicht sogar auf 1 runterschrauben kann.


    Also, ich versteh deinen Code so...
    Unter der Bedingung if (TsPayloadStart(Data) werden zwei verschiedene Dinge getan:


    Das eine ist das Einsammeln von PTS-Daten, um nachher die Framerate zu ermitteln.
    if (numPtsValues < 2 || numPtsValues < MaxPtsValues && numIFrames < 2) {
    Das sollte wohl tatsächlich nur unter der Bedingung TsPayloadStart(Data) passieren.


    Das andere ist der Sync-Vorgang, der angestoßen werden kann, wenn mindestens zwei
    I-Frames und mindestens zwei PTS-Werte gesichtet wurden.
    if (numPtsValues >= 2 && numIFrames >= 2) {
    Und bei dem frage ich mich: Kann man das nicht praktisch immer abfragen? Sinnvollerweise
    natürlich nur, wenn gerade ein neuer Frame gesichtet wurde (weil sich dann die I-Frames
    vermehrt haben könnten), aber von TsPayloadStart(Data) sollte das doch eigentlich unabhängig
    sein?


    Mit der entsprechenden Änderung kriege ich den Start des Recorders sogar bei einer Frame-
    Größe von 1 rechtzeitig. Ist da was dran falsch?


    Ciao,
    Eike


  • Der neue Frame muß aber genau dann erkannt werden, wenn ein TS-Paket mit PUSI=1 gefunden wird, weil in der Aufnahme vor diesem Paket eine PAT/PMT eingefügt werden muß, wenn es ein I-Frame ist.


    Ich werde in kürze einen Patch hier posten, der das besser macht.


    Klaus

  • Anbei nun der Patch, mit dem MIN_TS_PACKETS_FOR_FRAME_DETECTOR auf einen relativ hohen (und wohl ziemlich sicheren) Wert von 100 gesetzt wird, was keinen nennenswerten zusätzlichen Aufwand bedeuten sollte, da jetzt die Zahl der tatsächlich bearbeiteten Video-TS-Pakete über MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION limitiert wird.


    Die Macros WRN_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION und WRN_TS_PACKETS_FOR_FRAME_DETECTOR dienen dazu, bei überschreiten des jeweils halben Wertes der Grenzwerte eine Warnung ins Log zu schreiben. Damit sollte es möglich sein, rechtzeitig auf eventuelle künftige Änderungen zu reagieren. Mit den gegebenen Werten sollte es eigentich auf längere Sicht gut gehen.


    Bitte testet mal Aufnahmen hiermit, vor allem (aber nicht ausschließlich) auf den "Problemkanälen".
    Um die Warnungsmeldungen zu triggern könnt ihr auch die WRN_... Macros mal entsprechend runtersetzen.


    Klaus

  • Hallo!


    Ich hab mich da nochmal reingebohrt, und ich glaube, ich bin auf etwas gestoßen...


    Der RingBuffer wird mit einer Mindestframegröße MIN_TS_PACKETS_FOR_FRAME_DETECTOR erstellt.
    Wenn er jetzt tatsächlich immer nur diese Größe rausrückt, wird die an den FrameDetector weitergereicht
    und von dem an den MPEG-Parser. In dem ist aber die Abbruchbedingung:
    "tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE"
    Dadurch wird doch im Extremfall wieder nur jeweils ein einziges Paket berücksichtigt, richtig?
    Das geht bei meinem ARD-Programm regelmäßig schief, weil der I-Frame-Start erst im Frame nach dem
    PUSI kommt. Eigentlich müsste man nur zwei aufeinanderfolgende TS-Pakete analysieren, aber der Code
    schaut sich am Ende jedes Paket einzeln an...


    Ciao,
    Eike

  • Ich hatte mir das angeschaut, aber wenn ich es richtig verstehe, löst es das Problem nicht.


    Die Daten fließen doch so...


    Code
    void cRecorder::Action(void)
    
    
    	int Count = frameDetector->Analyze(b, r);


    Wir nehmen an, hier wird die Minmalzahl Pakete geliefert, nehmen wir 10, es können aber auch 100 oder auch 1000 sein.


    Code
    int cFrameDetector::Analyze(const uchar *Data, int Length)
    
    
    	int n = parser->Parse(Data, Length, pid);


    Hier werden alle weitergeschickt, sei es an den MPEG-2 oder -4-Parser.


    Code
    int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
    
    
    	if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary
    		|| (tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE // stop if the available data is below the limit...
    		&& (tsPayload.Available() <= 0 || tsPayload.AtTsStart()))) // ...but only if there is no more data at all, or if we are at a TS boundary
    			break;


    ... und hier wird dann nach dem ersten Frame wieder abgebrochen, weil sofort die Grenze unterschritten wird.
    (...und der Framedetector bricht dann auch ab, aus demselben Grund.)
    Wofür ist das gut, dass der Parser frühzeitig aufhört? Kann der nicht alle Frames anschauen, die er bekommt?
    Und wenn nicht, sollte zwischen dem, was der Parser liest, und dem, was der Buffer rausrückt, nicht ein paar Frames Abstand sein?
    Auch beim Framedetector verstehe ich die Einschränkung nicht: Klar soll er genug Frames bekommen - aber warum soll er sie
    sich dann nicht alle ankucken?


    Ich habe gesehen, dass du in dem Patch TsPayload umgebaut hast, aber FrameDetector und MPEGParser sind
    ja immer noch im (ungünstigen) Gleichtakt, richtig?


    Ciao,
    Eike

  • Ich hatte mir das angeschaut, aber wenn ich es richtig verstehe, löst es das Problem nicht.


    Es hat zumindest alle mir gemeldeten Problemfälle gelöst.



    Wenn er auf ein TS-Paket mit PUSI trifft, dann kehrt er zurück um von cRecorder::Action() sicherstellen zu lassen, daß wieder mindestens MIN_TS_PACKETS_FOR_FRAME_DETECTOR TS Pakete zur Verfügung stehen. Es ist also sichergestellt, daß die Frame-Erkennung immer mindestens diese Anzahl von TS-Paketen vorfindet.


    Zitat


    Wofür ist das gut, dass der Parser frühzeitig aufhört? Kann der nicht alle Frames anschauen, die er bekommt?


    Wenn du hier "Frames" schreibst meinst du wohl "TS-Pakete", oder?
    Ich möchte halt, daß er nur so viele TS-Pake anschaut, wie unbedingt nötig. Schließlich macht er das während einer Aufnahme sehr oft, und da möchte ich den Aufwand so gering wie möglich halten, damit das auch auf leistungsschwächeren Systemen funktioniert.



    Vielleicht siehst du einen Fehler, den ich bisher übersehen habe. Meiner Meinung nach müsste es so sein, daß die Frame-Erkennung immer mit mindestens 100 TS-Paketen anfängt, und die ersten beiden Video-TS-Pakete darin die benötigte Information haben. Sollten WRN_TS_PACKETS_FOR_FRAME_DETECTOR bzw. WRN_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION jemals überschritten werden, so werden entsprechende Meldungen ausgegeben und wir können die Limits rechtzeitig höher setzen (mal davon ausgehend daß sie nicht gleich auf einmal einen extremen Sprung nach oben machen).


    Klaus

  • Zitat

    Es hat zumindest alle mir gemeldeten Problemfälle gelöst.

    Du hast völlig Recht. Ich hätte erstmal das auftretende Problem beschreiben sollen, bevor ich zum
    Grund komme. Und vielleicht hätte ich auch einfach einen neuen Thread aufmachen sollen.


    Also...


    Mir ist ein Problem begegnet mit der Erkennung von I-Frames während der laufenden Aufnahme,
    also wenn der Recorder schon in "sync" ist. Es tritt nur auf bei Sendern, bei denen der Start des
    I-Frames erst im Paket (direkt) nach dem PUSI erkannt werden kann. (Bei mir unter DVB-T sind
    vor allem die ARD-Sender betroffen.)


    Es lässt sich bei mir auch gut repoduzieren (mit den passenden Sendern halt):
    Wenn man im Recorder jeweils die minimal erlaubte Zahl von TS-Paketen tröpfeln lässt...


    Code
    int Count = frameDetector->Analyze(b, min(MIN_TS_PACKETS_FOR_FRAME_DETECTOR * 188, r));


    ... lässt sich hinterher die Aufnahme nicht zurückspulen, weil die PAT-/PMT-Tabellen hinter dem I-Frame-Start
    landen. Die Analyse dazu hab ich oben ja schon dargestellt: Es wird vom MPEG-Parser unabhängig von der
    Größe von MIN_TS_PACKETS_FOR_FRAME_DETECTOR jeweils nur ein Paket auf einmal analysiert, weil nach
    diesem Paket die Anzahl der Pakete aus Sicht des Parsers eins zu klein ist. Er springt dann zurück, meldet
    ein analysiertes Paket, aber kein I-Frame.

    Zitat

    Wenn er auf ein TS-Paket mit PUSI trifft, dann kehrt er zurück um von
    cRecorder::Action() sicherstellen zu lassen, daß wieder mindestens
    MIN_TS_PACKETS_FOR_FRAME_DETECTOR TS Pakete zur Verfügung stehen. Es ist
    also sichergestellt, daß die Frame-Erkennung immer mindestens diese
    Anzahl von TS-Paketen vorfindet.

    Das ist richtig, aber er "verbraucht" dabei ein Paket - zum Beispiel das mit dem I-Frame-Start.


    Ciao,
    Eike

  • Es geht doch nichts über einen Bugreport, wo einer auch mal erzählt, was da nicht funktioniert hat. ;)


    Ich vermute, man sollte im MPEG-Parser nicht alle außer den letzten X TS-Paketen ankucken, sondern lieber bis zu X Pakete.
    Dann kuckt man z. B. 10 an, wenn man 27 bekommen hat, und kuckt 10 an, wenn man 10 bekommen hat.
    Dann könnte die Änderung sogar Performance-freundlich sein, wenn der Detector tendenziell viele Pakete liefert.


    Ciao,
    Eike

  • Wenn ich es mir recht überlege sollten die Abfragen auf MIN_TS_PACKETS_FOR_FRAME_DETECTOR in den Parse()-Funktionen eigentlich nicht mehr nötig sein. Das war noch ein Überbleibsel aus der Zeit, wo die Video-TS-Pakete nicht separat gezählt wurden.


    Magst du beiliegenden Patch mal ausprobieren (anzuwenden nach vdr-2.1.4-framedetect.diff)?


    Klaus


  • Hast du eigentlich einen bevorzugten Ort für Problemberichte?
    Hier oder auf der Mailingliste?


    Ist mir beides recht. Wenn "hier", dann vielleicht nicht unbedingt in "VDR News" sondern eher in "VDR core" ;-).
    Private Email geht natürlich auch.


    Vielleicht wieder mal der HInweis, daß ich "credits" in der HISTORY- bzw. CONTRIBUTORS-Datei nur dann eintrage, wenn ich von dem betreffenden Realname und Email-Adresse habe.
    Also nicht wundern, wenn ich Vorschläge, Patches etc. "einfach so" übernehme, ohne Namensnennung. Im Zweifelsfall schicke man mir bitte einfach eine Email mit einem entsprechenden Hinweis und ich trage das dann nach. Das jetzt nur allgemein, ist nicht auf dich bezogen ;-).


    Klaus

  • Vielleicht wieder mal der HInweis, daß ich "credits" in der HISTORY- bzw. CONTRIBUTORS-Datei nur dann eintrage, wenn ich von dem betreffenden Realname und Email-Adresse habe.

    Ich tauche ehrlich gesagt gerne in Credits von Open-Source-Software auf.
    Gestatten - Eike Sauer ist mein Name. ;) (eikesauer(bei)t-online.de)


    Ciao,
    Eike

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!