Alles anzeigen
...
Die Aufnahme lief ca. 35 Minuten und es gab 5 Fälle wo 10 oder mehr TS-Pakete nötig waren, um den Frame zu erkennen. Wobei dies nur bei I-Frames auftrat. Interessant ist auch, daß der Frametyp zwar immer im jeweils zweiten TS-Paket des Video-Streams erkannt wurde, zwischen dem ersten und zweiten Video-TS-Paket einer Payload aber bis zu 11 Pakete anderer PIDs (Audio) kamen.
Es könnte alles so einfach sein, wenn der Encoder nicht erstmal ein einzelnes Video-TS-Paket schicken würde und dann ewig viele Audio-Pakete, bevor die restlichen Video-Pakete kommen. Er könnte genausogut erstmal die Audio-Pakete schicken und dann die Video-Pakete "am Stück" (zumindest so viele, daß der Frame-Type erkannt werden kann). Dieses eine Paket vorzuziehen kann ja wohl keinen Unterschied machen. Aber dummerweise erlaubt der DVB-Standard solch ungeschicktes Verhalten...
Was also tun?
Fest steht, daß der Datenstrom nicht unnötig im Speicher umhergeschoben werden soll. Ein "Auseinanderdröseln" von Audio-, Subtitle- und Video-Daten kommt daher nicht in Frage. Bevor das erste Byte eines Video-Frames in die Aufnahmedatei geschrieben wird muß in cRecorder::Action() der Frame-Type bekannt sein, denn hier wird vor jedem I-Frame eine PAT/PMT eingefügt. Daher ist es wohl auch nicht möglich, daß der cFrameDetector erstmal bei jeder neuen Video-Payload (unabhängig davon, ob darin ein neuer Frame beginnt) ein "merk dir mal die Position" zurückgibt und cRecorder::Action() später, wenn tatsächlich ein Frame erkannt wird, diese Position anstatt der dann aktuellen nimmt, um den Index zu schreiben. Dann wäre die PAT/PMT ja nicht mehr vor dem I-Frame, und wenn sowas gleich am Anfang einer Aufnahme passieren würde, dann würde die ganze erste GOP nicht richtig wiedergegeben werden können, da zu diesem Zeitpunkt noch nicht bekannt wäre, welche PID was enthält.
Hmm, es wäre aber ohne weiteres möglich, die PAT/PMT auf jeden Fall am Beginn der Aufnahme zu schreiben. Das wäre also schonmal lösbar. Aber was, wenn die Wiedergabe irgendwo mitten in der Aufnahme starten soll? Wenn dann eine solche Stelle erwischt wird, wo keine PAT/PMT vor dem I-Frame kommt, dann haben wir wieder das gleiche Problem. Gut, das ließe sich dadurch lösen, daß bei der Wiedergabe am Einsprungpunkt der Frame nach einer PAT/PMT durchsucht wird. Das ist aber schon nicht mehr so schön, weil es halt einfach nicht mehr dir richtige Reihenfolge ist (Ursache vs. Wirkung). Und außerdem wäre das eine inkompatible Änderung des Aufzeichnungsformats. Ältere VDR-Versionen könnten eine solche Aufnahme zwar komplett abspielen, beim Einspringen irgendwo mittendrin würde aber eine GOP nicht richtig wiedergegeben. Könnte man vielleicht aber auch verschmerzen.
Gefallen tut es mir aber trotzdem nicht...
Bleibt fast nur, MIN_TS_PACKETS_FOR_FRAME_DETECTOR noch weiter hochzuschrauben. Fragt sich nur, wie hoch?
In der "guten alten Zeit" reichte mal ein einziges TS-Paket, denn da war der Frame-Type bereits im ersten TS-Paket einer Video-Payload bekannt. Irgendwann wurden es dann mal zwei TS-Pakete, da das ganze h.264-Gedöns erstmal so viel Vorgeplänkel benötigte bevor es zum Wesentlichen kam. Dann wurden es 5, weil sich einzelne Audio-TS-Pakete zwischen erstem und zweitem Video-TS-Paket eingeschlichen hatten. Und jetzt reichen in Extremfällen selbst 10 schon nicht mehr!
MIN_TS_PACKETS_FOR_FRAME_DETECTOR bestimmt, wieviele TS-Pakete auf jeden Fall "am Stück" im Puffer sein müssen, damit der cFrameDetector seine Aufgabe erfüllen kann. Der Puffer in cRecorder ist 20MB groß, 10 TS-Pakete am Stück sind 1880 Byte, also im Vergleich zum gesamten Puffer sehr wenig. Von daher gesehen sollte es kein großes Problem sein, diesen Wert deutlich zu erhöhen, also vielleicht tatsächlich auf 100, das wären dann ca. 18KB, immer noch wenig im Vergleich zum gesamten Puffer.
Das "Kleinhalten" dieser Zahl dient aber auch dem Zweck, in cFrameDetector nicht unnötig weit in die P- und B-Frames "hineinzuschauen", denn das kostet ja alles Rechenaufwand. Da aber, so wie es aussieht, der Frame-Type durchaus in den ersten beiden Video-TS-Paketen gefunden wird, wäre es vielleicht eine Überlegung wert, hierfür einfach eine zweite Konstante zu benutzen, die entsprechend klein ist (z.B. 5, um auf der sicheren Seite zu sein). Es würden dann auf jeden Fall immer 100 TS-Pakete am Stück zur Verfügung stehen (was den Aufwand nur minimal erhöhen sollte, wenn überhaupt), davon würden aber nur maximal 5 Video-TS-Pakete untersucht werden. Im einfachsten Fall würden damit dann wie bisher einfach nur 5 TS-Pakete angeschaut. Es könnten aber bis zu 95 andere Pakete dazwischen eingestreut liegen, die einfach übersprungen werden.
Das wäre meiner Meinung nach ein brauchbarer Kompromiss.
Ich werde das mal so einbauen, inclusive einer Log-Meldung, wenn eines der Limits jemals erreicht werden sollte.
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