Entwicklung eines 264 to avi Videokonverters fĂŒr die QCM-08DL Dashcam

TatsĂ€chlich widmet sich der Artikel der Entwicklung eines Programms zum Umpacken von DVR-Videos von einem Container in einen anderen, wenn dies als Konvertierung bezeichnet werden kann. Obwohl ich mein ganzes Leben lang dachte, dass der Konverter das Videoformat konvertiert (transkodiert). Dieser Artikel ist der zweite Teil meiner letzten Veröffentlichung, in der ich ausfĂŒhrlich ĂŒber den Zugriff auf alle Videoaufnahmen des DVR sprach. Ganz am Anfang der Veröffentlichung habe ich mir jedoch eine andere Aufgabe gestellt: den Algorithmus zu untersuchen, mit dem das Standard-264-avi-Repacker-Programm funktioniert, und dasselbe Programm zu erstellen, das dieselben Operationen ausfĂŒhrt, jedoch nicht fĂŒr eine, sondern fĂŒr eine ganze Gruppe von Dateien "Ein Klick".

Ich werde das Wesentliche aller Dinge noch einmal in einfacher Sprache erklÀren.

Der Benutzer hat einen Videorecorder, beispielsweise das beliebte Modell QCM-08DL. Er braucht ein Video fĂŒr ein bestimmtes Datum und eine bestimmte Uhrzeit. Er kann es entweder auf einem USB-Stick oder ĂŒber eine webbasierte Schnittstelle eines DVR zu einem Computer entfernen. Die extrahierte Videodatei (Erweiterung .264) wird nur im Player-Programm geöffnet, das mit dem DVR geliefert wird. Der Spieler fĂŒhlt sich sehr unwohl. Sie können es weiterhin im VLC-Player öffnen, indem Sie den RAW H264-Modus in den Demultiplexing-Einstellungen (Einstellungen fĂŒr fortgeschrittene Benutzer) einstellen. Gleichzeitig stören offenbar Blöcke von Audiostreams, die als Video interpretiert werden und keinen Ton enthalten, die normale Wiedergabe. Und um das Video in einem beliebigen Player zu öffnen, muss die .264-Datei zunĂ€chst in ein gĂ€ngiges Format konvertiert werden, z. B. avi. Ein Konvertierungsprogramm ist ebenfalls im DVR enthalten. Sie fĂŒhlt sich aber auch sehr unwohl. Wenn es um eine oder mehrere Dateien geht, gibt es keine Probleme. Wenn es jedoch darum geht, Zugriff auf alle Videos auf der Festplatte zu erhalten und diese noch mehr in das beliebte Format zu konvertieren, sind die Standardwerkzeuge praktisch nicht geeignet.



Das Problem des Zugriffs auf alle Dateien wurde behoben. Dies war das Thema der letzten Veröffentlichung. Wir lösen das zweite Problem. Sie gaben mir bereits "gute RatschlÀge": Es reicht aus, die Erweiterung im Dateinamen von "264" in "avi" umzubenennen, und alles wird schief gehen, sagen sie, es gibt nichts zu stören. Dies ist jedoch der hÀufigste Fehler eines normalen Benutzers, der die relevanten Probleme in der Regel nicht versteht.

In einer frĂŒheren Veröffentlichung habe ich bereits kurz ĂŒber die Struktur der .264-Quelldatei geschrieben. Lass mich dich erinnern.

Die Hauptinformationen mit Audio- und Videostreams stammen aus einem Offset von 65.536 Bytes. Videostream-Blöcke beginnen mit einem 8-Byte-Header „01dcH264“ (auch „00dcH264“). Die folgenden 4 Bytes beschreiben die GrĂ¶ĂŸe des aktuellen Blocks des Videostreams in Bytes. Nach 4 Bytes von Nullen (00 00 00 00) beginnt der Videostreamblock selbst. Die Audio-Stream-Blöcke haben den Titel "03wb" (obwohl nach meinen Beobachtungen das erste Zeichen des Headers in einigen FĂ€llen nicht unbedingt "0" war). Nach - 12 Bytes an Informationen, die ich noch nicht herausgefunden habe. Und beginnend mit dem 17. Byte - einem Audiostream mit einer festen LĂ€nge von 160 Bytes. Am Ende der Datei befinden sich keine Tags.

Ich werde das oben Gesagte kommentieren. Alles, was bis zu einem Offset von 65.536 Bytes ist, erwies sich als ungelöst und unnötig. Von einem Offset von 65.536 Bytes bis zum ersten Header des Streams gibt es eine kleine LĂŒcke, deren Inhalt ebenfalls nicht aufgelöst wird, und außerdem erscheint sie, wie ich ĂŒberprĂŒft habe, nach der Konvertierung durch ein regulĂ€res Programm nicht in der Ausgabe-AVI-Datei.

Jeder Block des Videostreams reprĂ€sentiert einen Frame. Das erste Zeichen in der Kopfzeile der Blöcke des Videostreams ist optional "0". Ich habe seinen Zweck nicht herausgefunden, weil es, wie ich herausgefunden habe, nicht der SchlĂŒssel zur Lösung der Aufgabe ist. Das zweite Zeichen im Header des Videostreams kann entweder "1" oder "0" sein. Im zweiten Fall ist der Inhalt des Videostreamblocks der sogenannte Referenzrahmen. Und im ersten Fall ist der Inhalt des Videostreamblocks ein codierter komprimierter Rahmen, der vom Referenzrahmen abhĂ€ngt. Die GrĂ¶ĂŸe des Inhalts des Referenzrahmens ist erheblich grĂ¶ĂŸer als die GrĂ¶ĂŸe des Inhalts des komprimierten Unterrahmens. Die Wiederholungszeit des Referenzrahmens hĂ€ngt höchstwahrscheinlich von den Einstellungen des KomprimierungsverhĂ€ltnisses im DVR ab. In meinem Fall betrug die Wiederholungszeit jedoch 1 Bild / Sek.


Das regulĂ€re Programm zum Umpacken von Videos vom Container „264“ in den Container „avi“ ergab unterschiedliche Ergebnisse hinsichtlich der Bildrate. Bei Videos, die im hochauflösenden Modus (704 * 576) aufgenommen wurden, betrug die Bildrate 20 Bilder / Sek. Und bei niedriger Auflösung (352 * 288) - 25 Bilder / Sek. Diese Informationen werden vom MediaInfo-Dienstprogramm bereitgestellt. Außerdem wird angegeben, dass die VideogrĂ¶ĂŸe in jedem Fall gleich ist: 720 * 576, und die GrĂ¶ĂŸe des Videostreams (dieses Dienstprogramm meldet) 704 * 576 oder 352 * 288. Die meisten Player werden speziell fĂŒr die GrĂ¶ĂŸe des Videostreams bereitgestellt. Ich habe jedoch einen Player getroffen, der beim Abspielen einer 352 * 288-Datei den Halbbildmodus falsch angezeigt hat. Ich wollte diesen kleinen Fehler des Vollzeit-Repackers beheben, indem ich mir die Bytes des Inhalts des Videostreams ansah und von dort Informationen ĂŒber die BildgrĂ¶ĂŸe abrief. Aber in Eile konnte ich das nicht tun. Das Obige ist in der folgenden Abbildung dargestellt.



Nun zur Bildrate. Wie ich herausgefunden habe, greift der regulĂ€re Repacker auf kein Headerfeld des Containers „264“ zu. Es beurteilt die Bildrate, indem es das VerhĂ€ltnis der Anzahl von Videoblöcken und Audiostreams berechnet. Und dieser Wert in der Berechnung wird nicht einmal auf den nĂ€chsten ganzen Wert gerundet, wie aus der obigen Abbildung ersichtlich ist (grĂŒn eingekreist). Wie ich herausgefunden habe, ist die Anzahl der Audio-Stream-Blöcke pro Zeiteinheit immer und ĂŒberall (in jeder Datei) festgelegt, nĂ€mlich 25 Blöcke pro Sekunde. Wenn Sie die Videodatei mit einer Frequenz von 20 Bildern / Sek. Untersuchen, tritt das Referenzbild (Block) alle 19 komprimierten Bilder und im Fall von 25 Bildern / Sek. Auf. - alle 24 komprimierten Frames.

Wir untersuchen weiterhin die Struktur des Headers des Videostreams. Wir haben die ersten acht Bytes herausgefunden: Dies ist die Bezeichnung der Referenz oder des komprimierten Frames plus das SchlĂŒsselwort „H264“. Die folgenden vier Bytes beschreiben, wie ich herausgefunden habe, nicht die genaue, sondern die ungefĂ€hre GrĂ¶ĂŸe des Inhalts des Videostreams. Ein normaler Repacker wirft alle Bytes dieses Inhalts vollstĂ€ndig und schreibt dann die resultierende GrĂ¶ĂŸe in die entsprechenden Felder des AVI-Containers. Dieser Wert unterscheidet sich von dem Wert, der im entsprechenden Feld der .264-Quelldatei angegeben ist.

Teilweise habe ich zwölf Bytes an Informationen nach dem Header des Audio-Stream-Blocks erraten. In jedem Fall sind die SchlĂŒsselelemente die letzten 4 Bytes, nach denen der Audiostream beginnt. Dies sind zwei 16-Bit-Zahlen, die die Anfangsparameter des iterativen Decodierungsschemas von ADPCM zu PCM beschreiben. Durch die Dekodierung wird der Audiostream um das Vierfache erhöht. Als ich die Dateien im Voraus recherchierte, stellte ich fest, dass der Vollzeit-Repacker das Audio dekodiert, den Videoinhalt jedoch unverĂ€ndert lĂ€sst.

Ohne tiefes Wissen habe ich lange versucht herauszufinden, welcher Decodierungsalgorithmus in meinem Fall verwendet wurde. Intuitiv bereits vermutet, dass die Komprimierungsmethode ADPCM angewendet wurde. Genauer gesagt, nicht intuitiv, sondern mit einem kompetenten Ansatz, der darauf basiert, dass der Audiostream genau viermal komprimiert wird. Und wenn ich ein Fragment in Adobe Audition als RAW in verschiedenen Formaten öffne (und dasselbe Fragment nach dem Umpacken mit einem regulĂ€ren Programm vergleiche), hat mir ADPCM ein sehr Ă€hnliches (aber nicht genaues) Klangergebnis gegeben. Bei der Analyse des Komprimierungsalgorithmus haben mir die Informationen auf der Website wiki.multimedia.cx/index.php/IMA_ADPCM geholfen. Hier lernte ich die beiden anfĂ€nglichen Decodierungsparameter kennen und stellte dann mithilfe der „Poke-Methode“ fest, dass diese anfĂ€nglichen Parameter vor dem Start des Audiostreams in 4 Byte aufgezeichnet wurden. Ich werde die Funktionsweise des Algorithmus beschreiben und eine grobe mathematische Interpretation geben (unter dem Spoiler).

Details zum ADPCM-Decodierungsalgorithmus
Es gibt eine Folge von Proben x0,x1,x2, dots.DarĂŒber hinaus gibt es, wie bereits erwĂ€hnt, zwei Anfangsparameter y0und s0. Benötigen Sie eine neue Beispielsequenz y0,y1,y2 dots.. Wie Sie bereits erraten können, ist das erste Ausgabebeispiel bereits bekannt: Es stimmt mit einem der Anfangsparameter ĂŒberein y0. Dies ist etwas anderes als eine „anfĂ€ngliche Verschiebung“. Es ist anzumerken, dass die Eingangs- (Quell-) Abtastwerte in vier Bits codiert sind. Bei vorzeichenbehafteten Typen fallen Ganzzahlen von -8 bis einschließlich 7 unter die Codierung. Das höchstwertige Bit ist tatsĂ€chlich fĂŒr das Vorzeichen der Zahl verantwortlich. Die Ausgabe-PCM-Abtastwerte, die nach dem Decodieren erhalten werden, haben ein vorzeichenbehaftetes 16-Bit-Standardformat.

Wenn Sie den Algorithmuscode in C analysieren, sehen Sie zwei Tabellen. Sie sind unten aufgefĂŒhrt.

int ima_index_table[] = { -1, -1, -1, -1, 2, 4, 6, 8 }; 


 int ima_step_table[] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 }; 


Man kann sagen, dass diese beiden "magischen" Arrays tabellarische Funktionen sind, in deren Argumenten dieselben zwei Anfangsparameter eingesetzt werden. WÀhrend der Iteration werden bei jedem Schritt die Parameter neu berechnet und erneut in diese Tabellen eingesetzt. Lassen Sie uns zunÀchst sehen, wie dies im Code implementiert ist.

Wir erklĂ€ren die notwendigen, einschließlich Hilfsvariablen.

 int current1; int step; int stepindex1; int diff; int current; int stepindex; int value; //  ; 


Bevor Sie mit der Iteration beginnen, mĂŒssen Sie der aktuellen Variablen den Anfangsparameter zuweisen y0und die Variable stepindex ist s0. Dies geschieht außerhalb des fraglichen Algorithmus, daher reflektiere ich dies nicht mit Code. Das Folgende sind die Transformationen, die in einem Kreis (in einer Schleife) ausgefĂŒhrt werden.

  value = read(input_sample); //   ; current1 = current; stepindex1 = stepindex; step = ima_step_table[stepindex1]; diff = step>>3; if(value & 1){ diff += step >> 2; } if(value & 2){ diff += step >> 1; } if(value & 4){ diff += step; } if(value & 8){ current1 -= diff; if(current1 < -32768){ //,  ""; current1 = -32768; } }else{ current1 += diff; if(current1 > 32767){ //,  ""; current1 = 32767; } } //      :   current1; stepindex1 += ima_index_table[value & 7]; if(stepindex1 < 0){ // ""; stepindex1 = 0; } if(stepindex1 > 88){ // ""; stepindex1 = 88; } output_sample = curent1; //   ; current = current1; stepindex = stepindex1; 


Im Hilfsvariablenschritt aus dem Array ima_step_table wird der Wert am Index stepindex1 geschrieben. Bei der ersten Iteration ist dies der Anfangsparameter s0FĂŒr weitere Iterationen ist dies ein neu berechneter Parameter si. Dann wird der Wert aus diesem Array durch eine Bitverschiebungsoperation nach rechts durch 8 (anscheinend vollstĂ€ndig) geteilt, und die Diff-Variable wird als Ergebnis dieser Teilung initialisiert. Dann werden die drei niedrigstwertigen Bits des Wertes der Eingangsabtastung analysiert und abhĂ€ngig von ihren ZustĂ€nden kann die Diff-Variable um drei Terme eingestellt werden. Die Terme sind eine Ă€hnliche ganzzahlige Division des Diff-Wertes durch 4 (>> 2), durch 2 (>> 1) oder Diff ohne Änderungen (sei es eine Division durch 1 zur Verallgemeinerung). Dann wird das höchstwertige (vorzeichenbehaftete) Bit des Wertes der Eingangsabtastung analysiert. AbhĂ€ngig von ihrem Zustand wird die zuvor erzeugte Diff-Variable zur Variablen current1 addiert oder subtrahiert. Dies ist der Wert des Ausgabebeispiels. Aus GrĂŒnden der Richtigkeit sind die Werte auf oben und unten beschrĂ€nkt. Dann wird stepindex1 angepasst, indem der Wert aus dem Array ima_index_table durch den Index des Werts des Eingangsabtastwerts addiert wird, wobei das Vorzeichenbit auf Null zurĂŒckgesetzt wird. Stepindex1-Werte unterliegen ebenfalls einer Begrenzung. Ganz am Ende, bevor dieser Algorithmus wiederholt wird, werden den aktuellen und Schrittindexwerten die gerade wiedergegebenen Werte von current1 und stepindex1 zugewiesen, und der Algorithmus wird erneut wiederholt.

Sie können versuchen, es herauszufinden, um ungefĂ€hr zu verstehen, wie die Diff-Variable gebildet wird. Lass fi=f(si). Dies sind die Werte der Schrittvariablen bei jedem i-ten Schritt der Iteration als Werte der Funktion (Array) des Arguments siwo i=0,1,2, dots. Der Einfachheit halber bezeichnen wir die Diff-Variable als d. Nach der Logik der oben beschriebenen Argumentation haben wir:

di= fracfi8+xi(0) fracfi4+xi(1) fracfi2+xi(2)fi,

wo xi(0),xi(1),xi(2)- niedrige 3 Bits einer Zahl xi. Wir fĂŒhren zu einem gemeinsamen Nenner und wandeln diesen Ausdruck in eine bequemere Form um:

di= fracfi8 Bigg(1+2xi(0)+4xi(1)+8xi(2) Bigg)=

= fracfi8 Bigg(1+2 Big(xi(0)+2xi(1)+4xi(2) Big) Bigg)= fracfi8(2xi+1).

Die letzte Konvertierung basiert auf der Tatsache, dass in gewissem Sinne die mindestens drei Bits (0 oder 1) einer Zahl vorliegen xiMit den dargestellten Koeffizienten gibt es etwas anderes als das Schreiben des Absolutwerts dieser Zahl und des höchstwertigen Bits der Zahl xientspricht dem Vorzeichen des gesamten Ausdrucks. Weiter nach der Formel

yi+1=yi+di

Ein neuer Stichprobenwert wird basierend auf dem alten berechnet. ZusÀtzlich wird ein neuer Variablenwert berechnet. s::

si+1=si+t(|xi|).

Das Modul in der Formel gibt an, dass die Variable xikommt in Funktion tohne das höchstwertige Vorzeichenbit, das sich im Code widerspiegelt. Eine Funktion tIst der Wert des Arrays ima_index_table, wobei der Index dem Argument entspricht.

Bei der Beschreibung der Formeln habe ich die oben und unten beschriebenen Restriktionsoperationen vernachlĂ€ssigt. Das gesamte iterative Schema sieht ungefĂ€hr so ​​aus:

y0; s0;  x0,x1,x2, dots

di= fracf(si)8 big(2xi+1 big)

yi+1=yi+di

si+1=si+t(|xi|)

i=0,1,2, dots.



Sehr tief in der Theorie der Kodierung / Dekodierung von ADPCM habe ich mich nicht vertieft. Die Tabellenwerte des Arrays ima_step_table (von 89 Teilen) beschreiben jedoch anhand ihrer Reflexion im Diagramm (siehe Abbildung unten) die Wahrscheinlichkeitsverteilung der Stichproben relativ zur Nulllinie. In der Praxis ist dies normalerweise der Fall: Je nÀher die Probe an der Nulllinie liegt, desto hÀufiger tritt sie auf. Daher basiert ADPCM auf einem Wahrscheinlichkeitsmodell, und keinesfalls kann ein Quellensatz von 16-Bit-PCM-Abtastwerten korrekt in 4-Bit-ADPCM-Abtastwerte konvertiert werden. Im Allgemeinen ist ADPCM PCM mit einem variablen Quantisierungsschritt. Anscheinend spiegelt dieses Diagramm diesen sehr variablen Schritt wider. Er wird richtig ausgewÀhlt, basierend auf dem Gesetz der Verteilung von Audiodaten in der Praxis.



Fahren wir nun mit der Beschreibung der Struktur des AVI-Containers fort. TatsÀchlich ist es eine komplexe hierarchische Struktur.


Nachdem ich die Aufgabe fĂŒr einen speziellen Fall vereinfacht hatte, prĂ€sentierte ich die AVI-Struktur in linearer Form. Das Ergebnis ist folgendes: Die AVI-Datei besteht aus einem großen Header, Null-Sprung-Bytes (JUNK), einem Bereich von Audio- und Videostreams (mit ihren Headern und InhaltsgrĂ¶ĂŸen) und einer Liste von Indizes. Letzteres dient insbesondere dazu, im Player durch das Video zu scrollen. Ohne diese Liste funktioniert das Scrollen nicht (aktiviert). Es ist nur ein Inhaltsverzeichnis, in dem die SchlĂŒsselnamen der Stream-Blöcke (die mit den Namen in den Block-Headern ĂŒbereinstimmen), die entsprechenden GrĂ¶ĂŸen des Inhalts und die Werte der Offsets (Adressen) relativ zum Beginn des Stream-Bereichs aufgelistet sind.

Jetzt können Sie mit der Entwicklung des Programms fortfahren. Eine spezifische Beschreibung des Problems lautet wie folgt.

Im Stammverzeichnis von Abschnitt X befindet sich ein DVR-Verzeichnis. Dieses Verzeichnis enthĂ€lt viele nicht leere Unterverzeichnisse (und nur Unterverzeichnisse) mit Namen, die bestimmten Daten entsprechen. In jedem dieser Unterverzeichnisse befinden sich viele Dateien mit unterschiedlichen Namen und der Erweiterung "264". Erforderlich in Abschnitt Y: Erstellen Sie das Verzeichnis „DVR“ und darin dieselben Unterverzeichnisse wie in Abschnitt X :. FĂŒllen Sie jedes dieser Unterverzeichnisse mit Dateien mit denselben entsprechenden Namen, jedoch mit den Erweiterungen nicht "264", sondern "avi". Diese AVI-Dateien mĂŒssen aus den ursprĂŒnglichen 264-Dateien erhalten werden, indem sie verarbeitet werden, wodurch auf die eine oder andere Weise der Algorithmus eines vorhandenen Programms wiederholt wird. Die Verarbeitung besteht darin, Videostreams direkt neu zu verpacken, Audio-Streams neu zu dekodieren und die AVI-Datei zu formatieren. Das Programm sollte ĂŒber die Befehlszeile wie folgt gestartet werden: "264toavi.exe X: Y:", wobei "264toavi.exe" der Name des Programms ist, "X:" der Quellabschnitt ist, "Y:" der Zielabschnitt ist.

Um die Aufgabe zu vereinfachen, war es tatsÀchlich möglich, ein Programm zu schreiben, das nur die Konvertierung (das Umpacken) einer Datei in zwei Tagen erledigt: den Namen der Eingabedatei und den Namen der Ausgabedatei. Um nur das Umpacken von Gruppen zu implementieren, können Sie eine Befehls-Batch-Datei (bat) mit anderen Tools, z. B. Excel, schreiben. Aber ich habe ein komplettes Programm implementiert, sehr umstÀndlich. Es ist unwahrscheinlich, dass der Quellcode die Aufmerksamkeit der Leser verdient. Ich werde die Struktur des Programmcodes beschreiben.

Das Programm ist in C in der Dev-C ++ - Entwicklungsumgebung mit WinAPI-Elementen geschrieben. Das Programm implementiert drei große Hilfsfunktionen: die Funktion zum Erzeugen des anfĂ€nglichen AVI-Headers, die Funktion zum Decodieren eines Audio-Samples und die Funktion zum Scannen der Quelldatei „264“ nach Wörtern. In Worten nenne ich einen Teil von 4 Bytes. Es wurde beobachtet, dass die GrĂ¶ĂŸe der Header und der Inhalt aller Streams ein Vielfaches von vier Bytes sind. Die Scanfunktion kann fĂŒnf Werte zurĂŒckgeben: 0 - wenn es sich um die ĂŒblichen 4 Bytes des Videostreams zum erneuten Packen handelt, 1 - wenn es sich um den Header des Blocks des Videostreams des Referenzrahmens handelt, 2 - wenn es sich um den Header des Blocks des Videostreams des komprimierten Frames handelt, 3 - wenn es sich um den Header des Audiostreamblocks handelt, 4 - wenn dies der Fall ist "BeschĂ€digter" Block, der beim Umpacken ignoriert wird. Sehr, sehr selten, aber es ist passiert. Der beschĂ€digte Block (wie ich ihn nannte) ist ein Header wie "\ 0 \ 0 \ 0 \ 0H264", wobei "\ 0" das Nullbyte ist. Der regulĂ€re Repacker ignoriert solche Blöcke. NatĂŒrlich kann sich herausstellen, dass der Inhalt eines solchen Blocks ziemlich gut funktioniert, aber ich ignoriere solche Blöcke, um mein Programm nĂ€her an den Standard zu bringen.

In der Hauptfunktion wird neben der Organisation von Verzeichnissen die Eingabedatei von der Scanfunktion gelesen. AbhĂ€ngig davon, was diese Funktion zurĂŒckgegeben hat, werden weitere Aktionen ausgefĂŒhrt. Wenn dies die Header der Videostreams sind, werden die entsprechenden Header in der Ausgabe-AVI-Datei gebildet. Dort werden sie unterschiedlich genannt: "00db" ist der Titel des Blocks des Videostreams des Referenzrahmens und "00dc" ist fĂŒr den komprimierten Rahmen. Nach dem Umpacken (Umschreiben von Wörtern) vor dem neu aufgetretenen Header wird die GrĂ¶ĂŸe des neu gepackten Inhalts berechnet und dieser Wert in das Feld geschrieben, das unmittelbar auf den Header des gerade verarbeiteten Streams folgt. Wenn beim Scannen ein Audiostream-Header auftritt, wird der Headername „03wb“ in der Ausgabe-AVI-Datei generiert und der Audiostream wird in der Schleife von ADPCM zu PCM decodiert, wĂ€hrend der decodierte Inhalt in die AVI-Datei geschrieben wird. Zusammen mit all dem wird eine kurze Information (Inhaltsverzeichnis) in einer temporĂ€ren Indexdatei „Index“ aufgezeichnet. Sie konnten keine Scanfunktion ausfĂŒhren, sondern alles in die Hauptfunktion schreiben. Aber dann wĂ€re das Programm sehr umstĂ€ndlich und fast schwer zu lesen.

Am Ende des gesamten Vorgangs, wenn die Eingabedatei „264“ beendet ist, bevor zu einer neuen Datei gewechselt wird, schließt das Programm alle VorgĂ€nge kompetent ab. Zuerst werden bestimmte Felder im Header der AVI-Datei angepasst, deren Werte von der GrĂ¶ĂŸe und Anzahl der Lesestreams abhĂ€ngen. Anschließend wird der Inhalt der temporĂ€ren Indexdatei an die fast fertige AVI-Datei angehĂ€ngt, die dann gelöscht wird. Nach diesen VorgĂ€ngen ist die Ausgabe-AVI-Datei zur Wiedergabe bereit.

WĂ€hrend das Programm ausgefĂŒhrt wird, findet in der Befehlszeile eine Textvisualisierung statt, in der das aktuelle Verzeichnis, die Datei sowie die Blocknummer des Videostreams pro Referenzrahmen und der entsprechende Zeitpunkt des Videos in Minuten und Sekunden angezeigt werden. Und wenn die Eingabedatei keinen beliebigen Namen hat, sondern den ursprĂŒnglichen (der die Kanalnummer, das Datum und die Uhrzeit des Beginns der Aufnahme enthĂ€lt), erfolgt eine interaktivere Visualisierung auf der Grundlage der Datums- / Zeitarithmetik.

Beim Testen und Debuggen des Programms gab es die Hauptprobleme, die ich bei der Arbeit mit der Sounddecodierung hatte. Einfache Arithmetik funktionierte nicht richtig, wenn ich beim Deklarieren von Variablen in der Dekodierungsfunktion die Typen nicht richtig eingeben wĂŒrde. Aus diesem Grund wurden einige Blöcke von Audiostreams unterbrochen und es gab Klicks nach Gehör. Einige unverstĂ€ndliche Headerfelder der ursprĂŒnglichen 264-Datei, die ich nicht herausfinden konnte, erwiesen sich als unempfindlich gegenĂŒber dem Ergebnis. Im Gegensatz zu einem normalen Programm wirft mein Programm nicht den letzten unvollstĂ€ndigen Flussblock aus dem Umpackvorgang. Obwohl seine Abwesenheit keine praktische Rolle spielen wird. Ein anderes regulĂ€res Programm hinterlĂ€sst im Gegensatz zu meinem eine kleine Menge „MĂŒll“ (dies ist der Inhalt des letzten Streams) ganz am Ende der AVI-Datei nach den Indizes. Trotzdem wird das Video fast gleich abgespielt. Und das Programm fĂŒhrt das Umpacken fĂŒr den gleichen Zeitraum wie das regulĂ€re Programm durch.

Abschließend werde ich Abbildungen geben, die die Struktur der Organisation von Flows in der .264-Datei (im WinHex-Hex-Editor) am Beispiel einer der Dateien und das Erscheinungsbild des RiffPad-Programms mit der darin gepackten neu gepackten AVI-Datei veranschaulichen. Dieses Programm hat das Studium der Struktur einer AVI-Datei erheblich vereinfacht. Es zeigt deutlich die hierarchische Struktur, zeigt den Byte-Inhalt jedes Mitglieds der Struktur und interpretiert den Inhalt der Header sogar geschickt in Form einer Liste von Parametern. Insbesondere das Bild zeigt, dass der Inhalt des Videostreams unverĂ€ndert ĂŒberschrieben wird.



Source: https://habr.com/ru/post/de422163/


All Articles