Medienverarbeitung mit Java in elementaren

Werbung
Medienverarbeitung mit Java
in elementaren Einheiten
Studienarbeit
Name: Verena Henrich
Dieburger Weg 9
64390 Erzhausen
Studiengang: Informationstechnik
Kurs: TIT03ANS
Semester: WS 05 / SS 06
Betreuer: Patrick Wolf
Firma: Fraunhofer IPSI
Dolivostraße 15
64293 Darmstadt
Universität: Berufsakademie Mannheim
Coblitzweg 7
68163 Mannheim
Abgabedatum: 1. Juni 2006
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Kurzfassung
Eine einfache Möglichkeit kontinuierliche, digitale Medien (Audio, Video, etc.) aufzufassen, ist sie als Folge von elementaren, semantischen Einheiten zu verstehen.
Solch eine Einheit stellt einen grundlegenden Bestandteil eines Mediums mit semantischer Bedeutung dar. Beispielsweise besteht ein Video aus einer Folge einzelner
Bilder (Frames), die jeweils eine elementare, semantische Einheit repräsentieren.
Eine solche Interpretation ermöglicht die Verarbeitung digitaler Medien auf einer höheren Abstraktionsebene als die herkömmliche Interpretation digitaler Medien als
Byteströme.
In Java steht für die Verarbeitung digitaler Medien das Java Media Framework (JMF)
zur Verfügung. Darin kommunizieren die einzelnen Glieder der digitalen Verarbeitungskette über einfache Byte-Array-Ströme miteinander. Das JMF erlaubt auch eigene Glieder (Plug-Ins) zu entwickeln und dieser Verarbeitungskette hinzuzufügen.
Ein Plug-In besteht aus einer oder mehreren Klassen und ist unabhängig vom eigentlichen Programm. Es kann dynamisch in ein Programm eingebunden und an
einer bestimmten Stelle im Programmfluss verwendet werden.
In dieser Arbeit wird vorgestellt, wie der Plug-In-Mechanismus des JMF genutzt werden kann, um das Verarbeiten digitaler Medien in elementaren, semantischen Einheiten zu ermöglichen. Es wird dabei ein DivideIntoUnits-Plug-In entwickelt, das
Videos des MPEG-1-Standards in solche Einheiten zerlegen kann. Als mögliche,
darauf aufsetzende Anwendung wird eine Watermarker-Klasse umgesetzt, mit der
einzelne Frames mit digitalen Wasserzeichen markiert werden können. Dafür wird
ein Konzept entwickelt, bei dem die elementaren, semantischen Einheiten durch
individuelle Frame-Klassen repräsentiert werden und so die beispielhaft aufsetzende
Anwendung des Verfahrens digitaler Wasserzeichen ermöglicht wird.
Ehrenwörtliche Erklärung
Ich versichere hiermit, dass ich die vorliegende Arbeit mit dem Titel
Medienverarbeitung mit Java in elementaren Einheiten
selbständig verfasst und keine anderen als die angegebenen Quellen und Hilfsmittel
verwendet habe.
Ort, Datum
Unterschrift
ii
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Inhaltsverzeichnis
Kurzfassung................................................................................................................. ii
Ehrenwörtliche Erklärung............................................................................................. ii
Inhaltsverzeichnis ....................................................................................................... iii
Abbildungsverzeichnis ................................................................................................ iv
1
Einleitung............................................................................................................. 1
1.1
Begriffsbildung: Elementare Einheiten ......................................................... 2
2
MPEG.................................................................................................................. 3
2.1
Notwendigkeit der Komprimierung ............................................................... 3
2.2
Grundlagen .................................................................................................. 3
2.3
Aufbau.......................................................................................................... 5
2.4
Elementare Einheiten in MPEG.................................................................... 7
3
Java Media Framework (JMF)............................................................................. 9
3.1
Grundlagen .................................................................................................. 9
3.2
Medienverarbeitung im JMF....................................................................... 10
3.3
Plug-Ins im JMF ......................................................................................... 11
4
Umsetzung des Projektes.................................................................................. 13
4.1
DivideIntoUnits-Plug-In............................................................................... 13
4.1.1
MPEG-Verarbeitung im JMF ............................................................... 13
4.1.2
Abstraktionsebene elementare Einheiten............................................ 15
4.1.3
Problem von binärer und hexadezimaler Schreibweise in Java .......... 16
4.2
Weiterverarbeitung der elementaren Einheiten .......................................... 17
4.2.1
Digitale Wasserzeichen....................................................................... 18
4.2.1.1
Grundlagen .................................................................................. 18
4.2.1.2
Eigenschaften .............................................................................. 18
4.2.1.3
Anwendungsgebiete .................................................................... 19
4.2.1.4
LSB-Wasserzeichen .................................................................... 20
5
4.2.2
4.2.3
Konzept der detaillierten Frame-Analyse ............................................ 21
LSB-Wasserzeichen in MPEG ............................................................ 22
4.2.4
Watermarker Klasse............................................................................ 25
Zusammenfassung............................................................................................ 26
Anhang – Codebeispiel ...............................................................................................v
Quellen ...................................................................................................................... vii
iii
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Abbildungsverzeichnis
Abbildung 1: Zwei aufeinander folgende Frames ....................................................... 4
Abbildung 2: I-, P- und B-Frames [M03] ..................................................................... 4
Abbildung 3: Makroblock ............................................................................................ 6
Abbildung 4: Aufbau einer Video Sequenz [L] ............................................................ 6
Abbildung 5: MPEG-Video-Strom-Schichten .............................................................. 7
Abbildung 6: Klassendiagramm zur Medienhandhabung [SM01] ............................. 10
Abbildung 7: Plus-Ins eines Processors [SM99] ....................................................... 11
Abbildung 8: Controls Klassendiagramm [SM01] ..................................................... 12
Abbildung 9: Diskrete Kosinus-Transformation [I93], [O04] ...................................... 23
iv
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
1 Einleitung
Digitale Medien lassen sich grob in zwei Kategorien einteilen: in zeitunabhängige und
in zeitabhängige. Zeitunabhängige Medien, beispielsweise Bilder, können als eine
einzige elementare, semantische Einheit betrachtet werden, die konstant unverändert bleibt. Anders ist dies bei zeitabhängigen Medien wie Audio und Video. Diese
bestehen aus einer Folge von Teileinheiten, die sich mit der Zeit verändern – sie
bestehen aus mehreren semantischen Einheiten, die es zu erfassen gilt. In dieser
Arbeit werden nur zeitabhängige Medien behandelt, bei denen elementare, semantische Einheiten separiert betrachtet werden.
Es stellt sich die Frage, wie solch eine elementare, semantische Einheit aussieht und
wie sie aufgebaut ist. Eine solche Einheit in einem Medium ist ein kleiner wohl definierter Teil – bei einem Video beispielsweise ein Frame. Zur genauen Begriffsklärung
dient der nächste Abschnitt 1.1, in dem eine elementare, semantische Einheit definiert und abgegrenzt wird.
In dieser Arbeit wird am Beispiel eines Videos im MPEG-Format der Bytestrom
analysiert und in elementare, semantische Einheiten unterteilt. Andere Medienformate werden nicht betrachtet. Eine elementare, semantische Einheit in einem
MPEG-Video ist ein Teil des Bytestroms und muss anhand von eindeutigen
Erkennungsmerkmalen aus dem gesamten Medienstrom herausgesucht werden. Auf
den Aufbau von MPEG und die darin enthaltenen elementaren Einheiten wird in
Kapitel 2 eingegangen.
Als nächste Grundlage wird in Kapitel 3 das Java Media Framework (JMF) vorgestellt. Dieses erlaubt die generische Handhabung digitaler Medien mit Java. Es werden bereits Standardimplementierungen zur Verfügung gestellt, die eine Erweiterung
durch selbst programmierte Schritte in Form von Plug-Ins ermöglichen.
Im Java Media Framework sollen MPEG-Videos, die in diesem Framework byteweise
eingelesen und verarbeitet werden, in elementare, semantische Einheiten geteilt
werden. Liegen diese Einheiten separiert vor, so wird die individuelle Bearbeitung
des Videos vereinfacht, indem die Bearbeitung auf einer höheren Abstraktionsebene,
nämlich in semantischen Einheiten, ermöglicht wird, ohne dabei auf der BytestromEbene arbeiten zu müssen.
Kapitel 4 beschreibt die Umsetzung des Projektes im JMF, wie dort mit Hilfe des
DivideIntoUnits-Plug-Ins das Medium in elementare, semantische Einheiten geteilt
und eine separate Weiterverarbeitung der Einheiten ermöglicht wird. Außerdem
erfolgt eine Einführung in das Verfahren digitaler Wasserzeichen. Dieses Verfahren
stellt eine mögliche Weiterverarbeitung der semantischen Einheiten dar – sie werden
mit Hilfe der Watermarker-Klasse mit digitalen Wasserzeichen markiert.
1
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
1.1 Begriffsbildung: Elementare Einheiten
Als erstes wird die Frage nach den elementaren, semantischen Einheiten in einem
Medium geklärt. Zur Begriffserklärung und als Denkanstoß zunächst die Wortklärungen von elementar und semantisch: Elementar bedeutet grundlegend
notwendig und wesentlich; semantisch hingegen bezieht sich auf die Bedeutung von
Zeichen bzw. die Bedeutung von Daten oder Informationen.
Eine elementare, semantische Einheit ist für Medien nicht spezifiziert. Da ein zeitabhängiges Medium oft aus einem Video- sowie einem Audio-Teil besteht, kann beispielsweise ein Video-Teil als eine elementare, semantische Einheit betrachtet werden (in Abgrenzung zum Audio-Teil). Als Alternative dazu könnte auch die vermutlich
kleinste visuelle Einheit, ein Bildpunkt eines Frames des Video-Teils, als elementare,
semantische Einheit in Betracht gezogen werden. In der Umsetzung des Projekts
wird nur mit dem Video-Teil gearbeitet, daher muss der Audio-Teil nicht näher
betrachtet werden. Zur Bearbeitung und logischen Verwendung der elementaren,
semantischen Einheiten ist es am sinnvollsten, einen Frame des Video-Teils als
elementare, semantische Einheit zu betrachten. Ein Vorteil dieser Betrachtung ist,
dass ein Video komplett in Einheiten aufgeteilt wird, also eine vollständige Komposition ergibt. Außerdem grenzt sich ein Frame zu anderen Frames ab und besitzt die
Semantik eines Bildes – er stellt also eine semantische Einheit dar. Elementar ist ein
Frame ebenfalls, denn ohne Frames als wesentliche Bestandteile wäre ein Video
kein zeitabhängiges, visuelles Medium.
Ein Video-Strom besteht aus einer Folge von Frames, die wiederum aus Bytes bestehen. Das Problem, das es zu lösen gilt, beruht auf der Interpretation dieser Bytes.
Ein kompletter Video-Strom wird durch einen Bytestrom repräsentiert. In diesem
Bytestrom sind die einzelnen Frames nicht ohne weiteres Wissen zu finden. Abschnitt 2.4 zeigt am Beispiel von MPEG, wie die Frames in einem Bytestrom gefunden werden können.
2
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
2 MPEG
In diesem Projekt werden nur die zeitabhängigen, visuellen Medien, also Videos,
betrachtet. Am Beispiel von MPEG-1 [I93] soll gezeigt werden, wie der Aufbau eines
Videos aussehen und wie der vorhandene Bytestrom interpretiert werden kann. Der
Video-Strom stellt eine Folge aneinander gereihter Frames dar, die wiederum aus
Bytes bestehen. Eine höhere Abstraktionsebene interpretiert die Bytes als zusammengehörige elementare, semantische Einheiten. Die Einheiten sollen in vorliegendem Kapitel gesucht und der Aufbau eines MPEG-Videos veranschaulicht dargestellt
werden, um dann eine weitere Bearbeitung der Einheiten verstehen und vornehmen
zu können. Dieses Kapitel gibt zunächst einen Überblick von MPEG und dann im
Detail dessen Aufbau im Hinblick auf die elementaren, semantischen Einheiten.
2.1 Notwendigkeit der Komprimierung
Unkomprimierte Videos weisen sehr hohe Bitraten auf – beim Format des digitalen
Fernsehens beispielsweise liegen sie in unkomprimierter Form zwischen 290 und
370 MBit/s [H95]. Effizienzprobleme, bei denen technische Geräte mit zu großen
Datenraten überfordert sind, treten meist nicht bei der Wiedergabe (Dekodierung),
sondern bei der Übertragung von Videos auf. Die Datenrate (Übertragungsrate)
beschreibt eine Menge von Daten, die in einer bestimmten Zeit übertragen werden.
Notwendige Übertragungsraten können nur durch Komprimierung erreicht werden.
Dabei werden die Datenraten reduziert. Eine Komprimierung ist notwendig; sie kann
jedoch andere Probleme mit sich ziehen, wie beispielsweise einen meist bei starker
Komprimierung auftretenden Qualitätsverlust. Es muss also ein Verfahren verwendet
werden, das ein geeignetes Mittel zwischen zu starken Qualitätsverlusten und einer
erwünschten oder vorgegebenen Kompressionsrate findet und so ein qualitativ gutes
Video mit vorgegebener Kompressionsrate erstellt. Dabei beschreibt die Kompressionsrate, wie stark Daten komprimiert werden. Hier setzt die Moving Pictures
Expert Group an [H95]. Diese hat Standards entwickelt, u. a. MPEG-1, bei dem eine
Bitrate (Datenrate) von bis zu 1,5 MBit/s [I93], und MPEG-2, bei dem eine Bitrate von
4 bis 80 MBit/s [M96], erreicht wird.
2.2 Grundlagen
Ein MPEG-Video [M95] besteht nicht aus einzelnen, aufeinander folgenden Bildern –
dies wäre zu ineffizient im Hinblick auf die Kompressionsrate. Die Idee von MPEG
besteht darin, redundante und überflüssige Informationen wegfallen zu lassen. So
wird zum Beispiel bei zwei aufeinander folgenden Frames der erste Frame vollständig komprimiert gespeichert und von dem zweiten wird nur die Differenz zum ersten
gespeichert. Diese Vorgehensweise ist möglich, weil es Informationen gibt, die
annähernd gleich bleiben. In Abbildung 1 bleibt der Hintergrund gleich, nur das Fahrzeug bewegt sich.
3
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Abbildung 1: Zwei aufeinander folgende Frames
In regelmäßigen Abständen, meist alle 12 bis 15 Frames, wird ein vollständiger, kodierter Frame, ein so genannter I-Frame (Intra-Coded-Frame), gespeichert. Dieser ist
JPEG-komprimiert und stellt ein Referenzframe dar. Ein Referenzframe dient als
Bezugspunkt für andere Frames und stellt seine Informationen anderen Frames zur
Verfügung. Zwischen den vollständigen intra-kodierten Frames befinden sich interkodierte Differenzframes. Diese besitzen nicht die komplette Bildinformation, die
notwendig ist, um den Frame wiederherstellen zu können, sondern beziehen sich auf
einen Referenzframe, speichern nötige Differenzinformationen und die Berechnungsmethode, wie sie aus vorangegangenen und gegebenenfalls auch nachfolgenden
Referenzframes wiederhergestellt (dekodiert) werden können. Sie weisen eine erheblich höhere Kompressionsrate als I-Frames auf ([S99], Kapitel 7.7.1).
Interframe-Kodierung klassifiziert zwei Frame-Typen: P-Frames (Predictive-CodedFrame) und B-Frames (Bidirectional-Predictive-Coded-Frame). P-Frames enthalten
Differenzinformationen zu ihrem vorhergegangenen Referenzframe und können
selbst wieder einen Referenzframe für andere Frames darstellen. B-Frames werden
ausgehend von einem vorhergehenden und einem nachfolgenden Referenzframe
berechnet. Diese Abhängigkeiten sind in Abbildung 2 dargestellt. Es ist ebenfalls der
unterschiedliche Informationsgehalt der einzelnen Frames zu erkennen: der I-Frame
ist ein vollständiges Bild, P- und B-Frames bestehen nur aus Teilinformationen.
Abbildung 2: I-, P- und B-Frames [M03]
4
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Zur Vollständigkeit wird noch der 4. Frame-Typ erwähnt, der D-Frame (DC-CodedFrame). Dieser ist intraframe-kodiert und beinhaltet nur ausgewählte Anteile eines
Frames, die einem schnellen Vorlauf des Videos dienen. D-Frames sind keine notwendigen Bestandteile des MPEG-Videos, ihre Funktion kann gegebenenfalls durch
I-Frames übernommen werden. Deshalb und weil sie keine Rolle bei der sequenziellen Betrachtung spielen, sind sie für diese Arbeit nicht von Interesse und werden
nicht weiter behandelt.
In P-Frames wird von einem sich bewegenden Frameteil der örtliche Unterschied
zum Referenzframe gespeichert. Abbildung 1 zeigt dafür ein Beispiel: Die beiden
Frames weisen einen örtlichen Unterschied zwischen dem Fahrzeug auf. Der rechte
Frame zeigt einen Vektor, der die Bewegungsrichtung und -länge wiedergibt. Der PFrame würde also diesen Vektor, den Frameteil der sich bewegt (in diesem Beispiel
das Fahrzeug) und, falls erforderlich, eine Veränderung des Fahrzeugs speichern.
Dieses Verfahren, bei dem ein Bewegungsvektor gespeichert wird, nennt man auch
Bewegungskompensation (engl.: motion compensation) und wird mit Hilfe von
Makroblöcken umgesetzt, die im nächsten Absatz erklärt sind.
2.3 Aufbau
Ein Video als zeitabhängiges Medium wird auch als System-Strom (system-stream)
bezeichnet und setzt sich aus Elementar-Strömen (elementary-stream oder auch
Track) zusammen. Elementar-Ströme können beispielsweise Audio- oder VideoStröme sein. Da andere Ströme hier nicht von Interesse sind, wird nur der reine
Video-Strom des gesamten MPEG-System-Stroms betrachtet. Dieser besteht aus
einzelnen Abschnitten, die als Sequenzen bezeichnet werden und in verschiedene
Ebenen (Schichten) unterteilt sind. Eine Sequenz besteht aus Folgen von Frames, I-,
P- und B-Frames, die jeweils zu Gruppen zusammengefasst sind, den Groups-OfPictures (GOP). Eine GOP besteht immer mindestens aus einem I-Frame. Eine typische GOP, die sich häufig als praktisch erwiesen hat, besteht aus folgender Framereihenfolge: I B B P B B P B B P B B P.
Die einzelnen Frames eines MPEG-Videos bestehen aus Slices, in deren Header
(Kopf mit Information) Informationen über ihre eigene räumliche Positionierung im
Frame gespeichert sind. Slices bestehen wiederum aus untergeordneten Einheiten,
den Makroblöcken. Ein Slice fasst nebeneinander liegende Makroblöcke zusammen.
Die Anzahl der Makroblöcke in einem Slice ist im Slice-Header gespeichert. Da die
Anzahl nicht vorgegeben ist und variieren kann, kann die Länge der Slices unterschiedlich sein. Es gibt in einem Slice mindestens einen Makroblock. Alle Slices
eines Frames füllen insgesamt einen ganzen Frame aus.
Ein Makroblock wird zur Speicherung der Bewegungsvektoren verwendet und besteht aus 6 Blöcken: 4 Luminanz- und 2 Chrominanzblöcke, mit je 8x8 Werten. Jeder
der Luminanzblöcke Y0 – Y3 speichert von 8x8 Bildpunkten (Pixel) 8x8 Luminanzwerte (Helligkeit, Leuchtdichte, Lichtstärke), sie ergeben zusammen eine 16x165
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Anordnung. In Abbildung 3 sind sie in schwarz dargestellt, wobei hier nur in Y0 für
jeden Bildpunkt ein Kästchen gezeichnet ist. Die Luminanzblöcke bilden 16x16 Werte
mit einem Wert für jeden Bildpunkt. Die Chrominanzblöcke Cb und Cr, enthalten je
einen Chrominanzwert (Farbe) für 4 Bildpunkte. Ein Chrominanzblock deckt mit 8x8
Chrominanzwerten 16x16 Bildpunkte ab. Beide Chrominanzblöcke liegen jeweils
räumlich deckend mit den 4 Luminanzblöcken. In Abbildung 3 stellen die 2 Chrominanzblöcke jeweils eine in blau-rot angedeutete Anordnung dar – sie bilden jeweils
8x8 Werte mit einem Wert für 4 Bildpunkte.
Abbildung 3: Makroblock
Nicht jeder Makroblock beinhaltet 6 vollständige Blöcke, sondern es ist abhängig
vom Frame-Typ, wie viel Information der jeweilige Makroblock beinhaltet. In I-Frames
besitzt ein Makroblock meist 6 Blöcke, da diese Frames vollständige Bilder darstellen. [I93]
Die Blöcke stellen die kleinste Einheit im MPEG-Standard dar, die für den Bewegungsalgorithmus relevant ist. Sie dienen als Eingabe für die diskrete KosinusTransformation (DCT). Bei der Bildkomprimierung werden Blöcke aus 8x8 BildpunktWerten in 8x8 DCT-Koeffizienten transformiert. Abschnitt 4.2.3 geht darauf genauer
ein.
Abbildung 4 zeigt die beschriebene Zusammensetzung eines MPEG-Videos:
Abbildung 4: Aufbau einer Video Sequenz [L]
6
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
MPEG-Video kann als Schichtenmodell betrachtet werden, welches Abstraktionen
zulässt. Es ergibt sich ein Schichtenmodell wie in Abbildung 5, bei dem jede Schicht
einen Header enthält, in dem sich beispielsweise weitere Informationen zur Schicht
mit spezifischen Parametern befinden. Die einzelnen Video-Strom-Schichten mit
ihren Headern und zusätzlichen, hier nicht aufgeführten Ergänzungen, ergeben
zusammen einen kodierten MPEG-Video-Strom [P06].
Abbildung 5: MPEG-Video-Strom-Schichten
2.4 Elementare Einheiten in MPEG
Wie in Abschnitt 1.1 bereits angesprochen, ist es zur Bearbeitung und logischen Verwendung der Einheiten am sinnvollsten, einen Frame als elementare, semantische
Einheit zu betrachten. In MPEG gibt es jedoch verschiedene Frame-Typen: I-, P- und
B-Frames. D-Frames werden von vorne herein außen vor gelassen.
Ein I-Frame kann separiert betrachtet werden und unabhängig davon, ob das Video
kodiert oder dekodiert vorliegt, sogar dann angezeigt werden, wenn sonst keine
Information vorhanden ist. Anders ist dies bei P- und B-Frames, bei denen in kodierter Form eine separierte Betrachtung und Bearbeitung schwer möglich ist, denn sie
benötigen zur Wiederherstellung (Dekodierung) Teile eines Referenzframes, welche
jedoch bereits einer anderen elementaren Einheit zugeteilt wären.
7
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Da in kodierter Form die separierte Betrachtung von P- und B-Frames als elementare, semantische Einheiten einen erheblichen Mehraufwand gegenüber der separierten Betrachtung von I-Frames erfordert, soll es für die Umsetzung des Projekts
genügen, lediglich alle I-Frames zu separieren und weiter zu verarbeiten.
Ein Frame muss aus dem gesamten Video-Bytestrom herausgesucht werden. Dafür
gibt es in einem MPEG-Video-Strom Erkennungsmerkmale in Form von Bytecodes.
Ein Beispiel eines solchen Bytecodes ist der Startcode, der eine 32 Bit (4 Byte) umfassende, genau definierte Folge von Bits umfasst. Ein Startcode beginnt immer mit
den gleichen drei Bytes, nämlich 0000 0000 0000 0000 0000 0001 (in binärer
Darstellung) bzw. 0x000001. Das vierte und letzte Byte des Startcodes gibt dessen
spezifischen Typ an. Das letzte Byte eines Frame-Startcodes ist 0000 0000 (binäre
Darstellung). Damit sieht der gesamte Startcode eines Frames wie folgt aus: 0000
0000 0000 0000 0000 0001 0000 0000 (in binärer Darstellung) bzw.
0x00000100.
Die Identifikation eines Frames im Hinblick auf dessen Typ, also ob es sich um einen
I-, P- oder B-Frames handelt, geschieht ebenfalls über genau spezifizierte Bytecodes
bzw. Bitcodes. Weiter gibt es eindeutig definierte Startcodes für Sequenzen, GroupsOf-Pictures und Slices. Außerdem gibt es einen Sequenz-Endcode und andere
Parameter-spezifische Byte- und Bitcodes, die beispielsweise für Header verwendet
werden. Alle Startcodes sind byte-aligned. Das bedeutet, dass sie in Bezug auf das
erste Bit des Bytestroms jeweils bei einem Vielfachen von 8 Bits beginnen. Außerdem müssen sie eindeutig zugeordnet werden können, um ihrer Aufgabe nachzukommen. Anderenfalls kann es zu Verwechslungen kommen, das MPEG-Video wäre
fehlerbehaftet und könnte nicht eindeutig und standardisiert dekodiert werden. Im
MPEG-1-Standard ISO/IEC 11172 [I93] sind unter anderem alle Byte- und Bitcodes
eines MPEG-1-Bytestroms definiert.
8
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
3 Java Media Framework (JMF)
Das Java Media Framework [SM05] erlaubt die generische Handhabung von
kontinuierlichen Medien mit Java. Es stellt bereits Standardimplementierungen für
Verarbeitungsschritte zur Verfügung und erlaubt gleichzeitig, eigene Erweiterungen
zu implementieren. So müssen Programmierer nicht ganze Verarbeitungsketten
selbst implementieren, sondern können sich auf wesentliche Aufgaben konzentrieren. Dieses Kapitel stellt das JMF vor und geht speziell auf die Medienverarbeitung
ein.
3.1 Grundlagen
Mit dem Java Media Framework [SM05] können zeitabhängige, digitale Medien
erfasst, abgespielt und bearbeitet werden. Die meisten gängigen Medienformate wie
AIFF, AU, AVI, GSM, MIDI, MPEG, Quicktime, RMF und WAV werden unterstützt
([SM99], Kapitel 2). Von den vielfältigen Anwendungen des JMF interessiert in dieser
Arbeit besonders das Bearbeiten von MPEG-Videos. Verschiedene Interfaces stellen
umfangreiche Funktionalitäten für die Medienbearbeitung zur Verfügung. Im Folgenden werden Java Interfaces und Klassen mit einer geänderten Schriftart hervorgehoben.
Eines der wichtigsten Interfaces des Java Media Frameworks ist Controller, das
die Hauptaktivitäten wie Abspielen und Bearbeiten von Medien unterstützt.
Controller realisiert eine Zeitbasis (Clock, Duration) und ein Ereignis-Verarbeitungsmodell (xListener). Die Zeitbasis wird durch die Interfaces Clock und
Duration realisiert; das Ereignis-Verarbeitungsmodell wird später genauer
beschrieben. Ein Beispiel für einen speziellen Controller ist Player (siehe
Abbildung 6), dessen Hauptaufgabe darin besteht, Tracks abzuspielen. Player
implementiert das Interface MediaHandler, durch das er Medien lesen und abspielen kann.
Eine weitere Möglichkeit, um Medien abzuspielen, ist durch das Interface
Processor gegeben, mit dessen Hilfe Tracks nicht nur abgespielt, sondern sogar
auch bearbeitet oder verändert werden können. Ein Track stellt einen ElemantarStrom, also beispielsweise ein Video-Strom des MPEG-System-Stroms dar. Die
meisten bisher genannten Interfaces sind im Klassendiagramm in Abbildung 6 zu
sehen.
9
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Abbildung 6: Klassendiagramm zur Medienhandhabung [SM01]
Zur Steuerung von Tracks, PlugIns und Controllern gibt es das Interface
Controls (siehe Abschnitt 3.3 bzw. Abbildung 8 auf Seite 12). Mit Controls können Objektattribute kontrolliert und eingestellt werden.
Controller, dessen Subinterfaces (Player und Processor) und die meisten
Subinterfaces von Controls (siehe Abbildung 8) bieten die Möglichkeit ein Interface
ControllerListenener bzw. allgemein xListener zu implementieren. Dadurch
können Statusänderungen verarbeitet werden, indem die implementierende Klasse
Events hervorruft (Ereignis-Verarbeitung). Diese Events werden ausgelöst, wenn ein
bestimmter Status erreicht wird (beispielsweise ein Zustand) oder ein Ereignis eintritt
(beispielsweise ein Zeitpunkt) und können für Status-, Ereignis- oder andere Bedingungsabfragen eingesetzt werden.
Da von einem Interface nicht direkt ein Objekt erzeugt werden kann, steht im JMF die
Klasse Manager zur Verfügung, mit deren Hilfe statisch Implementierungen von
Controller oder Controls erzeugt werden können ([ED04], Kapitel 4). Ein Beispiel hierzu folgt bei der Umsetzung des DivideIntoUnits-PlugIns in Abschnitt
4.1.1.
3.2 Medienverarbeitung im JMF
Für die Medienverarbeitung steht im Java Media Framework das Interface
Processor zu Verfügung. Dies ist ein spezieller Controller und enthält also eine
eigene Zeitbasis sowie ein Ereignis-Verarbeitungsmodell. Processor lässt sich als
Verarbeitungskette mit Eingabe, Verarbeitung und Ausgabe, dem typischen Aufbau
in der Computerverarbeitung, darstellen. Ein- und Ausgabe sind durch Datenquellen
(DataSource) gekennzeichnet. Eine DataSource (entspricht einem MPEGSystem-Strom) ist eine Klasse des JMF, die als Eingabe eines Controllers
10
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
(Processor oder Player) dienen oder ein Medium abspeichern kann. Im zweiten
Fall dient sie als Eingabe einer DataSink (Datensenke), die Mediendaten in Form
einer Datei persistent machen oder ausgeben kann.
Zwischen der Ein- und Ausgabe des Processors wird das Medium je nach Anwendung in individuellen Schritten nacheinander verarbeitet. Die einzelnen Schritte stellen meist PlugIns dar. PlugIn ist ein Subinterface von Controls (siehe nächster
Abschnitt, Abbildung 8). Abbildung 7 zeigt mögliche PlugIns von Processor, wie
(De-)Multiplexer, Codecs oder Effects ([ED04], Kapitel 4), die entweder mit
vorgefertigter Funktionalität aus dem JMF übernommen werden können oder als
implementierte Interfaces mit dem Superinterface PlugIn Funktionalitäten ersetzen
oder ergänzen können. Ihre Funktionsweise wird im folgenden Abschnitt beschrieben.
Abbildung 7: Plus-Ins eines Processors [SM99]
3.3 Plug-Ins im JMF
Die Aufgaben von PlugIns können sehr unterschiedlich sein, und somit auch ihr
Aussehen und ihre Verwendung. PlugIns sind Teilschritte der Verarbeitungskette
eines Processors, die in einer festgelegten Reihenfolge abgearbeitet werden
(siehe Abbildung 7). Sie bilden Bearbeitungsschritte, die entweder standardmäßig
oder individuell selbst programmiert verwendet werden können. Sofern keine
Standard-, sondern selbst programmierte Implementierungen verwendet werden,
muss Processor mitgeteilt werden, dass zusätzliche PlugIns verwendet werden
sollen. Dazu müssen die PlugIns im JMF registriert werden. Dies geschieht über
eine Manager-Klasse, PlugInManager, mit deren Hilfe statisch (und bei Bedarf
sogar permanent) PlugIns ergänzt werden können, die dann zur weiteren Verwendung zur Verfügung stehen [ED04].
Das Hinzufügen von PlugIns ermöglicht die Implementierung von zusätzlichen
Funktionalitäten. Bereits vorhandene PlugIns sind (De-)Multiplexer, Codec
oder Effect. Jedes dieser PlugIns stellt einen separaten Schritt dar und besitzt
eine Ein- und eine Ausgabe. Ein Demultiplexer bekommt einen Mediendatenstrom (im JMF DataSource, in MPEG der System-Strom) als Eingabe, analysiert
und zerlegt ihn, sofern er aus mehreren Elementar-Strömen besteht, also
gemultiplext (zusammengesetzt) vorliegt, in seine einzelnen Tracks. Andernfalls,
wenn der Mediendatenstrom nur aus einem Elementar-Strom besteht, wird dieser
(zunächst noch gemultiplext als DataSource vorliegend) in einen Track umgewandelt.
11
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Die Ausgabe des Demultiplexers von Tracks geschieht in Form von Buffern.
Solch ein Buffer stellt eine unstrukturierte Folge von bytes dar und dient dem
Transport von Mediendaten innerhalb von Player oder Processor. Die Aufgabe
eines Multiplexers hingegen ist genau das Gegenteil eines Demultiplexers.
Dieser führt die einzelnen Tracks bzw. Buffer (bei MPEG die Elementar-Ströme),
die er als Eingabe entgegennimmt, zusammen zu einem Datenstrom (im JMF DataSource; bei MPEG der System-Strom), den er als Ausgabe erzeugt.
Ein Codec kodiert bzw. dekodiert die zu verarbeitenden Videodaten eines Tracks.
Er bekommt einen einzelnen Track, bzw. Buffer als Eingabe und gibt auch einen
solchen aus. Eine spezielle Form des Codecs in der Sprache des JMF ist ein
Effect. Mit dessen Hilfe können Tracks mit gezielten Manipulationen verändert
werden. Abbildung 8 zeigt als Klassendiagramm den hierarchischen Zusammenhang
der zuvor genannten Controls.
Abbildung 8: Controls Klassendiagramm [SM01]
Die Lösung der vorgegebenen Aufgabe setzt bei den PlugIns an. Mit Hilfe eines
Codecs, dem DivideIntoUnits-PlugIn, kann ein Video-Strom analysiert und in
elementare, semantische Einheiten geteilt werden. Mit diesem Grundwissen über
das Java Media Framework und insbesondere von PlugIns kann auf die eigentliche
Aufgabe, die Medienverarbeitung mit Java in elementaren Einheiten eingegangen
werden. Wie zuvor erwähnt, wird als mögliche Weiterverarbeitung in das Verfahren
digitaler Wasserzeichen eingeführt. Das nächste Kapitel beschreibt zunächst die
Umsetzung des DivideIntoUnits-PlugIns, bei dem ein MPEG-Video analysiert
und in elementare Einheiten geteilt wird. Anschließend wird in das Verfahren digitaler
Wasserzeichen eingeführt und die Umsetzung der Watermarker-Klasse beschrieben, mit deren Hilfe die elementaren Einheiten mit digitalen Wasserzeichen markiert
werden können.
12
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
4 Umsetzung des Projektes
Die Hauptfunktionen des Projekts sind in einem PlugIn und einer Klasse gekapselt:
dem DivideIntoUnits-PlugIn und der Watermarker-Klasse. Ersteres ist dafür
zuständig, den gesamten MPEG-Bytestrom zu analysieren, die elementaren, semantischen Einheiten zu finden und deren separierte Weiterverarbeitung zu ermöglichen.
Watermarker stellt eine mögliche Weiterverarbeitung dar und markiert die elementaren, semantischen Einheiten mit digitalen Wasserzeichen.
Dieses Kapitel erklärt zuerst die Umsetzung des DivideIntoUnits-PlugIns, bei
dem die Konzentration auf der Zerlegung des MPEG-Bytestroms in elementare,
semantische Einheiten liegt. Als nächster Schritt wird in das Verfahren digitaler
Wasserzeichen eingeführt, um schließlich die Umsetzung der Watermarker-Klasse
zu verstehen. Insgesamt zeigt dieses Projekt eine Realisierung der Verarbeitung von
MPEG-Byteströmen auf Basis von elementaren, semantischen Einheiten im Java
Media Framework.
4.1 DivideIntoUnits-Plug-In
Das DivideIntoUnits-PlugIn soll den gesamten MPEG-Video-Strom analysieren und auf Bytestrom-Ebene die elementaren, semantischen Einheiten finden.
Diese Einheiten sind, wie in Abschnitt 1.1 erarbeitet, Frames und müssen in dem
Video-Bytestrom unter anderem mit Hilfe von Startcodes gefunden werden. Es wird
zuerst erklärt, wie im JMF die MPEG-Verarbeitung auf der Ebene des Bytestroms
funktioniert. Ziel ist es schließlich, nicht auf der Bytestrom-Ebene arbeiten zu
müssen, sondern eine Abstraktion der Verarbeitung auf elementaren, semantischen
Einheiten zu erreichen.
4.1.1 MPEG-Verarbeitung im JMF
Für die Medienverarbeitung im Java Media Framework wird das Interface
Processor benötigt (siehe Kapitel 3). Da von einem Interface nicht direkt ein Objekt
erzeugt werden kann, muss die Klasse Manager verwendet werden. Mit dem Aufruf
Manager.createProcessor(inputFile) kann statisch ein Objekt von
Processor erzeugt werden. Der Parameter inputFile kann entweder eine URL
(Pfadangabe eines Mediums), ein MediaLocator (gekapselte Pfadangabe zu
einem Medium) oder direkt eine DataSource (stellt ein Medium dar) sein. Die
Klasse Manager weiß durch diesen Parameter, wie sie den Dateninhalt findet und
auf welche Art und Weise sie eine Instanz von Processor erzeugen muss.
Processor ist ein Subinterface von Controller und besitzt somit ein EreignisVerarbeitungsmodell. Das Ereignis-Verarbeitungsmodell vergibt Processor einige
Status
und
erlaubt
deren
Abfrage.
Außerdem
kann
durch
processor.addControllerListener(controllerListener) das Interface
ControllerListener eingebunden werden. Dieses Interface stellt die Methode
13
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
controllerUpdate(controllerEvent) zur Verfügung, welche beim Auftreten
eines Ereignisses aufgerufen wird und Ereignisabfragen erlaubt. Mögliche Ereignisse
(Event bzw. ControllerEvent) können erreichte Zeitpunkte des Datenstroms
oder Status- bzw. Zustandsänderungen des Processors sein.
Hat man ein Objekt von Processor erzeugt, kann man einen eingehenden Bytestrom bearbeiten. Zunächst findet eine Abfrage der einzelnen Tracks im gesamten
MPEG-System-Strom statt. Der System-Strom setzt sich wie bereits erklärt aus ein
oder mehreren Tracks zusammen. Die Tracks eines Processor bzw. SystemStroms können mit Hilfe des Interfaces TrackControl (ebenfalls ein Subinterface
von Controls) kontrolliert und verändert werden. Die TrackControls, die jeweils
einen Track repräsentieren, können durch processor.getTrackControls()
abgefragt werden. In dieser Arbeit sind nur Video-Tracks von Interesse. Die Abfrage
von processor.getTrackControls() gibt ein Array von TrackControls zurück. Aus diesem Array kann man den Video-Track bzw. den zuständigen TrackControl für den Video-Track heraussuchen, indem man das Format der einzelnen
Tracks, das man durch TrackControl.getFormat() erhält, mit der Klasse
VideoFormat vergleicht. Stimmt das Format des Tracks mit VideoFormat überein, handelt es sich um einen Video-Track.
Die gesamte Verarbeitungskette des Processors teilt sich nach dem
Demultiplexer in einzelne Verarbeitungsketten für jeden Track. Die Tracks
werden später wieder mit einem Multiplexer zu einem System-Strom
(DataSource) zusammengeführt. Zwischen Demultiplexer und Multiplexer
können jedem Track individuell zusätzliche PlugIns als Verarbeitungsschritte
hinzugefügt werden. In diesem Fall wird ein Array aus PlugIns oder noch
spezieller ein Array aus Codecs angelegt. Da das DivideIntoUnits-PlugIn
ein Codec ist, also ein spezielles PlugIn, kann es diesem Array hinzugefügt
werden. Das Array beinhaltet alle zusätzlichen Schritte (PlugIns) und wird mit
videoTrack.setCodecChain(codecsArray) dem jeweiligen Track, hier dem
zuvor gesuchten Video-Track, hinzugefügt.
Die bisher in diesem Abschnitt beschriebenen Funktionalitäten sind im Anhang in
einem Codebeispiel zusammengeschrieben. Das Beispiel ist verkürzt und stellt nur
die hier relevanten Zeilen dar.
Die Hauptaufgaben des DivideIntoUnits-Codecs sind das Analysieren des
Video-Tracks und das Suchen der I-Frames als elementare, semantische Einheiten,
um schließlich deren separate Weiterverarbeitung zu ermöglichen.
Ein Codec besitzt die Methode process(inputBuffer,outputBuffer). Hier
stellt inputBuffer den eingehenden Buffer dar. Die darin enthaltenen Daten
können mit inputBuffer.getData() ausgelesen werden. Diese Methode gibt die
Daten als byte-Array zurück. Dieser Array kann analysiert, nach Startcodes
durchsucht und gegebenenfalls verändert werden. Die Bearbeitung ist im nächsten
Abschnitt erklärt. Schließlich werden die individuell bearbeiteten Daten mit
14
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
outputBuffer.setData(byteArray) an outputBuffer weitergegeben. Dieser
Buffer stellt die Ausgabe des Codecs dar und dient gleichzeitig als Eingabe des
nächsten PlugIns bzw. Verarbeitungsschrittes. Der folgende Codeausschnitt
verdeutlicht die Funktionsweise eines Codecs. Es sind nur hier relevante Zeilen
angegeben.
import javax.media.*;
public class DivideIntoUnits implements Codec {
Object bufferPartData;
byte[] byteData;
byte[] outputBufferByte;
/**
* processor calls this method, inputBuffer is given,
* outputBuffer need to be set
*/
public int process(Buffer inputBuffer, Buffer outputBuffer) {
//each buffer is passed to accessFrame for further process
accessFrame(inputBuffer);
...
//set outputBuffer
outputBuffer.setData(outputBufferByte);
return BUFFER_PROCESSED_OK;
}
/**
* analyse buffer and separate into units
*/
void accessFrame(Buffer bufferPart) {
bufferPartData = bufferPart.getData();
byteData = (byte[]) bufferPartData;
//set content of outputBuffer
outputBufferByte = ...;
//separation of units (is not specified in this example)
...
}
...
}
4.1.2 Abstraktionsebene elementare Einheiten
Die elementaren, semantischen Einheiten sind, wie in Abschnitt 2.4 erarbeitet, IFrames und besitzen die Semantik eines Bildes. Um diese Einheiten separieren zu
können, muss der eingehende Buffer analysiert und nach Startcodes durchsucht
werden. Die Daten des Buffers können als byte-Array ausgelesen und dann
byteweise verglichen werden. Da Startcodes byte-aligned sind, was bedeutet, dass
sie in Bezug auf das erste Bit des Bytestroms jeweils bei einem Vielfachen von 8 Bits
beginnen, reicht es aus, bei jedem neuen Byte nach dem Anfang eines Startcodes zu
suchen und nicht auf die Ebene einzelner Bits herunter gehen zu müssen.
Um einen Frame zu finden, muss man wissen, wie er charakterisiert ist. Wie in Abschnitt 2.4 beschrieben, sieht sein Startcode folgendermaßen aus: 0000 0000 0000
0000 0000 0001 0000 0000 (in binärer Darstellung) oder 0x00000100. Bei diesem
Projekt sollen zunächst nur I-Frames gesucht werden. Dabei spielt die 3-Bit-große
Frame-Typangabe eine Rolle, die in den auf einen Frame-Startcode folgenden Bytes
15
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
zu finden ist. Die I-Frame-Typangabe ist durch 001 (binäre Darstellung) charakterisiert. Die gesamte Suchabfrage für einen I-Frame ergibt sich also zu folgendem:
0000 0000 0000 0000 0000 0001 0000 0000 **** **** **00 1***
Startcode eines Frames
Frame-Typangabe
Hierbei stellen die * Platzhalter dar, die nicht zum Spezifizieren eines Frames benötigt werden, sondern andere Parameter beinhalten. Ein Frame beginnt mit solch
einem Startcode und reicht bis zum Anfang des nächsten Frame-, GOP- oder Sequenz-Startcodes. Innerhalb eines Frames können Startcodes für Slices vorkommen.
Hat man die Frames aus dem gesamten MPEG-Video-Bytestrom herausgesucht, so
können diese gegebenenfalls weiter verarbeitet und verändert werden. Abschnitt 4.2
gibt ein Beispiel für eine mögliche Weiterverarbeitung.
Die Bytecodes sind in dieser Arbeit wie im MPEG-1-Standard [I93] in binärer oder
hexadezimaler Darstellung angegeben. In binärer Darstellung werden einzelne Bits
und in hexadezimaler Darstellung je 4 Bits pro Ziffer bzw. Buchstabe dargestellt. Es
tritt ein Problem bei der Verarbeitung auf, denn in Java gibt es als kleinsten Datentyp
byte. Die auftretende Schwierigkeit liegt darin, dass mit byte auf die einzelnen Bits
zugegriffen werden soll. Der nächste Abschnitt geht auf das Problem ein und gibt
eine mögliche Lösung, die hier verwendet wird, an.
4.1.3 Problem von binärer und hexadezimaler Schreibweise in Java
Zwischen den beiden Darstellungen binär und hexadezimal kann umgerechnet
werden. In binärer Darstellung ist jedes Bit beschrieben, wogegen die hexadezimale
Darstellung als Zusammenfassung von je 4 Bits aufgefasst werden kann – sie ist
dementsprechend ¾ kürzer als die binäre. Trotzdem ist sie noch doppelt so lang wie
der Datentyp byte, der kleinste, den es in Java gibt. Das Problem, das hierbei auftritt, ist nicht die Umrechnung von einem Java-byte in eine der anderen beiden Darstellungen, die hier wie im MPEG-1-Standard [I93] verwendet werden, sondern vielmehr die Verarbeitung einzelner Bits. Wenn auf weniger als 8 Bits oder 8 nicht bytealigned Bits zugegriffen werden soll, dann ist es nicht möglich einfach ein byte zu
verändern. Es muss Bit-Shifting verwendet werden, bei dem einzelne (oder auch
zusammenhängende) Bits separiert werden, damit auf diese einzeln zugegriffen
werden kann und sie einzeln bearbeitet werden können. Die Funktionsweise des BitShiftings wird hier nicht erklärt; dies kann in [U06], Kapitel 2.8.4, nachgelesen
werden.
Bei der Bearbeitung und genauen Analyse von MPEG-Byteströmen (siehe Kapitel
4.2.2) muss nicht nur auf byte-aligned Bytes, sondern auch auf Bits, die nicht aus
mindestens 8 aufeinander folgenden Bits bestehen und mitten in einem Byte anfangen, also nicht byte-aligned sind, zugegriffen werden. Dieser Problematik vorwegnehmend wird hier festgelegt, dass eine Bearbeitung auf Bitebene erfolgen und die
16
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
binäre Darstellung verwendet werden soll. So kann auf jedes Bit einzeln zugegriffen
werden, was sich in Kapitel 4.2.2 als geeignet herausstellen wird.
Die Bearbeitung von Bits kann nicht ohne weiteres in Java umgesetzt werden, denn
dort ist byte der kleinste Datentyp. Zur Lösung dieses Problems wurde eine Variante gewählt, bei der mit byte je ein Bit repräsentiert wird. Ein byte soll nur die
binären Werte 0 (als Byte repräsentiert durch 0000 0000) und 1 (als Byte repräsentiert durch 0000 0001) annehmen können. So kann ein byte als Bit interpretiert
werden und das Problem ist gelöst, denn es kann auf einzelne Bits zugegriffen
werden.
Diese Variante ist nicht speicherfreundlich, denn dadurch steigen die jeweiligen
byte-Arrays auf 8-fache Länge an. Trotzdem hat sich dieses Vorgehen bewährt,
denn es ist notwendig an die Werte der einzelnen Bits zu gelangen. Eine Alternative
wäre das Bit-Shifting, bei dem im Endeffekt auch nichts anderes gemacht wird, als
ein Bit mit einem Byte dazustellen. Diese Alternative würde vielleicht weniger Speicher benötigen da jeweils nur ein oder wenige aktuelle Bits eines bytes, die gerade
verglichen oder verändert werden, als separate zusätzliche bytes dargestellt werden. Das Problem, das bei dieser Alternative auftritt, besteht in einer längeren höheren Laufzeit, denn es ist rechenaufwändig jedes Bit einzeln umzuwandeln und gleich
wieder zurück in Byte zu wandeln. Da Java eine verhältnismäßig langsame Programmiersprache ist, ist die Variante mehr Speicherplatz zu benötigen der Variante
mehr Rechenaufwand zu haben vorzuziehen.
4.2 Weiterverarbeitung der elementaren Einheiten
Eine mögliche Weiterverarbeitung der elementaren Einheiten stellt die
Watermarker-Klasse dar. Sie kann als Verarbeitung auf der Abstraktionsebene der
elementaren, semantischen Einheiten gesehen werden, dessen Grundlage im
vorigen Abschnitt erarbeitet wurde.
Es wird ein Konzept entwickelt, bei dem die elementaren, semantischen Einheiten
durch Frame-Klassen repräsentiert werden. Diese Frame-Klassen ermöglichen eine
detaillierte Analyse der Frames eines MPEG-Videos. Es soll sogar auch auf die
kleinsten Einheiten, die DCT-Koeffizienten, zugegriffen werden können. Das vorgestellte Konzept dient als notwendige Grundlage für Watermarker.
Vorliegendes Kapitel gibt zuerst einen grundlegenden Einblick in das Verfahren digitaler Wasserzeichen (Abschnitt 4.2.1), bevor die Umsetzung des Konzeptes der detaillierten Frame-Analyse erarbeitet wird (Abschnitt 4.2.2). Schließlich ist in den Abschnitten 4.2.3 und 4.2.4 die Umsetzung der weiteren Verarbeitung der elementaren
Einheiten am Beispiel der Markierung von MPEG-Videos mit digitalen Wasserzeichen beschrieben.
17
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
4.2.1 Digitale Wasserzeichen
Das Haupteinsatzgebiet digitaler Wasserzeichen sind Integritäts- und Authentizitätsnachweise digitaler Medien. Die Anwendungsgebiete digitaler Wasserzeichen sind
vielfältig und fordern unterschiedliche Eigenschaften und Parameter. Digitale
Wasserzeichen sind nicht-wahrnehmbar und untrennbar mit einem Medium verbunden, so dass sie nicht unbefugt entfernt oder modifiziert werden können. Dieser
Abschnitt gibt einen Überblick über Eigenschaften und Anwendungsgebiete digitaler
Wasserzeichen.
4.2.1.1 Grundlagen
Digitale Wasserzeichen stellen eine Sicherheitslösung für Angriffe gegen digitale
Medien dar. Sie sind so konzipiert, dass sie nicht-wahrnehmbar, also transparent
sind. Digitale Wasserzeichen beschreiben Verfahren, die es ermöglichen, versteckt
Informationen in digitale Medien einzubetten ([CMB02], Kapitel 1).
Die eingebetteten Informationen (Wasserzeichennachricht) können zum Beispiel
einen Urhebernamen, eine Kunden- oder Seriennummer, Prüfsummen oder Produktwerbung beinhalten. Bei der Einbettung eines Wasserzeichens wird der Inhalt des
digitalen Mediums insofern modifiziert, dass die Aussage des Mediums unverändert
bleibt und die zusätzlichen Informationen nicht-wahrnehmbar hinzugefügt werden.
Die zusätzliche Information wird untrennbar mit dem Medium verbunden.
Wasserzeichenverfahren sind abhängig von den gewünschten Eigenschaften, die im
nächsten Abschnitt erklärt sind. ([D00], Kapitel 3)
4.2.1.2 Eigenschaften
Digitale Wasserzeichen besitzen verschiedene Eigenschaften. Die wichtigsten sind
Transparenz, Kapazität, Robustheit, Sicherheit und Performanz. Es hängt jeweils von
der Art der Anwendung ab, welcher dieser Faktoren wie stark gewichtet wird.
Die Transparenz gibt an, wie stark ein Wasserzeichen wahrnehmbar ist. Sie ist also
ein Maß für den Qualitätsverlust, der durch das Einbetten entsteht. Wasserzeichenverfahren mit hoher Transparenz zielen auf eine nicht-wahrnehmbare Manipulation,
also einen geringen Qualitätsverlust des ursprünglichen Mediums. Im Gegensatz
dazu, liegt auf diesem Verlust bei Verfahren mit geringer Transparenz ein nicht so
großer Wert.
Die Kapazität digitaler Wasserzeichen bezeichnet den Umfang (die Anzahl der Bits)
der eingebetteten Information. Um eine große Kapazität zu erzielen, muss das
Medium eine ausreichend hohe Datenrate für die Wasserzeichennachricht
bereitstellen. ([CMB02], Kapitel 2.2.3)
Robuste Wasserzeichen dürfen durch übliche Verarbeitungsschritte oder Manipulationen, wie Komprimierung und Skalierung der Medien nicht zerstört werden. Sie
18
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
müssen beispielsweise nach Digital/Analog- bzw. Analog/Digital-Wandlungen oder
Konvertierungen in andere Datei- und Kompressionsformate noch eindeutig und
unverändert auszulesen sein. ([D00], Kapitel 3.1.3.1) Die Skala der Robustheit reicht
von robust bis fragil, wobei fragil bedeutet, dass das Wasserzeichen bei Veränderungen zerstört wird.
Sicherheit bei digitalen Wasserzeichen bedeutet, wie hoch der Schutz des Wasserzeichens vor gezielten Angriffen ist. Ein Wasserzeichen gilt als sicher, wenn man es
ohne einen geheimen Schlüssel weder auslesen noch verändern kann, ohne dabei
das Medium selbst zu zerstören – sogar dann, wenn man ein markiertes Medium
besitzt und Kenntnis über das Wasserzeichenverfahren hat ([D00], Kapitel 3.1.3.4).
Wenn von der Performanz digitaler Wasserzeichen gesprochen wird, dann ist damit
die Einbettungszeit gemeint. Im Praxiseinsatz müssen der Einbettungs- und der
Auslesevorgang ausreichend schnell geschehen. Je nach Anwendung ist hierbei ein
Vielfaches von Echtzeitgeschwindigkeit notwendig.
All diesen Anforderungen zu entsprechen würde für ein einziges digitales Wasserzeichen keinen Sinn ergeben und wäre auch nicht möglich. Die Anforderungsschwerpunkte und Eigenschaften hängen daher von der jeweiligen Anwendung ab.
([D00], Kapitel 3.1.3.8)
4.2.1.3 Anwendungsgebiete
Ein Hauptanwendungsgebiet digitaler Wasserzeichen ist die Urheberidentifizierung
(Schutz des Urheberrechts, Authentifizierung des Senders). Hierfür ist es sinnvoll,
die zusätzlichen Informationen, die einen Urheber eindeutig kennzeichnen, so komplex wie möglich mit dem Medium zu verbinden. Nach Veränderungen und Angriffen
muss die Urheberschaft (Authentizität) noch eindeutig nachgewiesen werden
können. Es werden nicht-wahrnehmbare, robuste Wasserzeichen eingesetzt, um den
Urheber, in der Kommunikationstheorie auch als Sender bezeichnet, eindeutig identifizieren bzw. authentifizieren zu können. ([D00], Kapitel 4)
Eine ähnliche Anwendung ist die Kundenidentifizierung (Authentifizierung des
Empfängers), bei der eine eindeutige Kundeninformation, beispielsweise eine
Kundennummer, individuell in jedem verkauften Medium robust eingebettet wird. Die
Verkäufer digitaler Medien können jederzeit den Käufer identifizieren und auch bei
unberechtigter Vervielfältigung oder Veröffentlichung kann ein eindeutiger Erzeuger
(Kunde) der Kopie authentifiziert werden ([D00], Kapitel 5)
Ein anderes Einsatzgebiet digitaler Wasserzeichen ist der Integritätsnachweis. Dabei
muss jede kleinste Veränderung, die die Aussage des Mediums betrifft, erkannt werden. Das Medium darf nicht unbemerkt und unberechtigt verändert werden. Gleichzeitig sollte das Wasserzeichen gegenüber Manipulationen, die unabhängig von der
Aussage sind, wie Kompression oder Skalierung, robust sein. Für solche Anforderungen werden inhaltsbasierte fragile Wasserzeichen verwendet. Eine Modifikation
19
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
der Aussage des Mediums zerstört diese einerseits fragilen Wasserzeichen. Andererseits sind diese robust, da sie durch Modifikationen ohne Änderung der Aussage
nicht zerstört werden. Nutzt man die Eigenschaften inhaltsbasierter fragiler
Wasserzeichen, kann Integritätsschutz gewährleistet werden ([D00], Kapitel 6).
4.2.1.4 LSB-Wasserzeichen
In dieser Arbeit wird ein simples digitales Wasserzeichen verwendet, ein LSBWasserzeichen (Least Significant Bit). Es handelt sich dabei um ein Bildwasserzeichen, bei dem einzelne Werte eines Bildes nicht-wahrnehmbar manipuliert werden. In diesem Abschnitt wird ein LSB-Wasserzeichen am Beispiel eines Bildes im
RGB-Format vorgestellt. Es gibt verschiedene Möglichkeiten ein LSB-Wasserzeichen
zu realisieren. Ein grundlegendes Verständnis für ein LSB-Wasserzeichen wird in
diesem Abschnitt geschaffen und später bei der Umsetzung im Projekt in Abschnitt
4.2.3 auf ein Frame des MPEG-Videos übertragen.
In einem digitalen Bild, das im RGB-Format vorliegt, hat jeder Bildpunkt jeweils eine
Farbwertangabe für Rot (R), Grün (G) und Blau (B). Diese Werte liegen normalerweise jeweils zwischen 0 und 255 und sind also je 8 Bit groß. Andere Werte des
RGB-Formates werden an dieser Stelle vernachlässigt, da sie für das Verstehen des
LSB-Wasserzeichens nicht von Interesse sind.
Die Rot-, Grün- und Blauwerte werden vom menschlichen Auge unterschiedlich stark
wahrgenommen. Da der Blauwert am geringsten wahrgenommen wird, fällt dort eine
Wertänderung am wenigsten auf. Das hier erklärte LSB-Wasserzeichen verändert
das niedrigste Bit des Blauwertes, das LSB, also das Bit mit der geringsten Bedeutung für den visuellen Gesamteindruck. Dies erfolgt, indem von jedem Bildpunkt, in
das die Wasserzeichennachricht eingebettet werden soll, jeweils das LSB betrachtet
wird. Die Wasserzeichennachricht, die letztendlich auch nur durch Bits repräsentiert
wird, wird auf die ausgewählten LSBs übertragen. Dabei kann entweder einfach
jedes LSB des Bildes an das Bit der Wasserzeichennachricht angepasst werden, unberücksichtigt welche Werte die LSBs zuvor hatten.
Eine andere Möglichkeit wäre folgende: Wenn die Wasserzeichennachricht in dem
jeweiligen Bit eine 0 bzw.1 enthält, so wird das LSB, das dieses Bit repräsentieren
soll, ebenfalls auf 0 bzw. 1 gesetzt. Es wird zunächst verglichen, ob das LSB bereits
identisch mit dem einzubettenden Bit ist, in diesem Fall wird keine Manipulation vorgenommen, andernfalls wird das LSB angepasst. Es wird also nicht unbedingt jedes
LSB bzw. Bildpunkt, das einen Teil der Wasserzeichennachricht darstellt, manipuliert, sondern nur solche, die nicht von vorne herein die gewünschte Information tragen. Das Ergebnis ist mit beiden Vorgehensweisen gleich; also egal, ob man einfach
jedes LSB mit dem Bit der Wasserzeichennachricht überschreibt unbeachtet der
vorigen Werte der LSBs oder ob man zuerst jedes LSB mit dem Bit der Nachricht
vergleicht und nur wenn notwendig eine Anpassung vornimmt.
20
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
In diesem Projekt soll ein LSB-Wasserzeichen in ein MPEG-Video eingebettet werden. Ähnlich dem beschriebenen LSB-Wasserzeichen in einem Bild im RGB-Format,
kann auch in I-Frames eines MPEG-Videos ein LSB-Wasserzeichen eingebracht
werden. Wie in Kapitel 2.2 beschrieben, basieren I-Frames auf JPEG-Komprimierung. Bei der Markierung von I-Frames bzw. JPEG-Bildern mit LSB-Wasserzeichen
übernehmen DCT-Werte die Rolle der RGB-Werte. Dies ist in Abschnitt 4.2.3
beschrieben.
Das LSB-Wasserzeichen ist fragil, denn die Wahrscheinlichkeit, selbst bei einer einfachen Manipulation des Bildes ein LSB, das einen Teil der Wasserzeichennachricht
darstellt, zu verändern, ist sehr hoch. Das LSB-Wasserzeichen ist für viele Anwendungen von Interesse. Es kann beispielsweise als fragiles Wasserzeichen zur
Authentifizierung von Bildinhalten verwendet werden. ([CMB02], Kapitel 5.3.3)
4.2.2 Konzept der detaillierten Frame-Analyse
In Abschnitt 4.1 wurde bereits das DivideIntoUnits-PlugIn vorgestellt, mit
dessen Hilfe Frames aus einem MPEG-Video-Strom herausgesucht werden können.
Diese Frames sollen mit Hilfe der Watermarker-Klasse mit digitalen Wasserzeichen
markiert werden. Dafür ist ein Zwischenschritt notwendig, der hier vorgestellt wird.
Das Konzept sieht eine Frame-Klasse vor; diese ist nicht zu verwechseln mit
java.awt.Frame. Das DivideIntoUnits-PlugIn soll der Klasse Frame die
herausgesuchten Frame-Daten übergeben und somit separieren. Bei noch genauerer Betrachtung dieses Konzeptes gibt es für die spezifischen Frame-Typen individuelle Subklassen von Frame. So gibt es die Klasse IFrame, die alle I-Frames repräsentiert. Das DivideIntoUnits-PlugIn soll also alle I-Frame-Daten der Klasse
IFrame übergeben. An dieser Stelle kommt einer der in Abschnitt 2.4 angedeuteten
Gründe zum Tragen, warum in dieser Arbeit lediglich I-Frames und keine P- oder BFrames separiert und weiter verarbeitet werden: I-Frames besitzen insgesamt zwar
mehr Informationen, da sie komplette Bilder darstellen, jedoch gibt es beim Analysieren eines MPEG-Bytestroms einige erhebliche Erleichterungen. All diese Erleichterungen zu erwähnen würde den Rahmen der Arbeit übersteigen, sie sind im MPEG1-Standard [I93] nachzulesen. Hier soll ein ausgewähltes Beispiel genügen: Makroblöcke besitzen Typangaben, die weitere Parameter nach sich ziehen. Werden nur IFrames untersucht, so können die Typen und Parameter-Werte für P- und B-Frames
von vorneherein ausgeschlossen werden.
Die Klasse IFrame analysiert die Daten, die sie von DivideIntoUnits übergeben
bekommt. Da die DCT-Koeffizienten zur Markierung mit einem LSB-Wasserzeichen
von Interesse sind, müssen die Frame-Daten danach durchsucht werden. Als erstes
müssen jedoch die Slices herausgesucht werden. Dabei sieht das Konzept die
Klasse Slice vor, an die IFrame die Slice-Daten übergibt. Dies stellt kaum eine
Schwierigkeit dar, denn Slices haben Startcodes. Das bedeutet, sie beginnen mit den
üblichen 3 Bytes aus Nullen. Das 4. Byte kann 0x01 bis 0xAF beinhalten und dient
21
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
neben der Erkennung als Slice-Startcode gleichzeitig als vertikale Positionierung des
ersten Makroblocks eines Slices in einem Frame. Darauf folgen einige Angaben wie
Quantisierung und Zusatzinformationen, bevor die Makroblöcke beginnen.
Ein Makroblock eines I-Frames hat eine Adress- und eine Typangabe, gefolgt von
den Blöcken. Da ein I-Frame ein vollständiges Bild darstellt, besitzen die Makroblöcke jeweils sechs Blöcke; vier für die Luminanz (Helligkeit) und zwei für die Chrominanz (Farbe). Diese Blöcke stellen eine Anordnung von 8x8 Bildpunkten dar und
dienen als Eingabe für die diskrete Kosinus-Transformation. Bei der Bildkomprimierung werden Blöcke aus 8x8 Bildpunkten in 8x8 DCT-Koeffizienten transformiert, wie
dies im nächsten Abschnitt beschrieben wird. Die Slice-Klasse sucht aus den
Daten, die sie von IFrame übergeben bekommen hat, die DCT-Koeffizienten heraus,
damit diese dann mit Wasserzeichen markieren werden können.
An dieser Stelle kann die Klasse Watermarker eingebunden werden. Die DCTKoeffizienten liegen als Bits in byte-Arrays vor und können mit einem LSBWasserzeichen markiert werden, wie es in den nächsten Abschnitten beschrieben
wird.
4.2.3 LSB-Wasserzeichen in MPEG
Der Aufbau eines LSB-Wasserzeichen in einem Bild, das im RGB-Format vorliegt,
wurde in Abschnitt 4.2.1.4 beschrieben. Es wurde darauf hingewiesen, dass es sich
von einem LSB-Wasserzeichen in einem MPEG-Video unterscheidet. Die Frames
eines MPEG-Videos basieren auf JPEG-Komprimierung. Sie beinhalten keine separaten Werte für Rot, Grün und Blau, sondern die Bildpunkte werden durch DCTKoeffizienten dargestellt. Um ein LSB-Wasserzeichen in einem MPEG-Frame nachvollziehen zu können, werden die DCT-Koeffizienten eines Frames genauer erklärt.
Wie in Abschnitt 2.3 beschrieben, bestehen Makroblöcke in I-Frames aus 6 Blöcken,
die zusammen 16x16 Bildpunkte darstellen (siehe Abbildung 3). Jeder Block beinhaltet 8x8 Werte des Bildpunktbereichs (Ortsbereich) und dient als Eingabe für die
diskrete Kosinus-Transformation. Ein Block mit 8x8 Werten aus dem Ortsbereich,
Abbildung 9 (a), wird mit Hilfe der zweidimensionalen diskreten Kosinus-Transformation in 8x8 Werte im Frequenzbereich, also in DCT-Koeffizienten siehe Abbildung
9 (b), transformiert.
22
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Abbildung 9: Diskrete Kosinus-Transformation [I93], [O04]
Abbildung 9 stellt neben den DCT-Koeffizienten (b) die nach der Frequenz angeordnet sind die zugehörigen DCT-Basisfunktionen (c) dar. Der linke obere DCT-Koeffizient wird mit DC (Direct Current) bezeichnet und gibt die durchschnittliche Helligkeit
aller Werte eines Blockes an. DC repräsentiert die einzige konstante Basisfunktion.
Die anderen Koeffizienten heißen AC (Alternating Current) und geben die Abweichung zu dem DC-Wert an. Die AC-Werte rechts von DC repräsentieren horizontale,
ansteigende Frequenzen und die AC-Werte unterhalb des DC-Wertes repräsentieren
vertikale, ansteigende Frequenzen. Andere AC-Werte beinhalten sowohl horizontale,
als auch vertikale Frequenzen.
Alle DCT-Koeffizienten eines Blocks beinhalten alle Bildpunkt-Werte eines Blocks.
Dabei können diese beiden Block-Repräsentationen trotz ähnlicher Darstellungsmöglichkeiten (Koordinaten-Anordnung) und gleichen Werte-Anzahlen (beide 8x8)
nicht gleichgesetzt werden; in einem Frame wird nicht einfach jeder Bildpunkt durch
einen DCT-Koeffizient repräsentiert. Die diskrete Kosinus-Transformation, die die
beiden Repräsentationen voneinander trennt bzw. ineinander transformiert, ist komplexer als solch eine simple Annahme.
Die zweidimensionale diskrete Kosinus-Transformation ist ein Produkt zweier eindimensionaler DCTs. x und y beschreiben die 64 Werte eines Blocks, die wie folgt in
eine DCT-Darstellung transformiert werden: [I93]
23
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Mit Hilfe der Transformationsformel werden räumlich angeordnete Bildpunkte f(x,y)
aus dem Ortsbereich in eine äquivalente Darstellung im Frequenzbereich, in DCTKoeffizienten F(u,v), transformiert. Dabei stellt f(x,y) die 64 Werte im Bild- bzw. Ortsbereich (Bildpunkte) dar. Die exakten Werte sind vom jeweiligen Farbmodell abhängig und können in MPEG-1 die in der Formel angegebenen Werte annehmen. F(u,v)
repräsentiert die 64 DCT-Koeffizienten-Werte des Frequenzbereichs. Das Prinzip der
Transformation ist für alle Blöcke (Luminanz- und Chrominanzblöcke) gleich; lediglich
die exakten Werte hängen von dem jeweiligen Block, also von dem was sie repräsentieren (beispielsweise Helligkeit oder Farbe), ab.
Um einen Frame in quadratischen Einheiten darstellen zu können und gleichzeitig
den Rechenaufwand zu verringern, wird die DCT nicht auf einen ganzen Frame angewendet, sondern normalerweise auf 8x8 Bildpunkt-Werte. Würde man die Anzahl
der Bildpunkte erhöhen, könnte zwar eine bessere Komprimierung erreicht werden,
jedoch zum Nachteil der Laufzeit. ([KAA04], Kapitel 2) So kommt es zu einer Blockgröße von 8x8 Bildpunkten.
Die berechneten DCT-Koeffizienten werden schließlich noch einer Quantisierung
unterzogen, die hier nicht erklärt wird, da sie für diese Arbeit nicht relevant ist.
Die DCT-Koeffizienten müssen im Bytestrom nacheinander gespeichert sein, sie
werden im Zig-Zag-Modus von links oben bis rechts unten geordnet. Da sich die
meisten Werte auf die linke obere Ecke der Matrix aus Abbildung 9 (b) konzentrieren,
also meistens die hohen Frequenzen auftreten, ergibt sich der Vorteil, dass mögliche
Nullen am Ende eines Blockes nicht unbedingt aufgeführt werden müssen, sondern
durch einen End-Of-Block-Code verkürzt werden können.
Ein Makroblock besteht aus 4 Luminanz- und 2 Chrominanzblöcken. Deren Werte
werden nacheinander im Bytestrom angeordnet, zuerst die Luminanz- und dann die
Chrominanz-Werte. Da Änderungen von Luminanzblöcken stärker auffallen, sollen
für die Least-Significant-Bits in einem Frame die Chrominanzblöcke betrachtet
werden.
24
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
In einem I-Frame bestehen Makroblöcke jeweils aus sechs Blöcken, die je 64 DCTWerte besitzen. Da der letzte Chrominanzblock weniger Relevanz als der vorletzte
besitzt, beschränkt sich das hier verwendete LSB-Wasserzeichen auf diesen. Von
den 64 DCT-Werten fallen Änderungen am niedrigsten (also letzten) Wert am geringsten auf. Genau diese Bits stellen die LSBs dar und können analog zu den LSBs
eines Bildes im RGB-Format mit einem LSB-Wasserzeichen markiert werden. Die
LSBs werden für die Markierung mit einem LSB-Wasserzeichen herausgesucht, um
dann durch die Watermarker Klasse markiert werden zu können. Diese Funktionalität ist im folgenden Abschnitt beschrieben.
4.2.4 Watermarker Klasse
Die Funktionalität der Markierung mit digitalen Wasserzeichen erfolgt durch die
Watermarker-Klasse. Diese Klasse ist abstrakt und wird von der
LSBWatermarker-Klasse implementiert. Watermarker besitzt die abstakte
Methode process(inputByte), die von LSBWatermarker ebenfalls implementiert und definiert werden muss. Dieser Methode wird als Parameter ein byte übergeben, das ein Bit repräsentiert, und ein solches wird auch zurückgegeben – der
Rückgabetyp dieser Methode ist byte.
Die Funktionalität, die LSBWatermarker erfüllen soll, besteht in der Veränderung
der übergebenen bytes, die Bits repräsentieren. Die Bits, die an LSBWatermarker
übergeben werden, stellen bereits die LSBs dar. Das bedeutet, dass diese nun nach
dem Prinzip aus Abschnitt 4.2.1.4 an die Bits der Wasserzeichennachricht angepasst
werden müssen. Dabei wird nicht unbedingt jedes LSB, das an LSBWatermarker
übergeben wird und einen Teil der Wasserzeicheninformation darstellt, verändert
zurückgegeben. Es werden nur solche LSBs verändert zurückgegeben, die nicht von
vorne herein die gewünschte Information tragen.
Eine Schwierigkeit, die auftritt ist die, dass in Java lediglich byte als kleinste verwendbare Einheit existiert. Eine Lösung hierfür wurde bereits in Abschnitt 4.1.3 vorgestellt. Dort ist beschrieben, wie byte als Bit interpretiert werden kann und wie eine
mögliche Problemlösung aussehen kann.
25
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
5 Zusammenfassung
Die Aufgabe dieser Studienarbeit ist die Medienverarbeitung mit Java in elementaren
Einheiten. Das Ergebnis besteht aus einem PlugIn für das Java Media Framework:
Mit Hilfe des DivideIntoUnits-PlugIns wird eine Weiterverarbeitung in
elementaren, semantischen Einheiten ermöglicht. Es können die Klassen Frame,
Slice und Watermarker ergänzt werden, durch die eine Markierung des Videos
mit digitalen Wasserzeichen als Weiterverarbeitung der elementaren Einheiten ermöglicht wird.
Zuerst wurde die Frage nach den elementaren, semantischen Einheiten geklärt.
Diese Einheiten sollen die Eigenschaften von elementar, also grundlegend notwendig und wesentlich, sowie von semantisch, also einen Bezug zu der Bedeutung von
Zeichen bzw. der Bedeutung von Daten oder von Informationen, besitzen. Da ein
Video aus einer Folge von Frames besteht, kann eine elementare, semantische Einheit ein Frame sein.
In dieser Arbeit wird mit dem Videoformat MPEG gearbeitet. Dieses besteht aus Sequenzen, die sich aus Groups-Of-Pictures zusammensetzen. GOPs sind Folgen von
Frames. In einem Frame gibt es Slices, in denen wiederum Makroblöcke vorzufinden
sind. Die kleinste Einheit stellen schließlich die Blöcke dar.
In solch einem MPEG-Video wurde als nächstes eine elementare, semantische Einheit definiert. Der Aufbau eines MPEG-Videos zeigt, dass dieses Video durch die Art
der Komprimierung nicht einfach nur aneinander gereihte Frames darstellt, sondern
u. a. verschiedene Frame-Typen aufweist. In einer genauen Analyse wurde herausgearbeitet, dass für diese Arbeit die Separation von I-Frames ausreicht. Bei Separation aller möglichen Frame-Typen, also auch B-, P- und D-Frames, würde ein erheblicher Mehraufwand den Rahmen übersteigen. Kennt man den Aufbau eines MPEGVideos kann dessen Bearbeitung beginnen, bei der zunächst die elementaren, semantischen Einheiten herausgesucht werden sollen.
Für die Medienverarbeitung in Java bietet sich das Java Media Framework an. Dieses Framework stellt umfangreiche Funktionalitäten für die Medienbearbeitung zur
Verfügung. Um einen Video-Strom gezielt zu analysieren und zu bearbeiten eignet
sich die Verwendung von Processor. Es wird ein zusätzliches PlugIn mit vorgegebener Funktionalität benötigt, denn ein PlugIn kann in die Verarbeitungskette von
Processor integriert werden und auf die einzelnen Tracks eines Videos angewendet werden.
Ein Teil des Ergebnisses ist ein DivideIntoUnits-PlugIn, oder besser gesagt
ein DivideIntoUnits-Codec, also ein spezielles PlugIn, das auf den VideoTrack des MPEG-Videos angewendet wird. Es hat die Aufgabe, den Video-Strom,
der im JMF als byte-Array vorliegt, zu analysieren, die elementaren, semantischen
Einheiten zu finden und zu separieren. Es ist möglich, dass diese Einheiten einer
weiteren Verarbeitung unterzogen werden; beispielsweise können sie mit Hilfe der
26
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Klassen Frame, Slice und Watermarker mit digitalen Wasserzeichen markiert
werden.
Digitale Wasserzeichen können unter anderem dem Nachweis der Integrität oder
Authentizität eines Mediums dienen. Bei der Markierung eines Mediums mit einem
digitalen Wasserzeichen wird das Medium verändert, indem ihm zusätzlich nichtwahrnehmbare Informationen hinzugefügt werden.
Das Ergebnis besteht aus zwei Teilen, die kombiniert werden können. Zum einen
dient das DivideIntoUnits-PlugIn der Analyse eines Videos und dessen Zerlegung in elementare, semantische Einheiten. Zum anderen stellen Frame, Slice und
Watermarker eine mögliche Weiterverarbeitung der elementaren Einheiten dar, bei
der ein Video mit digitalen Wasserzeichen markiert werden kann.
27
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Anhang – Codebeispiel
Im Folgenden wird als Ergänzung zu Kapitel 4.1.1 ein Java Codebeispiel vorgestellt.
Es ist in gekürzter Form abgebildet und stellt keinen Anspruch auf Vollständigkeit,
sondern verdeutlicht die Funktionsweise der Medienverarbeitung im Java Media
Framework. Um ein solches Programm fehlerfrei auszuführen, fehlen noch einige
weitere Zeilen. Das Codebeispiel zeigt, wie ein MPEG-System-Strom eingelesen und
damit ein Processor erzeugt werden kann. Aus dem MPEG-System-Strom wird ein
Video-Track herausgesucht, um schließlich das DivideIntoUnits-PlugIn darauf anwenden zu können. Durch das Interface ControllerListener mit der Methode controllerUpdate ist ein Ereignis-Verarbeitungsmodell mit eingebunden.
import java.io.*;
import javax.media.*;
public class MpegAnalyser implements ControllerListener {
Processor processor;
MediaLocator inputMediaLocator;
Object waitSync = new Object();
boolean stateTransitionOK = true;
String inputFilePath = „pathToSomeVideo\\someVideo.mpg“;
TrackControl[] trackControl;
TrackControl videoTrack;
public static void main(String[] args) {
MpegAnalyser mpegAnalyser = new MpegAnalyser();
mpegAnalyser.startMpegAnalyser();
}
public MpegAnalyser() {
//create processor
processor = null;
inputMediaLocator = new MediaLocator("file:" + inputFilePath);
try {
processor = Manager.createProcessor(inputMediaLocator);
} catch (Exception exception) {
exception.printStackTrace();
}
processor.addControllerListener(this);
}
/**
* analyse MPEG stream and search video track, set plug-in to flow path
*/
public boolean startMpegAnalyser() {
//put the processor into configured state
processor.configure();
if (!waitForState(processor.Configured)) {
System.err.println("Failed to configure the processor.");
return false;
}
//obtain the track controls
trackControls = processor.getTrackControls();
if (trackControls == null) {
return false;
}
//search for the trackControl for the videoTrack
videoTrack = null;
for (int i = 0; i < trackControls.length; i++) {
if (trackControls[i].getFormat() instanceof VideoFormat){
videoTrack = trackControls[i];
break;
}
v
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
}
if (videoTrack == null) {
System.err.println("Input media does not contain a video track.");
return false;
}
//instantiate and set DivideIntoUnits codec to data flow path
try {
Codec codecs[] = {new DivideIntoUnits()};
videoTrack.setCodecChain(codecs);
} catch (UnsupportedPlugInException e) {
System.err.println("Process does not support effects.");
}
//realize the processor
processor.prefetch();
if (!waitForState(processor.Prefetched)) {
System.err.println("Failed to realize the processor.");
return false;
}
//start the processor
processor.start();
return true;
}
/**
* block until processor has transitioned to the given state,
* return false if transition failed
*/
boolean waitForState(int state) {
synchronized (waitSync) {
try {
while (processor.getState() != state && stateTransitionOK)
waitSync.wait();
} catch (Exception e) {
System.err.println("Exception in method waitForState: " + e);
}
}
return stateTransitionOK;
}
/**
* method for event handling, is always called if event is caused
*/
public void controllerUpdate(ControllerEvent controllerEvent) {
if (controllerEvent instanceof ConfigureCompleteEvent ||
controllerEvent instanceof RealizeCompleteEvent ||
controllerEvent instanceof PrefetchCompleteEvent) {
synchronized (waitSync) {
stateTransitionOK = true;
waitSync.notifyAll();
}
} else if (controllerEvent instanceof ResourceUnavailableEvent) {
synchronized (waitSync) {
stateTransitionOK = false;
waitSync.notifyAll();
}
} else if (controllerEvent instanceof EndOfMediaEvent) {
processor.close();
System.exit(0);
}
}
}
vi
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
Quellen
[CMB02]
Cox, I. J., Miller, M. L., Bloom, J. A.: Digital Watermarking.
Academic Press, San Diego, ISBN: 1-55860-714-5, 2002
[D00]
Dittmann, J.: Digitale Wasserzeichen. Springer Verlag, Berlin,
Heidelberg, ISBN: 3-540-66661-3, 2000
[ED04]
Eidenberger, H. M., Divotkey, R.: Medienverarbeitung in Java™ – Audio
und Video mit Java Media Framework & Mobile Media API,
dpunkt Verlag, Heidelberg, ISBN: 3-89864-184-8, 1. Auflage, 2004
[H95]
Heuler, M.: Bilddatenkompression mit MPEG-2.
http://www.heuler.net/stud/seminar/node3.html#SECTION00021,
13.06.1995, zuletzt überprüft: 10.01.2006
[I93]
ISO/IEC 11172: Information technology – Coding of moving pictures
and associated audio for digital storage media at up to about 1,5 MBit/s.
International Standart © ISO/IEC, Genf, 1. Ausgabe: 01.08.1993
[KAA04]
Kachouri, R., Abid, M., Amar, C. B.: Design of DCT_2D toward FPGA.
IEEE Conference Proceeding, 2004
[L]
Lo, V.: A beginners guide for MPEG-2 Standard.
http://www.fh-friedberg.de/fachbereiche/e2/telekomlabor/zinke/mk/mpeg2beg/beginnzi.htm, zuletzt überprüft: 22.03.2006
[M95]
Moving Pictures Experts Group: The MPEG Home page.
http://www.chiariglione.org/mpeg/, zuletzt überprüft: 10.01.2006
[M96]
MPEG-2: Unix Open 05/96 Mai – Video-Codierung mit MPEG-2.
http://www.mpeg2.de/doc/mpuo05/mpuo05.htm, 1996,
zuletzt überprüft: 10.01.2006
[M03]
Mandau, M.: Vergleichstest: MPEG4-Encoder & Alternativen – Wie
MPEG-Standards Filme komprimieren. CHIP Online Archiv,
http://archiv.chip.de/artikel/c1_archiv_artikelunterseite_17143436.html,
27.05.2003, zuletzt überprüft: 30.03.2006
[O04]
Okumura, H.: DCT (Discrete Cosine Transform).
http://oku.edu.mie-u.ac.jp/~okumura/compression/dct.html, 2004,
zuletzt überprüft: 22.03.2006
vii
Medienverarbeitung mit Java in elementaren Einheiten
Verena Henrich
[P06]
PARADISO-design.net: Fernsehnormen – Standards und Technik.
http://www.paradiso-design.net/videostandards.html, 2004 – 2006,
zuletzt überprüft: 10.01.2006
[S99]
Steinmetz, R.: Multimedia-Technologie – Grundlagen, Komponenten
und Systeme. Springer Verlag, Berlin, Heidelberg,
ISBN: 3-540-62060-5, 2. Auflage, 1999
[SM99]
Sun Microsystems: Java™ Media Framework API Guide.
Sun Microsystems, Inc., California,
http://java.sun.com/products/java-media/jmf/2.1.1/specdownload.html,
19.11.1999
[SM01]
Sun Microsystems: Java Media Framework API. Sun Microsystems,
Inc., http://java.sun.com/products/java-media/jmf/2.1.1/apidocs/,
1999 – 2001, zuletzt überprüft: 25.01.2006
[SM05]
Sun Microsystems: Java Media Framework Homepage.
Sun Microsystems, Inc., http://java.sun.com/products/java-media/jmf/,
1994 – 2005, zuletzt überprüft: 10.01.2006
[U06]
Ullenboom, C: Java ist auch eine Insel – Programmieren mit der Java
Standard Edition Version 5. Galileo Computing, ISBN 3-89842-747-1,
http://www.galileocomputing.de/openbook/javainsel5/, 5. Auflage, 2006
viii
Herunterladen