Hallo,
ich dachte, ich gebe mal 'ne Zusammenfassung von meinen Versuchen (vielleicht kann ich ja ein paar Mitstreiter locken ...)
Vorne weg ein paar Details:mein
- Ich habe einen DVD-Brenner und brenne liebend gern Mitschnitte ohne Werbung auf DVD, insbesondere wenn Sie mit AC3-Sound kommen (Pro7) oder zusätzlich mit Originalton (Arte).
- Hierfür nehme ich u.a. ds.jar, da ich ja von den VDR Dateien zu einem DVD-Image kommen muss (geschnittenes vdr durch ds.jar, dann tcmplex, dann dvdauthor, dann mkisofs und dvdrecord)
- Das klappt wunderbar (meistens), aber ds.jar ist ja nun nicht mehr
- Mein grösstes Problem war immer Audio/Video Sync, und das hätte ich gerne für alle Kanäle gelöst. ds.jar war echt prima...
- Also hätte ich gern einen Ersatz für ds.jar, möglichst unter Linux auf der Kommando Zeile
- Ich kann nicht Programmieren, und das bisschen, was ich kann, ist Perl, aber was soll's?
Also habe ich mich auf die Suche nach Infos über MPEG2 Streams gemacht. Da ich mal aufgeschnappt habe, dass .vdr Files PES Dateien sind und ich als input von mplex immer ES-Streams angeben muss, wollte ich auch wissen, wie die aufgebaut sind.
Hier erstmal eine Uebersicht über die Infos, die ich gefunden habe. Falls ein Guru das liest, BITTE KORRIGIEREN UND ERGAENZEN. Danke.
Eine Video Datei im MPEG Format (ES = elementary stream):
- Einzelne Frames sind in GOPs (groups of pictures) organisiert, das erste Bild in voller Schönheit (I-Frame), die danach als Differenz zu dem Frame davor (P-Frame), oder als Differenz zu dem davor UND dem danach (B-Frame). Meistens (immer?) sind 15 Frames in einer GOP. Die Länge eines GOP (in Byte, nicht in Frames) variiert je nach Komprimierungsgrad von GOP zu GOP (variable Bitrate).
- Aus der Frame-Rate und der Anzahl der Frames ergibt sich zwangsläufig die Länge des Videos. Soweit alles ganz ok.
- Audio (ebenfalls ES Stream)
-Eine Audio Datei im MPEG Format (MP2) besteht aus Frames, die immer 1152 Bytes lang sind. Aus der Bitrate und der Anzahl der Frames ergibt sich die Länge des Audiostücks. Soweit auch ganz klar.
Nun wirds langsam interessant:
Wenn man Audio und Video Dateien synchron abspielen will und nur einen Uebertragungskanal hat (so wie z.B. ein .VOB File auf einer DVD oder wie ein .vdr File), dann muss man abwechselnd Video und Audio Daten senden. Damit sind wir (fast) beim
PES Stream (= packetized elementary stream):
- Der PES besteht also aus zerhackten und gemischten Video und Audio Streams. Etwa so:
ES-Video: VVV VVV VVV VVV VVV VVV VVV VVV VVV
(V steht für Video Stream, drei Vs ein GOP)
ES-Audio: AA AA AA AA AA AA AA
(A steht für Audio, zwei As ein Frame)
PES A/V: VVAVVAVVAVVAVVAVVAVVA
OOPs, nun sind die GOPS und die Audio Frames zerhackt..... Macht aber nix (später mehr). Das eigentliche Problem besteht in der Synchronisation der Daten. Welches (wieder rekonstruierte) Audio-Schnippselchen gehört zu welchem (rekonstruierten) Video-Schnippselchen? Wenn der Sender einen kontinuierlichen Stream schickt, dann hat man ja schliesslich keinen Anfang und kein Ende.
Jetzt kommen die PES-HEADER ins Spiel:
Der PES Stream enthält neben den zerhackten GOPs und Audio Frames auch Packet-Header, in denen Infos zur Audio/Video Synchronisation stehen. Eigentlich sieht der Stream so aus:
PES-A/V: HVHVHAHVHVHAHVHVHA
(H für Header)
Also steht vor jedem PES-Packet ein Header mit Infos über den Stream (Welcher Stream ist es, Video 1 oder 2 oder 3 ... Audio 1 oder 2 oder 3 ... Private Data (Teletext) oder oder oder) und mit TIMING Infos. D.h. der Header kann einen Zeitstempel enthalten, der sagt "spiele diesen Schnipsel bei 10.543 sec".
Also habe ich versucht, in einem 5 min .vdr File PES-Packete zu finden. Die starten immer mit 0x000001, dann kommt die Stream Bezeichnung und dann die Länge des Packets. Und siehe da: es geht (nach eingem Tüfteln), ich kann mich per Skript von Packet zu Packet "hangeln".
Dann habe ich versucht, die Streams in eigene Dateien zu schreiben (also Audio PES Packete in ein File und Video-PES Packete in ein anderes). Es geht, mplayer spielt den Video Stream ohne Ton, tcprobe sagt einmal Audio und einmal Video. Hurra.
Schliesslich habe ich versucht, die PES-Header los zu werden. Dazu habe ich nicht mehr die gesamten Packete in getrennte Dateien geschrieben, sondern nur den Payload (=Packet minus Header). Und was soll ich sagen: Es geht! Kein Problem mit zerhackten GOPs oder Audio Frames. Die Payloads hintereinander ergeben saubere ES Streams. mplayer und tcprobe sind happy. Cool....oder?
Nun habe ich also das langweiligste programmiert, was man sich nur vorstellen kann: denn X-ten demuxer, den niemand haben will oder gebrauchen kann. Der produziert aus .vdr files (die ja PES sind) getrennte Audio und Video ES-Streams. Und dafür habt Ihr bis hierher gelesen. Sorry.
Tut mir echt leid.
Aber es geht noch ein wenig weiter (ich sage nicht, dass es besser wird ;-))
Wie gesagt, der X-te demuxer, der sich nicht um A/V Sync kümmert. Nun, die anderen demuxer sagen ja sogar noch, wieviel Verschiebung die Audio und Video Streams in ms haben. Der mutiplexer der dvb-mpegtools der Metzler-Bros nimmt sogar ein .vdr File auseinander, und baut es ohne shift wieder zusammen - manchmal.
Wo ist das Problem? Warum nur manchmal? Was programmiere ich mir zusammen, wo ich doch gar nicht programmieren kann? Mal wieder ein bisschen ASCII-Art (mit der bitte um Korrektur):
Ein PES:
HVHVHAHVHVHAHVHVHA
In den PES-Headern stecken, wie oben gesagt, Timing Informationen, genauer gesagt PTS und DTS Infos. Das sind die Zeitstempel die angeben, wann ein bestimmtes Schnippselchen Audio oder Vodeo Dekodiert (DTS) oder Präsentiert (=abgespielt) werden soll. Wenn also der erste Teil meines PES aus
HVHV
besteht, dann steht da z.B. drin, "abspielen nach 00:00:10.345". Danach kommt
HA
da steht z.B. drin "abspielen nach 00:00:10.545".
Nun kann ich getrost hingehen und demuxen und sagen "Audio Abspielen muss 200 ms nach Video Abspielen starten". Nun kommt das Schneiden (oje oje oje)
Vorher
HVHVHAHVHVHAHVHVHAHVHVHA
Schnitt | |
HVHVHAHVHVHVHAHVHVHA
Das soll heissen: Ich habe ein bisschen Video rausgeworfen, aber wieviel Audio weiss ich auch nicht so genau undistjaauchgarnichtsoschlimmoderweilichguckjanuraufGOPsundüberhaupt
In anderen Worten:
- wegen der GOP Strukturen kann mann nur effizient (=sehr schnell) zwischen GOPs schneiden (also alle 15 Bilder), sonst müsste man die Bilder neu kodieren (laaaange Arbeit => transcodiere mal 'nen Spielfilem)
- dabei gehen aber, tja, weiss auch nicht, ein paar Audio Frames drauf. Wieviele? Puuh, soviele wie zwischen den GOPS halt stehen, die wegfallen. Lange Rede, kurzer Sinn:
Durch das Schneiden an GOPs ergibt sich eine Veränderung der A/V Verschiebung. Deshalb war/ist ds.jar wahrscheinlich so cool: es findet Schnitte und gleicht spätere Verschiebungen durch Einfügen oder Löschen von Audio Frames aus. HIER BITTE JA ODER NEIN ANTWORTEN (Nein bitte mit Erklärung ;-))
Das habe ich natürlich auch ausprobiert, und habe meine 5 min test .vdr File mit meinem Demuxer demuxt und mit tcmplex wieder zusammengebaut: Ergebnis: A/V nicht mehr synchron.
Dann habe die AV sync aus den PTS-Stamps des PES Streams berechnet und 6 Audio Frames weggeschmissen. Siehe da, nach remux wieder synchron. Hey Coool! Was für ein schöner 1ster Mai (na gut, wenn man seinen Compi liebt)!
Also werde ich mal weiter tüfteln (der nächste erste Mai kommt bestimmt), und jetzt seid Ihr dran (wenn Ihr noch dran seid):
- Habt Ihr überhaupt bis hierhin gelesen? Wirklich? Warum? Könnt Ihr nicht schlafen?
- Wisst Ihr was über den Quatsch, den ich geschrieben habe, oder kennt Ihr jemanden, der jemanden kennt, der mir auf die Sprünge helfen könnte (dein Opa sein Kollege sein Enkel oder so)?
- Würdet Ihr so ein Tool überhaupt wollen, oder ist ds.jar / PVAstrumento gut genug?
- Könnt Ihr programmieren und sowas nicht viel besser als ich?
- Wisst Ihr wie man einen PTS-Timestamp mit 33 bit verteilt auf 40 Bit am besten in Perl entschlüsselt? Oder wo derjenige wohnt, der sich so was ausgedacht hat? Wärt Ihr bereit, dem mal den Marsch zu blasen? (Erklärung: hier das PTS-TIMESTAMP Format als BIT-Code:
0010XXX1XXXXXXXXXXXXXXX1XXXXXXXXXXXXXXX1
die Xse sind wichtig, die anderen Bits sind immer wie angegeben)
- Würdet Ihr ein Tool testen und mehr Feedback geben als "echt sch*** dass Du nicht coden kannst" (das weiss ich nämlich schon;-))?
JETZT KOMMTS:
- Wie ist AC3 aufgebaut? Wie MP2 was die Header angeht?
- Wäre das Beste nicht Frame-genaues Schneiden, mit einem neuen GOP mit evt weniger als 15 Frames? Kann ein DVD Player das lesen?
- Wenn man über den Audiostream sync-Pannen ausbügeln will, muss man dann nicht eigentlich den Audiostream komplett neu kodieren, weil man sonst auch nur in Frame Schritten arbeiten kann?
- Wie lang ist ein Audio Frame eigentlich? Meine Rechnung:
1152 Byte/s / 192KBit/s = 0.048 s. Stimmt das? Wie ist das mit anderen Bit-Raten? Ist MP2 immer "constant bit rate" codiert? Wie ist das mit AC3?
Ich habe noch mindestens 100 Fragen mehr, aber
1) es ist spät
2) Bier ist alle
3) Ich muss mal Rauchen
(ich weiss, ich lebe VIEL zu ungesund)
Ich freue mich auf Input
Cheers
doc