• Bleibt jetzt nur noch zu klären ob "DefaultDuration" und/oder "Blockduration" immer irgendiwe vorhanden sind, denn es sind beides keine "zwingenden" Elemente.


    Nein, sind nicht immer vorhanden.
    Hab noch einen alten Post von Mosu gefunden, bei dem er mit dem MediaInfo-Entwickler über das Problem spricht. Ist in manchen Fällen wie vermutet nicht definiert.
    https://forum.doom9.org/showthread.php?p=1604014#post1604014

    Ich kann mir vorstellen das für Video und Audio da werte enthalten sind, aber für die Subs wird das nicht wirklich gebraucht, daher nicht "zwingend".


    Bei Subs kommt es auf das Format an. ASS und SRT ohne Blockduration gibt es nicht. Bei PGS/SUP werden die i.d.R. nicht genutzt, wegen dieses komischen Formats (leere "Zeile" beendet quasi vorherige "Zeile"). Bei IDX/SUB weiß ich es nicht aus dem Kopf.

  • 1. IDX/SUB haben (üblicherweise) eine wohldefinierte Länge.
    2. Bzgl. der Länge von Blöcken solltest du dir einmal die Erklärung bzgl. Blockduration ansehen. Im Wesentlichen besagt sie, dass die Dauer eines Blocks gegeben ist durch
    a) den durch BlockDuration (des Blocks) signalisierten Wert.
    b) den durch DefaultDuration signalisierten Wert (sofern vorhanden), falls nicht schon durch a) ein Wert gegeben ist.
    c) die Differenz der Zeitstempel des nächsten (Simple)Blocks in Anzeigereihenfolge und des Zeitstempels des fraglichen (Simple)Blocks (dessen Dauer man herausfinden will), falls der zu untersuchende Block nicht der letzte Block in Anzeigereihenfolge ist und falls nicht schon durch a) oder b) ein Wert gegeben ist.
    Für einen SimpleBlock kommt nur b) und c) in Frage; für den letzten Block (an dem du interessiert bist) nur a) und b).
    3. Es gibt grundsätzlich zwei Möglichkeiten, in einer Matroska-Datei zu spulen: Alle Level 1-Elemente (also die, die auf derselben Ebene wie Cluster sind) haben eine EBML ID mit einer Länge von vier Bytes; man kann die Datei danach absuchen (natürlich muss man Vorkehrungen für falsche Treffer treffen). Oder man benutzt die Cues (den Index). Sofern vorhanden kannst du hier die Position des letzten Schlüsselbildes herausfinden und dann von dort aus den Rest der Datei parsen. Die Cues selbst werden üblicherweise in einem Suchkopf ganz am Anfang referenziert.

  • sneaker2
    Habe mir mal ein Stück durchgelesen. Ist dennoch etwas verwirrend für mich, aber anscheinend auch nicht so schwer.

    Also Block-Duration, wenn nicht vorhanden, dann DefaultDuration nutzen (dazu beachten ob Laced Frames vorhanden).
    Wenn keines der beiden da ist, dann die "nächste" Cluster Startzeit mit der aktuellen verrechnen.
    Problem hier, was ist bei dem letzten Cluster, der hat keinen nächsten.

    Die Untertitel schaue ich mir dann noch mal etwas genauer an. BD-Sups habe ich genug und auch DVD-idx/sub.

  • Danke mkver für die Erklärung.

    Du hast auch gleich die Lösung für den letzten Block geliefert.

    Was das parsen ansich angeht, so habe ich sicher keinen hoch-perfekten Parser, aber er tut bei "korrekten" mkvs auch korrekte Arbeit.
    Ich sehe das bei mkvmerge fast immer Such-Indexe und oft Cue-Index geschrieben werden, aber machen das immer alle anderen mkv-writer Apps auch so?

  • Ja, das ist so ziemlich Standard. Die einzige mir bekannte Ausnahme (wenn man davon absieht, dass z.B. mkvmerge bei entsprechenden Kommandozeilenparametern ebenfalls Dateien ohne Cues erstellen kann) ist das in viele Versionen von x264 eingebaute Matroska Ausgabemodul (das auf Haalis Muxer basiert); aber diese Dateien werden üblicherweise noch einmal remultiplext (mit Tonspuren etc. versehen).
    Beachte übrigens, dass eine GOP über mehrere Cluster verteilt sein kann; d.h. wenn du die Cues analysierst und dann zu dem Cluster mit dem letzten Schlüsselbild der Datei springst, musst du noch nicht den letzten Cluster der Datei haben.

  • Genau, der letzte Cluster muss(hat oft) nicht die Infos die ich brauche, da es erstmal nur um das Video geht.
    Ich müsste sicher immer nur im "hinteren" Bereich des mkvs suchen. Also vll die letzten 10% Cluster genauer untersuchen. Vorher reicht es wohl aus zu wissen das ein neuer Cluster einen höheren Zeitstempel hat.

    Genial wäre natürlich man hätte in Matroska ein Element: Anzahl Cluster und dann eine Tabelle mit Startbytes.
    Ich hatte gesehen das es in Clustern ein Element PrevSize gibt, was einem helfen könnte, leichter rückwärst zu parsen. Aber es ist nicht mandatory und daher nicht zuverlässig.

    Mal sehen wie fix mein Parser ist, wenn er durch ein 30gb Full-Bluray-mkv die Cluster parst.

  • Ältere Versionen von mkvmerge haben standardmäßig einen Suchkopf am Ende der Datei geschrieben, in dem jeder Cluster referenziert wurde. (Dieser zweite Suchkopf wurde wiederum vom ersten Suchkopf referenziert.) Aber das ist nicht mehr standardmäßig so, denn die Positionen aller Cluster bringt beim Spulen eigentlich keinen Mehrwert, man muss ja mit dem Dekodieren sowieso beim Schlüsselbild anfangen.
    Du musst nicht 10% oder so parsen; parse die Cues und gehe zum letzten Schlüsselbild. Das reicht.

  • OK, aber die Cues sind eben auch kein zwingendes muss. Von daher nicht so sicher oder?

    Ausserdem muss ich wie von sneaker2 anfangs erwähnt:
    auch die Startzeit des Videos betrachten.
    Es macht schon sinn im ordered chapter die entsprechende Startzeit zu setzen.
    Von daher werde ich sicher auch den ersten oder zweiten Cluster parsen müssen.


    Kann denn ein Schlüsselbild auch ein Audio Block sein? Also das im letzten Cluster mit Schlüsselbild kein Video ist.
    Denn dann muss ich auf jedenfall weiter zurückliegende Cluster untersuchen.

    In den Cues scheint es immer eine Spurnummer für das Video zugeben, sind die Cues ausschliesslich für Video Spuren/Daten?

  • Die Bilder werden benutzt. Das sind nur von anderen Bildern nicht referenzierte Bilder. Die könnte ein Player theoretisch auslassen, wenn er z.B. nur im Schnellvorlauf durchs Video möchte. Beim "normalen" Abspielen werden die aber ganz normal dekodiert und angezeigt. Davon abgesehen ist das Flag eh häufig falsch gesetzt, daher sollte man das einfach ignorieren.

    Einmal editiert, zuletzt von sneaker2 (9. Januar 2018 um 10:58)

  • Ich habe da doch noch ne Frage.

    In mkvInfo steht bei einem SimpleBlock und Block immer die Anzahl der Bilder. Bei "Video-Blocks" scheint es immer nur ein Bild zu geben (anders als bei Audiospuren wo oft 8 Bilder in einem SimpleBlock sind).

    1. Frage: Gibt es dafür ein Byte/Bit was ich auslesen könnte, oder wie kommt diese Anzahl der Bilder zustande?
    2. Frage: Kann es für Video auch mehrere Bilder geben?

    3. Frage: 2.Frage = ja -> SimpleBlock: die Dauer müsste dann Anzahl_Frames * DefaultDuration sein?
    3.1: und für eine BlockGroup ändert sich dann die BlockDuration?

    Für den SimpleBlock muss/kann/sollte man ja die DefaultDuration nutzen, was mir dann immer exakte Nanosekunden liefert.
    Da in einer BlockGroup die BlockDuration vorhanden ist, könnte man diesen Wert ja eigentlich gleich nutzen. Allerdings ist er nur auf Millisekunden Genauigkeit begrenzt.
    Ich mache es momentan so das auch für eine BlockGroup die DefaultDuration verwendet wird um den "EndzeitStempel" zu ermitteln.

    4.Frage: 2.Frage= nein -> dann sollte es doch keine Probleme geben ?
    4.1: 2.Frage=ja -> müsste/könnte ich dann ebenfalls wie in Frage 3 die Dauer berechnen?

    Danke an Alle. Mein Parser ist so gut wie fertig und ich bekomme nun endlich nach vielen Jahren, einen exakten Nanosekunden Wert für die Video-Spieldauer, welche nach ersten Tests perfekt zu seien scheint.

  • 1. Siehe: https://www.matroska.org/technical/spec…block_structure
    Also schauen, ob Lacing-Flag (Bits 5&6 von Flags) != 00 und falls ja, dann "0x00 Number of frames in the lace-1 (uint8)" auswerten.
    2. Ja, wüßte nicht, warum nicht.
    3. Ja. (falls DefaultDuration gesetzt)
    3.1 Was meinst Du mit "ändern"? Nein. BlockDuration ist die BlockDuration. Die ändert sich nicht und ist IMHO "stärker" als n * DefaultDuration.
    4.1 Ja

  • 1. Siehe: https://www.matroska.org/technical/spec…block_structure
    Also schauen, ob Lacing-Flag (Bits 5&6 von Flags) != 00 und falls ja, dann "0x00 Number of frames in the lace-1 (uint8)" auswerten.


    In meinen test mkvs war dies FLAG Byte immer 0x00. Von daher kann ich ja dort auch keine Bilder ermitteln... also wenn dort alles 0 ist, dann gibt es nur 1 Bild?


    2. Ja, wüßte nicht, warum nicht.
    3. Ja. (falls DefaultDuration gesetzt)


    Ok.


    3.1 Was meinst Du mit "ändern"? Nein. BlockDuration ist die BlockDuration. Die ändert sich nicht und ist IMHO "stärker" als n * DefaultDuration.

    Mit "ändern" meinte ich das der Wert sich entsprechend erhöht, je nachdem wieviele Bilder vorhanden sind.
    Also 1 Bild = BlockDuration 40ms, dann würde aus 4 Bilder 160 ms werden. Oder bezieht sich die BlockDuration nur auf ein einzelnes Bild?

  • Hi sneaker2

    Mir ist da noch etwas aufgefallen. Ich habe bei MPEG2 im mkv bei Video Interlaced Flag eine 1. Die DefaultDuration wird in mkvInfo so angegeben
    50 Bilder je Sekunde im Falle eines Videos
    Dauer: 20ms

    Das Video ist von DVD (DS9) und hat 25 FPS.

    Bei jeder BlockDuration ist 40ms angegeben.

    Die 25FPS werden aber nirgends im mkv hinterlegt. Wie muss ich das mit dem Interlaced handhaben?
    Kann ich immer davon ausgehen das ich die DefaultDuration verdoppeln muss?

Jetzt mitmachen!

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