MediaCodec Klasse

Definition

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

[Android.Runtime.Register("android/media/MediaCodec", DoNotGenerateAcw=true)]
public sealed class MediaCodec : Java.Lang.Object
[<Android.Runtime.Register("android/media/MediaCodec", DoNotGenerateAcw=true)>]
type MediaCodec = class
    inherit Object
Vererbung
MediaCodec
Attribute

Hinweise

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs, d. h. Encoder-/Decoderkomponenten, verwendet werden. Es ist Teil der Low-Level-Multimedia-Unterstützungsinfrastruktur von Android (wird normalerweise zusammen mit MediaExtractor, MediaSync, MediaMuxer, MediaCrypto, MediaDrm, Image, Surfaceund AudioTrackverwendet).

<center><img src=". /.. /.. /images/media/mediacodec_buffers.svg" style="width: 540px; height: 205px" alt="MediaCodec puffer flow diagram"></center>

Im Allgemeinen verarbeitet ein Codec Eingabedaten, um Ausgabedaten zu generieren. Es verarbeitet Daten asynchron und verwendet einen Satz von Eingabe- und Ausgabepuffern. Auf einer einfachen Ebene fordern (oder empfangen) Sie einen leeren Eingabepuffer an, füllen ihn mit Daten auf und senden ihn zur Verarbeitung an den Codec. Der Codec verwendet die Daten und transformiert sie in einen seiner leeren Ausgabepuffer. Schließlich fordern (oder empfangen) Sie einen gefüllten Ausgabepuffer an, nutzen dessen Inhalt und geben ihn wieder an den Codec frei.

<h3 id=qualityFloor>"qualityFloor">Minimum Quality Floor for Video Encoding</h3>

android.os.Build.VERSION_CODES#SAb erzwingen die Video MediaCodecs von Android eine Mindestqualität. Die Absicht besteht darin, Videocodierungen mit schlechter Qualität zu beseitigen. Dieser Qualitätsboden wird angewendet, wenn sich der Codec im VBR-Modus (Variable Bitrate) befindet. Sie wird nicht angewendet, wenn sich der Codec im CBR-Modus (Constant Bitrate) befindet. Die Qualität der Bodenerzwingung ist ebenfalls auf einen bestimmten Größenbereich beschränkt; Dieser Größenbereich ist derzeit für Videoauflösungen größer als 320 x 240 bis 1920 x 1080.

Wenn diese Qualitätsebene wirksam ist, funktionieren der Codec und der unterstützende Frameworkcode, um sicherzustellen, dass das generierte Video mindestens eine "faire" oder "gute" Qualität aufweist. Die Metrik, die zum Auswählen dieser Ziele verwendet wird, ist die VMAF (Video Multi-Method Assessment Function) mit einer Zielbewertung von 70 für ausgewählte Testsequenzen.

Der typische Effekt ist, dass einige Videos eine höhere Bitrate generieren als ursprünglich konfiguriert. Dies ist besonders für Videos zu beachten, die mit sehr niedrigen Bitraten konfiguriert wurden; Der Codec verwendet eine Bitrate, bei der die Wahrscheinlichkeit höher ist, dass ein Video mit "fairer" oder "guter" Qualität generiert wird. Eine andere Situation ist, dass ein Video sehr komplizierte Inhalte enthält (viel Bewegung und Details); in solchen Konfigurationen verwendet der Codec bei Bedarf eine zusätzliche Bitrate, um zu vermeiden, dass alle detailsigen Inhalte verloren gehen.

Diese Qualitätsebene wirkt sich nicht auf Inhalte aus, die mit hohen Bitraten erfasst wurden (eine hohe Bitrate sollte dem Codec bereits genügend Kapazität bieten, um alle Details zu codieren). Der Qualitätsboden funktioniert nicht mit CBR-Codierungen. Der Qualitätsboden funktioniert derzeit nicht mit Auflösungen von 320x240 oder niedriger, noch bei Videos mit einer Auflösung über 1920 x 1080.

<h3-Datentypen></h3>

Codecs arbeiten mit drei Arten von Daten: komprimierte Daten, Rohdaten von Audiodaten und Rohvideodaten. Alle drei Arten von Daten können mit ByteBuffer ByteBuffersverarbeitet werden, aber Sie sollten ein Surface für Rohvideodaten verwenden, um die Codecleistung zu verbessern. Surface verwendet native Videopuffer, ohne sie zuzuordnen oder in ByteBuffers zu kopieren. daher ist es viel effizienter. Normalerweise können Sie nicht auf die Rohdaten zugreifen, wenn Sie ein Surface verwenden, aber Sie können die ImageReader -Klasse verwenden, um auf ungesicherte decodierte (rohe) Videoframes zuzugreifen. Dies ist möglicherweise noch effizienter als die Verwendung von ByteBuffers, da einige native Puffer möglicherweise byteBuffer#isDirect direct ByteBuffers zugeordnet werden. Wenn Sie den ByteBuffer-Modus verwenden, können Sie mit der Image -Klasse und #getInputImage getInput/#getOutputImage OutputImage(int)auf rohe Videoframes zugreifen.

<h4>Komprimierte Puffer</h4>

Eingabepuffer (für Decoder) und Ausgabepuffer (für Encoder) enthalten komprimierte Daten gemäß dem Formattyp MediaFormat#KEY_MIME. Bei Videotypen handelt es sich normalerweise um einen einzelnen komprimierten Videoframe. Bei Audiodaten handelt es sich normalerweise um eine einzelne Zugriffseinheit (ein codiertes Audiosegment, das in der Regel einige Millisekunden Audio enthält, wie vom Formattyp vorgegeben), aber diese Anforderung wird etwas gelockert, da ein Puffer mehrere codierte Audiozugriffseinheiten enthalten kann. In beiden Fällen beginnen oder enden Puffer nicht auf beliebigen Bytegrenzen, sondern auf Rahmen-/Zugriffseinheitsgrenzen, es sei denn, sie sind mit #BUFFER_FLAG_PARTIAL_FRAMEgekennzeichnet.

<h4>Rohdaten-Audiopuffer</h4>

Rohdaten-Audiopuffer enthalten ganze Frames von PCM-Audiodaten, bei denen es sich um ein Beispiel für jeden Kanal in der Kanalreihenfolge handelt. Jedes PCM-Audiobeispiel ist entweder eine 16-Bit-Ganzzahl mit Vorzeichen oder ein Float in nativer Bytereihenfolge. Rohdaten-Audiopuffer in der Float-PCM-Codierung sind nur möglich, wenn mediaFormat#KEY_PCM_ENCODING mediaFormat#ENCODING_PCM_FLOAT während MediaCodec #configure configure(&hellip;) auf AudioFormat#ENCODING_PCM_FLOAT festgelegt und von #getOutputFormat für Decoder oder #getInputFormat Encoder bestätigt wird. Eine Beispielmethode zur Überprüfung auf Float-PCM im MediaFormat lautet wie folgt:

static boolean isPcmFloat(MediaFormat format) {
               return format.getInteger(MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_16BIT)
                   == AudioFormat.ENCODING_PCM_FLOAT;
             }

Um in einem kurzen Array einen Kanal eines Puffers zu extrahieren, der 16-Bit-Ganzzahl-Audiodaten mit Vorzeichen enthält, kann der folgende Code verwendet werden:

// Assumes the buffer PCM encoding is 16 bit.
             short[] getSamplesForChannel(MediaCodec codec, int bufferId, int channelIx) {
               ByteBuffer outputBuffer = codec.getOutputBuffer(bufferId);
               MediaFormat format = codec.getOutputFormat(bufferId);
               ShortBuffer samples = outputBuffer.order(ByteOrder.nativeOrder()).asShortBuffer();
               int numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
               if (channelIx &lt; 0 || channelIx &gt;= numChannels) {
                 return null;
               }
               short[] res = new short[samples.remaining() / numChannels];
               for (int i = 0; i &lt; res.length; ++i) {
                 res[i] = samples.get(i * numChannels + channelIx);
               }
               return res;
             }

<h4>Raw Video Buffers</h4>

Im ByteBuffer-Modus werden Videopuffer entsprechend ihrem MediaFormat#KEY_COLOR_FORMAT Farbformat angeordnet. Sie können die unterstützten Farbformate als Array von #getCodecInfo..MediaCodecInfo#getCapabilitiesForType getCapabilitiesForType(&hellip;)CodecCapabilities#colorFormats colorFormatsabrufen. Videocodecs können drei Arten von Farbformaten unterstützen: <ul><li><strong>natives Raw-Videoformat:</strong> Dies ist gekennzeichnet durch CodecCapabilities#COLOR_FormatSurface und kann mit einem Eingabe- oder Ausgabe-Surface verwendet werden.</li><li strong>><flexible YUV-Puffer</strong> (zCodecCapabilities#COLOR_FormatYUV420Flexible. B. ): Diese können mit einem Ein-/Ausgabe-Surface sowie im ByteBuffer-Modus mithilfe/#getInputImage getInput#getOutputImage OutputImage(int) von verwendet werden.</li><li><strong>andere, spezifische Formate:</strong> Diese werden normalerweise nur im ByteBuffer-Modus unterstützt. Einige Farbformate sind herstellerspezifisch. Andere sind in CodecCapabilitiesdefiniert. Für Farbformate, die einem flexiblen Format entsprechen, können Sie weiterhin verwenden #getInputImage getInput/#getOutputImage OutputImage(int).</li></ul>

Seit unterstützen alle Videocodecs flexible YUV 4:2:0-Puffer android.os.Build.VERSION_CODES#LOLLIPOP_MR1.

<h4>Zugriff auf Raw-Video-ByteBuffers auf älteren Geräten</h4>

android.os.Build.VERSION_CODES#LOLLIPOP Vor und Image unterstützung müssen Sie die Werte für das MediaFormat#KEY_STRIDE Ausgabeformat und MediaFormat#KEY_SLICE_HEIGHT verwenden, um das Layout der Rohausgabepuffer zu verstehen. <p class=note> Beachten Sie, dass auf einigen Geräten die Slicehöhe als 0 angekündigt wird. Dies kann entweder bedeuten, dass die Slicehöhe mit der Framehöhe identisch ist, oder dass die Slicehöhe die Framehöhe ist, die an einem Bestimmten Wert ausgerichtet ist (normalerweise eine Leistung von 2). Leider gibt es in diesem Fall keine standard- und einfache Möglichkeit, die tatsächliche Slicehöhe zu ermitteln. Darüber hinaus wird der vertikale Schritt der U Ebene in planaren Formaten ebenfalls nicht angegeben oder definiert, obwohl es in der Regel die Hälfte der Slicehöhe ist.

Die MediaFormat#KEY_WIDTH Tasten und MediaFormat#KEY_HEIGHT geben die Größe der Videoframes an. Für die meisten Encondings belegt das Video (Bild) jedoch nur einen Teil des Videoframes. Dies wird durch das "Zuschneiderechteck" dargestellt.

Sie müssen die folgenden Schlüssel verwenden, um das Zuschneiderechteck von Rohausgabebildern aus dem #getOutputFormat Ausgabeformat abzurufen. Wenn diese Tasten nicht vorhanden sind, belegt das Video den gesamten Videoframe. Das Zuschneiderechteck wird im Kontext des Ausgaberahmens <vor>< dem Anwenden> von MediaFormat#KEY_ROTATION Drehung verstanden. <table style="width: 0%"><thead><tr><th>Format key</th><type></th<>th th>description</th></tr></thead<>tbody<>tr<>tdMediaFormat#KEY_CROP_LEFT<>/td<>td>Integer</td<>td>Die linke Koordinate (x) des Zuschneiderechtecks</td></tr><tr tr><td><MediaFormat#KEY_CROP_TOP/td td<>>Integer/< td><td>Die obere Koordinate (y) des Zuschneiderechtecks</td></tr><tr<>tdMediaFormat#KEY_CROP_RIGHT<>/td><td>Integer</td<>td>Die rechte Koordinate (x) <stark>MINUS 1</strong> des Zuschneiderechtecks</td<>/tr><tr<>td<MediaFormat#KEY_CROP_BOTTOM>/td><td<> Integer/td<>td>Die untere Koordinate (y) <stark>MINUS 1</strong> des Zuschneiderechtecks</td></tr><tr><td colspan=3> Die rechte und die untere Koordinate können als Koordinaten der rechts gültigsten Spalte bzw. der untersten gültigen Zeile des zugeschnittenen Ausgabebilds verstanden werden. </td></tr></tbody></table>

Die Größe des Videoframes (vor der Drehung) kann als solche berechnet werden:

MediaFormat format = decoder.getOutputFormat(&hellip;);
             int width = format.getInteger(MediaFormat.KEY_WIDTH);
             if (format.containsKey(MediaFormat.KEY_CROP_LEFT)
                     && format.containsKey(MediaFormat.KEY_CROP_RIGHT)) {
                 width = format.getInteger(MediaFormat.KEY_CROP_RIGHT) + 1
                             - format.getInteger(MediaFormat.KEY_CROP_LEFT);
             }
             int height = format.getInteger(MediaFormat.KEY_HEIGHT);
             if (format.containsKey(MediaFormat.KEY_CROP_TOP)
                     && format.containsKey(MediaFormat.KEY_CROP_BOTTOM)) {
                 height = format.getInteger(MediaFormat.KEY_CROP_BOTTOM) + 1
                              - format.getInteger(MediaFormat.KEY_CROP_TOP);
             }

<p class=note> Beachten Sie auch, dass die Bedeutung von BufferInfo#offset BufferInfo.offset nicht geräteübergreifend konsistent war. Auf einigen Geräten zeigte der Offset auf das obere linke Pixel des Zuschneiderechtecks, während er auf den meisten Geräten auf das pixel oben links des gesamten Frames zeigte.

<h3>States</h3>

Während seiner Lebensdauer ist ein Codec konzeptionell in einem von drei Zuständen vorhanden: Stopped, Executing oder Released. Der kollektive Zustand Beendet ist eigentlich die Verkettung von drei Zuständen: Nicht initialisiert, Konfiguriert und Fehler, während der Zustand "Executing" konzeptionell drei Unterzustände durchläuft: Geleert, Ausgeführt und End-of-Stream.

<center><img src=". /.. /.. /images/media/mediacodec_states.svg" style="width: 519px; height: 356px" alt="MediaCodec state diagram"></center>

Wenn Sie einen Codec mit einer der Factorymethoden erstellen, befindet sich der Codec im Nicht initialisierten Zustand. Zuerst müssen Sie sie über #configure configure(&hellip;)konfigurieren, wodurch sie in den Zustand Konfiguriert versetzt wird, und rufen Sie dann auf #start , um sie in den Zustand Executing zu verschieben. In diesem Zustand können Sie Daten über die oben beschriebene Manipulation der Pufferwarteschlange verarbeiten.

Der Zustand "Executing" weist drei Unterzustände auf: Geleert, Ausgeführt und Ende des Datenstroms. Unmittelbar nachdem #start sich der Codec im Unterzustand Geleert befindet, in dem er alle Puffer enthält. Sobald der erste Eingabepuffer aus der Warteschlange entfernt wird, wechselt der Codec in den Unterzustand Wird ausgeführt, wo er den größten Teil seiner Lebensdauer verbringt. Wenn Sie einen Eingabepuffer mit dem #BUFFER_FLAG_END_OF_STREAM-Endpunktmarker in die Warteschlange stellen, wechselt der Codec in den Unterzustand "Stream end-of-Stream". In diesem Zustand akzeptiert der Codec keine weiteren Eingabepuffer mehr, generiert aber weiterhin Ausgabepuffer, bis das Ende des Datenstroms für die Ausgabe erreicht ist. Bei Decodern können Sie jederzeit in den Unterzustand Geleert zurückwechseln, während Sie sich mit im Zustand "Ausführen" befinden #flush. <p class=note><strong>Hinweis:</strong> Der Wechsel zum Zustand "Geleert" wird nur für Decoder unterstützt und funktioniert möglicherweise nicht für Encoder (das Verhalten ist undefiniert).

Rufen Sie auf #stop , um den Codec in den Nicht initialisierten Zustand zurückzugeben, wobei er möglicherweise erneut konfiguriert werden kann. Wenn Sie mit der Verwendung eines Codecs fertig sind, müssen Sie ihn freigeben, indem Sie aufrufen #release.

In seltenen Fällen tritt für den Codec möglicherweise ein Fehler auf und wechselt in den Fehlerzustand. Dies wird mithilfe eines ungültigen Rückgabewerts aus einem Warteschlangenvorgang oder manchmal über eine Ausnahme kommuniziert. Rufen Sie auf #reset , um den Codec wieder nutzbar zu machen. Sie können ihn aus einem beliebigen Zustand aufrufen, um den Codec zurück in den Nicht initialisierten Zustand zu verschieben. Andernfalls rufen Sie auf #release , um in den Terminalzustand Freigegeben zu wechseln.

<h3>Creation</h3>

Verwenden Sie MediaCodecList , um einen MediaCodec für eine bestimmte MediaFormatzu erstellen. Beim Decodieren einer Datei oder eines Streams können Sie das gewünschte Format von MediaExtractor#getTrackFormat MediaExtractor.getTrackFormatabrufen. Fügen Sie alle spezifischen Features ein, die Sie mit MediaFormat#setFeatureEnabled MediaFormat.setFeatureEnabledhinzufügen möchten, und rufen MediaCodecList#findDecoderForFormat MediaCodecList.findDecoderForFormat Sie dann auf, um den Namen eines Codecs abzurufen, der dieses bestimmte Medienformat verarbeiten kann. Erstellen Sie schließlich den Codec mit #createByCodecName. <p class=note><strong>Hinweis:</strong> Auf android.os.Build.VERSION_CODES#LOLLIPOPdarf das Format für MediaCodecList.findDecoder/EncoderForFormat keine MediaFormat#KEY_FRAME_RATE Bildfrequenz enthalten. Verwenden Sie format.setString(MediaFormat.KEY_FRAME_RATE, null) , um alle vorhandenen Einstellungen für die Bildfrequenz im Format zu löschen.

Sie können den bevorzugten Codec für einen bestimmten MIME-Typ auch mit #createDecoderByType createDecoder/#createEncoderByType EncoderByType(String)erstellen. Dies kann jedoch nicht zum Einfügen von Features verwendet werden und kann einen Codec erstellen, der das spezifische gewünschte Medienformat nicht verarbeiten kann.

<h4>Erstellen sicherer Decoder</h4>

In Versionen und früheren Versionen android.os.Build.VERSION_CODES#KITKAT_WATCH sind sichere Codecs möglicherweise nicht in MediaCodecListaufgeführt, aber möglicherweise noch auf dem System verfügbar. Sichere Codecs, die vorhanden sind, können nur anhand des Namens instanziiert werden, indem an den Namen eines regulären Codecs angefügt ".secure" wird (der Name aller sicheren Codecs muss mit ".secure"enden) #createByCodecName wird ausgelöst, IOException wenn der Codec nicht auf dem System vorhanden ist.

Von android.os.Build.VERSION_CODES#LOLLIPOP nun an sollten Sie das CodecCapabilities#FEATURE_SecurePlayback Feature im Medienformat verwenden, um einen sicheren Decoder zu erstellen.

<h3>Initialisierung</h3>

Nach dem Erstellen des Codecs können Sie einen Rückruf mit #setCallback setCallback festlegen, wenn Sie Daten asynchron verarbeiten möchten. Anschließend #configure den Codec mit dem spezifischen Medienformat konfigurieren. In diesem Fall können Sie die Ausgabe Surface für Videoproduzenten – Codecs angeben, die Videorohdaten generieren (z. B. Videodecoder). Dies ist auch der Fall, wenn Sie die Entschlüsselungsparameter für sichere Codecs festlegen können (siehe MediaCrypto). Da einige Codecs in mehreren Modi betrieben werden können, müssen Sie angeben, ob sie als Decoder oder Encoder funktionieren sollen.

Seit android.os.Build.VERSION_CODES#LOLLIPOPkönnen Sie das resultierende Eingabe- und Ausgabeformat im Zustand Konfiguriert abfragen. Sie können dies verwenden, um die resultierende Konfiguration zu überprüfen, z. B. Farbformate, bevor Sie den Codec starten.

Wenn Sie Rohdateneingabe-Videopuffer nativ mit einem Videoconsumer &ndash verarbeiten möchten; ein Codec, der unformatierte Videoeingaben verarbeitet, z. B. ein Videoencoder – Erstellen Sie mit nach der Konfiguration ein Ziel-Surface für Ihre Eingabedaten #createInputSurface . Alternativ können Sie den Codec so einrichten, dass eine zuvor erstellte #createPersistentInputSurface persistente Eingabeoberfläche verwendet wird, indem Sie aufrufen #setInputSurface.

<h4 id=CSD>"CSD">Codec-spezifische Daten</h4>

Einige Formate, insbesondere AAC-Audio und MPEG4-, H.264- und H.265-Videoformate erfordern, dass den tatsächlichen Daten eine Reihe von Puffern mit Setupdaten oder Codec-spezifischen Daten vorangestellt wird. Bei der Verarbeitung solcher komprimierten Formate müssen diese Daten nach #start und vor allen Framedaten an den Codec übermittelt werden. Solche Daten müssen mit dem Flag #BUFFER_FLAG_CODEC_CONFIG in einem Aufruf von #queueInputBuffer queueInputBuffergekennzeichnet werden.

Codecspezifische Daten können auch in das Format einbezogen werden, #configure configure das in ByteBuffer-Einträgen mit den Schlüsseln "csd-0", "csd-1" usw. übergeben wird. Diese Schlüssel sind immer in der Spur MediaFormat enthalten, die MediaExtractor#getTrackFormat MediaExtractorvon abgerufen wird. Codec-spezifische Daten im Format werden automatisch an den Codec #startübermittelt. Sie>< müssen diese Daten nicht<> explizit übermitteln. Wenn das Format keine Codec-spezifischen Daten enthält, können Sie es mit der angegebenen Anzahl von Puffern in der richtigen Reihenfolge gemäß den Formatanforderungen übermitteln. Im Fall von H.264 AVC können Sie auch alle Codec-spezifischen Daten verketten und als einzelnen Codec-Config-Puffer übermitteln.

Android verwendet die folgenden codecspezifischen Datenpuffer. Diese müssen auch im Spurformat für die ordnungsgemäße MediaMuxer Streckenkonfiguration festgelegt werden. Jeder Parametersatz und die mit (<sup>*</sup>) gekennzeichneten Codec-spezifischen Datenabschnitte müssen mit einem Startcode beginnen "\x00\x00\x00\x01".

<style>td. NA { background: #ccc; } .mid > tr > td { vertical-align: middle; }</style><table><thead><th>Format</th<>>CSD-Puffer #0</th><th>CSD-Puffer #1</th<>th>CSD-Puffer #2</th></thead<>tbody class=mid><tr<>td>AAC</td td<>>Decoder-spezifische Informationen aus ESDS<sup>*</sup></td td><td class=NA>Not Used</td td><class=NA>Not Used</Td></tr>tr td><>VORBIS</td td>><Identification header</td td>><Setup header</td td><td class=NA>Not Used</td></tr<>tr tr><td>OPUS</td td<>td>Identification header</td td>><Pre-skip in nanosecs<br> (unsigned 64-Bit ByteOrder#nativeOrder native order integer.)<<br> Dadurch wird der Pre-Skip-Wert im Identifikationsheader überschrieben.</td><td>Seek Pre-roll in nanosecs<br> (unsigned 64-Bit ByteOrder#nativeOrder native-order integer.)</td></tr><tr td>><FLAC</td><td>"fLaC", der FLAC-Streammarker in ASCII,< br> gefolgt vom STREAMINFO-Block (der obligatorische Metadatenblock),<br> optional gefolgt von einer beliebigen Anzahl anderer Metadatenblöcke</td td><class=NA>Not Used</td td class=NA Not Used/td<>td class=NA>Not Used</td<>/tr<>trd><>MPEG-4</td><Td>Decoderspezifische Informationen aus ESDS sup*/sup></td td><td class=NA>Not Used</td td<>class=NA>Not Used</td></tr<>tr trd>><H.264 AVC</td td><td>SPS (Sequence Parameter Sets<sup>*</sup>)</td td><td>PPS (Picture Parameter Sets<sup>*</sup>)</td td<>td<>< class=NA>Not Used</td></tr><tr tr td><>H.265 HEVC</td td><>VPS (Video Parameter Sets<sup>*</sup>) +<br> SPS (Sequence Parameter Sets<sup>*</sup>) +<br> PPS (Picture Parameter Sets<sup>*</sup>)</td td><td class=NA>Not Used</td td<>class=NA>Not Used/< td></tr><tr><td>VP9</td><td>VP9 CodecPrivate Data (optional)</td td<>td class=NA>Not Used</td td<>class=NA>Not Used</td></tr><tr td>><AV1</td td><>AV1 AV1CodecConfigurationRecord Data (optional) </td td<>td class=NA>Not Used</td><td class=NA>Not Used</td></tr></tbody></table>

<p class=note><strong>Hinweis:</strong> muss beachtet werden, wenn der Codec sofort oder kurz nach dem Start geleert wird, bevor eine Änderung des Ausgabepuffers oder Ausgabeformats zurückgegeben wurde, da die codecspezifischen Daten während der Leerung möglicherweise verloren gehen. Sie müssen die Daten mithilfe von Puffern erneut übermitteln, die mit #BUFFER_FLAG_CODEC_CONFIG gekennzeichnet sind, nachdem eine solche Leerung erfolgt ist, um einen ordnungsgemäßen Codecbetrieb sicherzustellen.

Encoder (oder Codecs, die komprimierte Daten generieren) erstellen und geben die codecspezifischen Daten vor jedem gültigen Ausgabepuffer in Ausgabepuffern zurück, die mit dem Flag #BUFFER_FLAG_CODEC_CONFIG codec-config gekennzeichnet sind. Puffer, die Codec-spezifische Daten enthalten, weisen keine aussagekräftigen Zeitstempel auf.

<h3>Datenverarbeitung</h3>

Jeder Codec verwaltet einen Satz von Eingabe- und Ausgabepuffern, auf die in API-Aufrufen von einer Puffer-ID verwiesen wird. Nach einem erfolgreichen Aufruf #start des Clients "besitzt" weder Eingabe- noch Ausgabepuffer. Rufen Sie #dequeueInputBuffer dequeueInput/#dequeueOutputBuffer OutputBuffer(&hellip;) im synchronen Modus auf, um den Besitz eines Eingabe- oder Ausgabepuffers aus dem Codec abzurufen (den Besitz von zu erhalten). Im asynchronen Modus erhalten Sie automatisch verfügbare Puffer über die Callback#onInputBufferAvailable MediaCodec.Callback.onInput/Callback#onOutputBufferAvailable OutputBufferAvailable(&hellip;) Rückrufe.

Wenn Sie einen Eingabepuffer abrufen, füllen Sie ihn mit Daten aus, und übermitteln Sie sie mithilfe #queueInputBuffer queueInputBuffer &ndash oder #queueSecureInputBuffer queueSecureInputBuffer bei Verwendung der Entschlüsselung an den Codec. Übermitteln Sie nicht mehrere Eingabepuffer mit dem gleichen Zeitstempel (es sei denn, es handelt sich um Codec-spezifische Daten, die als solche gekennzeichnet sind).

Der Codec gibt wiederum einen schreibgeschützten Ausgabepuffer über den Callback#onOutputBufferAvailable onOutputBufferAvailable Rückruf im asynchronen Modus oder als Reaktion auf einen #dequeueOutputBuffer dequeueOutputBuffer Aufruf im synchronen Modus zurück. Rufen Sie nach der Verarbeitung des Ausgabepuffers eine der #releaseOutputBuffer releaseOutputBuffer Methoden auf, um den Puffer an den Codec zurückzugeben.

Sie müssen Puffer zwar nicht sofort erneut an den Codec übermitteln/freigeben, aber das Halten an Eingabe- und/oder Ausgabepuffern kann den Codec zum Stillstand kommen, und dieses Verhalten ist geräteabhängig. <strong>Insbesondere ist es möglich, dass ein Codec beim Generieren von Ausgabepuffern anhalten kann, bis <em>all</em> ausstehende Puffer freigegeben/erneut übermittelt wurden.</strong> Versuchen Sie daher, so wenig wie möglich an verfügbaren Puffern festzuhalten.

Abhängig von der API-Version können Sie Daten auf drei Arten verarbeiten: <Table><thead><tr><th>Processing Mode</th<>th>API-Version <= 20<br>Jelly Bean/KitKat</th><th>API-Version >= 21<br>Lollipop und höher</th></tr<>/thead<>tbody><tr><td>Synchrone API mit Pufferarrays</td td<>>Supported</tdtd>Veraltet</td></tr><tr tr><td>Synchrone API using buffers</td td<>class=NA>Not Available</td td td>><Supported</td></tr><tr td<>>Asynchrone API using buffers</td td><class=NA>Not Available</td td><Supported<>/td></tr></tbody></table ><>

<h4>Asynchrone Verarbeitung mithilfe von Puffern</h4>

Da android.os.Build.VERSION_CODES#LOLLIPOPist die bevorzugte Methode das asynchrone Verarbeiten von Daten durch Festlegen eines Rückrufs vor dem Aufrufen #configure configurevon . Der asynchrone Modus ändert die Zustandsübergänge geringfügig, da Sie nach #flush aufrufen #start müssen, um den Codec in den Unterzustand Ausführen zu überstellen und mit dem Empfangen von Eingabepuffern zu beginnen. Auf ähnliche Weise wird beim ersten Aufruf start des Codecs direkt in den Unterzustand Ausführen verschoben und die Übergabe verfügbarer Eingabepuffer über den Rückruf gestartet.

<center><img src=".. /.. /.. /images/media/mediacodec_async_states.svg" style="width: 516px; height: 353px" alt="MediaCodec state diagram for a asynchron operation"></center>

MediaCodec wird in der Regel wie folgt im asynchronen Modus verwendet:

MediaCodec codec = MediaCodec.createByCodecName(name);
             MediaFormat mOutputFormat; // member variable
             codec.setCallback(new MediaCodec.Callback() {
               {@literal @Override}
               void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
                 ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
                 // fill inputBuffer with valid data
                 &hellip;
                 codec.queueInputBuffer(inputBufferId, &hellip;);
               }

               {@literal @Override}
               void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, &hellip;) {
                 ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
                 MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
                 // bufferFormat is equivalent to mOutputFormat
                 // outputBuffer is ready to be processed or rendered.
                 &hellip;
                 codec.releaseOutputBuffer(outputBufferId, &hellip;);
               }

               {@literal @Override}
               void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
                 // Subsequent data will conform to new format.
                 // Can ignore if using getOutputFormat(outputBufferId)
                 mOutputFormat = format; // option B
               }

               {@literal @Override}
               void onError(&hellip;) {
                 &hellip;
               }
               {@literal @Override}
               void onCryptoError(&hellip;) {
                 &hellip;
               }
             });
             codec.configure(format, &hellip;);
             mOutputFormat = codec.getOutputFormat(); // option B
             codec.start();
             // wait for processing to complete
             codec.stop();
             codec.release();

<h4>Synchrone Verarbeitung mithilfe von Puffern</h4>

Da android.os.Build.VERSION_CODES#LOLLIPOPsollten Sie Eingabe- und Ausgabepuffer mit #getInputBuffer getInput/#getOutputBuffer OutputBuffer(int) und/oder #getInputImage getInput/#getOutputImage OutputImage(int) abrufen, auch wenn sie den Codec im synchronen Modus verwenden. Dies ermöglicht bestimmte Optimierungen durch das Framework, z.B. bei der Verarbeitung dynamischer Inhalte. Diese Optimierung ist deaktiviert, wenn Sie aufrufen #getInputBuffers getInput/#getOutputBuffers OutputBuffers().

<p class=note><strong>Hinweis:</strong> mischen Sie die Methoden der Verwendung von Puffern und Pufferarrays nicht gleichzeitig. Rufen Sie getInput/OutputBuffers insbesondere nur direkt nach #start oder nach dem Dequeuieren einer Ausgabepuffer-ID mit dem Wert von auf.#INFO_OUTPUT_FORMAT_CHANGED

MediaCodec wird in der Regel wie folgt im synchronen Modus verwendet:

MediaCodec codec = MediaCodec.createByCodecName(name);
             codec.configure(format, &hellip;);
             MediaFormat outputFormat = codec.getOutputFormat(); // option B
             codec.start();
             for (;;) {
               int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
               if (inputBufferId &gt;= 0) {
                 ByteBuffer inputBuffer = codec.getInputBuffer(&hellip;);
                 // fill inputBuffer with valid data
                 &hellip;
                 codec.queueInputBuffer(inputBufferId, &hellip;);
               }
               int outputBufferId = codec.dequeueOutputBuffer(&hellip;);
               if (outputBufferId &gt;= 0) {
                 ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
                 MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
                 // bufferFormat is identical to outputFormat
                 // outputBuffer is ready to be processed or rendered.
                 &hellip;
                 codec.releaseOutputBuffer(outputBufferId, &hellip;);
               } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                 // Subsequent data will conform to new format.
                 // Can ignore if using getOutputFormat(outputBufferId)
                 outputFormat = codec.getOutputFormat(); // option B
               }
             }
             codec.stop();
             codec.release();

<h4>Synchrone Verarbeitung mithilfe von Pufferarrays (veraltet)</h4>

In Versionen android.os.Build.VERSION_CODES#KITKAT_WATCH und früher werden die Eingabe- und Ausgabepuffer durch die ByteBuffer[] Arrays dargestellt. Rufen Sie nach einem erfolgreichen Aufruf von #startdie Pufferarrays mit #getInputBuffers getInput/#getOutputBuffers OutputBuffers()ab. Verwenden Sie die Puffer-ID-s als Indizes in diesen Arrays (wenn sie nicht negativ sind), wie im folgenden Beispiel veranschaulicht. Beachten Sie, dass es keine inhärente Korrelation zwischen der Größe der Arrays und der Anzahl der vom System verwendeten Eingabe- und Ausgabepuffer gibt, obwohl die Arraygröße eine Obergrenze bietet.

MediaCodec codec = MediaCodec.createByCodecName(name);
             codec.configure(format, &hellip;);
             codec.start();
             ByteBuffer[] inputBuffers = codec.getInputBuffers();
             ByteBuffer[] outputBuffers = codec.getOutputBuffers();
             for (;;) {
               int inputBufferId = codec.dequeueInputBuffer(&hellip;);
               if (inputBufferId &gt;= 0) {
                 // fill inputBuffers[inputBufferId] with valid data
                 &hellip;
                 codec.queueInputBuffer(inputBufferId, &hellip;);
               }
               int outputBufferId = codec.dequeueOutputBuffer(&hellip;);
               if (outputBufferId &gt;= 0) {
                 // outputBuffers[outputBufferId] is ready to be processed or rendered.
                 &hellip;
                 codec.releaseOutputBuffer(outputBufferId, &hellip;);
               } else if (outputBufferId == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                 outputBuffers = codec.getOutputBuffers();
               } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                 // Subsequent data will conform to new format.
                 MediaFormat format = codec.getOutputFormat();
               }
             }
             codec.stop();
             codec.release();

<h4>Verarbeitung am Ende des Streams</h4>

Wenn Sie das Ende der Eingabedaten erreichen, müssen Sie sie dem Codec signalisieren, indem Sie das #BUFFER_FLAG_END_OF_STREAM Flag im Aufruf von angeben #queueInputBuffer queueInputBuffer. Dazu können Sie den letzten gültigen Eingabepuffer verwenden oder einen zusätzlichen leeren Eingabepuffer mit festgelegtem Flag zum Ende des Datenstroms übermitteln. Bei Verwendung eines leeren Puffers wird der Zeitstempel ignoriert.

Der Codec gibt weiterhin Ausgabepuffer zurück, bis er schließlich das Ende des Ausgabedatenstroms signalisiert, indem er dasselbe Ende-of-Stream-Flag im BufferInfo Set in #dequeueOutputBuffer dequeueOutputBuffer angibt oder über Callback#onOutputBufferAvailable onOutputBufferAvailablezurückgegeben wird. Dies kann für den letzten gültigen Ausgabepuffer oder für einen leeren Puffer nach dem letzten gültigen Ausgabepuffer festgelegt werden. Der Zeitstempel eines solchen leeren Puffers sollte ignoriert werden.

Übermitteln Sie keine zusätzlichen Eingabepuffer, nachdem sie das Ende des Eingabedatenstroms signalisiert haben, es sei denn, der Codec wurde geleert oder beendet und neu gestartet.

<h4>Verwenden einer Ausgabeoberfläche</h4>

Die Datenverarbeitung ist bei Verwendung einer Ausgabe Surfacenahezu identisch mit dem ByteBuffer-Modus. Auf die Ausgabepuffer kann jedoch nicht zugegriffen werden und werden als null Werte dargestellt. #getOutputBuffer getOutputBuffer/#getOutputImage Image(int) Beispielsweise wird ein Array zurückgegebennull, #getOutputBuffers das nur null-s enthält.

Wenn Sie ein Ausgabe-Surface verwenden, können Sie auswählen, ob jeder Ausgabepuffer auf der Oberfläche gerendert werden soll oder nicht. Sie haben drei Optionen: <ul><li><strong>Den Puffer nicht rendern:</strong> Aufrufen #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, false).</li><li strong>><Rendern Sie den Puffer mit dem Standardzeitstempel:</strong> Rufen Sie auf #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, true).</li><li strong>><Rendern Sie den Puffer mit einem bestimmten Zeitstempel:</strong> Rufen Sie auf #releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp).</li></ul>

Da android.os.Build.VERSION_CODES#Mist der Standardzeitstempel der BufferInfo#presentationTimeUs-Präsentationszeitstempel des Puffers (konvertiert in Nanosekunden). Sie wurde zuvor nicht definiert.

android.os.Build.VERSION_CODES#MAußerdem können Sie die Surface-Ausgabe mit #setOutputSurface setOutputSurfacedynamisch ändern.

Beim Rendern der Ausgabe auf einem Surface kann das Surface so konfiguriert werden, dass übermäßige Frames (die vom Surface nicht rechtzeitig genutzt werden) gelöscht werden. Oder es kann so konfiguriert sein, dass keine übermäßigen Frames gelöscht werden. Wenn das Surface im letztgenannten Modus die Ausgabeframes nicht schnell genug verbraucht, blockiert es schließlich den Decoder. android.os.Build.VERSION_CODES#Q Zuvor war das genaue Verhalten nicht definiert, mit der Ausnahme, dass Ansichtsoberflächen (SurfaceView oder TextureView) immer übermäßige Frames gelöscht haben. Da android.os.Build.VERSION_CODES#Q das Standardverhalten darin besteht, übermäßige Frames zu löschen. Anwendungen können dieses Verhalten für Nicht-View-Oberflächen (z. B. ImageReader oder SurfaceTexture) deaktivieren, indem sie das SDK android.os.Build.VERSION_CODES#Q als Ziel festlegen und den Schlüssel MediaFormat#KEY_ALLOW_FRAME_DROP auf 0 im Konfigurationsformat festlegen.

<h4-Transformationen>beim Rendern auf Surface</h4>

Wenn der Codec im Surface-Modus konfiguriert ist, werden alle Zuschneiderechtecke, MediaFormat#KEY_ROTATION Rotation und #setVideoScalingMode Videoskalierungsmodus automatisch mit einer Ausnahme angewendet: <p class=note> Vor der android.os.Build.VERSION_CODES#M Veröffentlichung haben Softwaredecoder die Drehung beim Rendern auf ein Surface möglicherweise nicht angewendet. Leider gibt es keine standard- und einfache Möglichkeit, Softwaredecoder zu identifizieren, oder wenn sie die Drehung anders anwenden, als es auszuprobieren.

Es gibt auch einige Einschränkungen. <p class=note> Beachten Sie, dass das Pixelseitenverhältnis beim Anzeigen der Ausgabe auf dem Surface nicht berücksichtigt wird. Dies bedeutet, dass Sie bei Verwendung #VIDEO_SCALING_MODE_SCALE_TO_FIT des Modus das Ausgabe-Surface so positionieren müssen, dass es das richtige endgültige Seitenverhältnis der Anzeige aufweist. Umgekehrt können Sie den Modus nur für Inhalte mit quadratischen Pixeln (Pixelseitenverhältnis oder 1:1) verwenden #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING . <p class=note> Beachten Sie außerdem, #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING dass der android.os.Build.VERSION_CODES#N Modus zum Release möglicherweise nicht ordnungsgemäß für um 90 oder 270 Grad gedrehte Videos funktioniert. <p class=note> Beachten Sie beim Festlegen des Videoskalierungsmodus, dass er nach jeder Änderung der Ausgabepuffer zurückgesetzt werden muss. Da das #INFO_OUTPUT_BUFFERS_CHANGED Ereignis veraltet ist, können Sie dies nach jeder Änderung des Ausgabeformats tun.

<h4>Verwenden einer Eingabeoberfläche</h4>

Wenn Sie ein Eingabe-Surface verwenden, sind keine Eingabepuffer verfügbar, da Puffer automatisch von der Eingabeoberfläche an den Codec übergeben werden. Beim Aufrufen #dequeueInputBuffer dequeueInputBuffer wird ein IllegalStateExceptionausgelöst, und #getInputBuffers es wird ein falsches ByteBuffer[] Array zurückgegeben, in das <strong>NICHT</strong> geschrieben werden DARF.

Rufen Sie #signalEndOfInputStream auf, um das Ende des Datenstroms zu signalisieren. Die Eingabeoberfläche beendet die Übermittlung von Daten an den Codec unmittelbar nach diesem Aufruf.

<h3>Sucht & Unterstützung für< adaptive Wiedergabe/h3>

Videodecoder (und im Allgemeinen Codecs, die komprimierte Videodaten nutzen) verhalten sich in Bezug auf Such- und Formatänderungen unterschiedlich, unabhängig davon, ob sie unterstützen und für die adaptive Wiedergabe konfiguriert sind. Sie können überprüfen, ob ein Decoder CodecCapabilities#FEATURE_AdaptivePlayback adaptive Wiedergabe über CodecCapabilities#isFeatureSupported CodecCapabilities.isFeatureSupported(String)unterstützt. Die Unterstützung der adaptiven Wiedergabe für Videodecoder ist nur aktiviert, wenn Sie den Codec so konfigurieren, dass er auf einen Surfacedecodiert wird.

<h4 id=KeyFrames>"KeyFrames">Stream Boundary and KeyFrames</h4>

Es ist wichtig, dass die Eingabedaten nach #start oder #flush an einer geeigneten Streamgrenze beginnen: Der erste Frame muss ein Keyframe sein. Ein <em>Keyframe</em> kann vollständig von selbst decodiert werden (für die meisten Codecs bedeutet dies ein I-Frame), und keine Frames, die nach einem Keyframe angezeigt werden sollen, beziehen sich auf Frames vor dem Keyframe.

In der folgenden Tabelle sind die geeigneten Keyframes für verschiedene Videoformate zusammengefasst. <table><thead><tr><th>Format</th<>th th>Geeignete Keyframe</th></tr></thead<>tbody class=mid<>tr<>td>VP9/VP8</td td<>>ein geeigneter Intraframe, bei dem keine nachfolgenden Frames auf Frames vor diesem Frame verweisen.<br>(Es gibt keinen spezifischen Namen für einen solchen Keyframe.)</td></tr><tr><td>H.265 HEVC</td td<>td>IDR or CRA</td<>/tr<>tr trd<>>H.264 AVC</td><td td>IDR</td<>/tr<>tr<>td>MPEG-4<br>H.263<br>MPEG-2</td td<>>ein geeigneter I-Frame, bei dem keine nachfolgenden Frames auf Frames vor diesem Frame verweisen.<br>(Es gibt keinen spezifischen Namen für einen solchen Keyframe.)</td></tr></tbody></table>

<h4>Für Decoder, die keine adaptive Wiedergabe unterstützen (auch wenn sie nicht auf einem Surface decodiert werden)</h4>

Um mit der Decodierung von Daten zu beginnen, die nicht an zuvor übermittelte Daten (d. h. nach einer Suche) angrenzen, müssen<> Sie <den Decoder stark>leeren. Da alle Ausgabepuffer am Punkt der Leerung sofort widerrufen werden, sollten Sie zuerst signalisieren und dann auf das Ende des Datenstroms warten, bevor Sie aufrufen flush. Es ist wichtig, dass die Eingabedaten nach einer Spülung an einer geeigneten Streamgrenze/keyframe beginnen. <p class=note>strong Hinweis:</strong> Das Format der Daten, die nach einer Leerung übermittelt werden, darf sich nicht ändern; #flush unterstützt keine Formatbrüche. Dafür ist ein vollständiger#start - - #stop#configure configure(&hellip;) Zyklus erforderlich.><

<p class=note><strong>Beachten Sie außerdem:</strong> , wenn Sie den Codec zu früh nach #start &ndash leeren. Im Allgemeinen, bevor die erste Ausgabepuffer- oder Ausgabeformatänderung &ndash empfangen wird. Sie müssen die Codec-spezifischen Daten erneut an den Codec übermitteln. Weitere Informationen finden Sie im Abschnitt codec-specific-data.

<h4>Für Decoder, die adaptive Wiedergabe< unterstützen und konfiguriert sind/h4>

Um mit der Entschlüsselung von Daten zu beginnen, die nicht an zuvor übermittelte Daten (d. h. nach einer Suche) angrenzen, ist <>es nicht erforderlich</em>, den Decoder zu leeren. Eingabedaten müssen jedoch nach der Diskontinuität an einer geeigneten Streamgrenze/einem geeigneten Schlüsselrahmen beginnen.

Bei einigen Videoformaten – nämlich H.264, H.265, VP8 und VP9 – ist es auch möglich, die Bildgröße oder konfiguration mid-stream zu ändern. Dazu müssen Sie die gesamten neuen Codec-spezifischen Konfigurationsdaten zusammen mit dem Keyframe in einen einzelnen Puffer (einschließlich aller Startcodes) packen und als <starken>regulären</starken> Eingabepuffer übermitteln.

Sie erhalten einen #INFO_OUTPUT_FORMAT_CHANGED Rückgabewert von #dequeueOutputBuffer dequeueOutputBuffer oder einen Callback#onOutputBufferAvailable onOutputFormatChanged Rückruf unmittelbar nach der Änderung der Bildgröße und bevor Frames mit der neuen Größe zurückgegeben wurden. <p class=note><strong>Hinweis:</strong> , genau wie bei codecspezifischen Daten, seien Sie vorsichtig, wenn Sie kurz nach dem Ändern der Bildgröße aufrufen #flush . Wenn Sie keine Bestätigung für die Änderung der Bildgröße erhalten haben, müssen Sie die Anforderung für die neue Bildgröße wiederholen.

<h3>Fehlerbehandlung</h3>

Die Factorymethoden #createByCodecName createByCodecName und #createDecoderByType createDecoder/#createEncoderByType EncoderByType lösen IOException bei Fehlern aus, die Sie abfangen oder deklarieren müssen, um zu übergeben. MediaCodec-Methoden lösen aus IllegalStateException , wenn die Methode aus einem Codeczustand aufgerufen wird, der dies nicht zulässt. Dies ist in der Regel auf eine falsche Anwendungs-API-Verwendung zurückzuführen. Methoden, die sichere Puffer enthalten, können auslösen CryptoException, was weitere Fehlerinformationen enthält, die von abgerufen werden CryptoException#getErrorCodekönnen.

Interne Codecfehler führen zu einem CodecException, was auf Medieninhaltebeschädigung, Hardwarefehler, Ressourcenauslastung usw. zurückzuführen sein kann, selbst wenn die Anwendung die API ordnungsgemäß verwendet. Die empfohlene Aktion beim Empfangen von CodecException kann durch Aufrufen CodecException#isRecoverable von und CodecException#isTransientbestimmt werden: <ul><li><strong>recoverable errors:</strong> If isRecoverable() returns true, then call #stop, #configure configure(&hellip;)and #start to recover.</li><li strong>><transient errors:</strong> Wenn isTransient() true zurückgegeben wird, sind Ressourcen vorübergehend nicht verfügbar, und die Methode kann zu einem späteren Zeitpunkt wiederholt werden.</li><li strong>><Schwerwiegende Fehler:</strong> Wenn sowohl als auch isTransient()isRecoverable() false zurückgegeben werden, ist der CodecException -Wert schwerwiegend, und der Codec muss #reset zurückgesetzt oder #release freigegeben werden.</li></ul>

isTransient() Sowohl als auch isRecoverable() geben nicht gleichzeitig true zurück.

<h2 id=History>"History">Valid API Calls and API History</h2>

In diesem Abschnitt werden die gültigen API-Aufrufe in jedem Zustand und der API-Verlauf der MediaCodec-Klasse zusammengefasst. Api-Versionsnummern finden Sie unter android.os.Build.VERSION_CODES.

<style> .api > tr > th, .api > tr > td { text-align: center; padding: 4px 4px; } .api > tr > th { vertical-align: bottom; } .api > tr > td { vertical-align: middle; } .sml > tr > th, .sml > tr > td { text-align: center; padding: 2px 4px; } .fn { text-align: left; } .fn > code > a { font: 14px/19px Roboto Condensed, sans-serif; } .deg45 { white-space: nowrap; background: none; border: none; vertical-align: bottom; width: 30px; Höhe: 83px; } .deg45 > div { transform: skew(-45deg, 0deg) translate(1px, -67px); transform-origin: unten links 0; width: 30px; height: 20px; } .deg45 > div > { border: 1px solid #ddd; background: #999; height: 90px; width: 42px; } .deg45 > div > div > div { transform: skew(45deg, 0deg) translate(-55px, 55px) rotate(-45deg); }</Stil>

<table align="right" style="width: 0%">thead<>tr><th>Symbol</th><th>Meaning</th></tr></thead><tbody class=sml><tr><td>●</td><td>Supported</td></tr<>tr td><>⁕</td td><td>Semantics changed</td></tr<>tr><td>○</td><td td>Experimentelle Unterstützung</td></tr><tr td><<>[ ]</td><td td>Deprecated</td></tr><tr><td>⎋</td><td>Eingeschränkt auf surface input mode</td></tr><tr><td>⎆</td><td>Restricted to surface output mode</td></tr><tr><td>▧</td><td>Restricted to ByteBuffer input mode</td></tr><tr tr><td>↩</td><td>Restricted to synchron mode/< td></tr><tr><td>⇄</td><td>Eingeschränkt auf asynchronen Modus</td></tr<>tr td>><( )</td td><td>Kann aufgerufen werden, sollte aber nicht</td></tr<>/tbody></table>

<table style="width: 100%;"><thead class=api><tr><th class=deg45><div><div style="background:#4285f4"><div>Uninitialized</div></><div></div/th<>class=deg45><div><div style="background:#f4b400"><div>Configured</div></><div/div></th><class=deg45><div><style="background:#e67c73"><div>Flushed</div><></div></th><class=deg45><div><div style="background:#0f9d58"><div>Running</div><></div></th><class=deg45><div><div style="background:#f7cb4d"><div>End of Stream</div><></div/div></th><class=deg45><div><div style="background:#db4437"><div>Error</div><></div></th><th class=deg45><div><div style="background:#666"div>><Released</div></div></div></th>><</th<>th/th colspan="8">SDK Version</th<>/tr<>tr<>th colspan="7">State</>><th th>><< th 16/th>><17<</th>><18</th>><19</th><>th 20/th<>>21<</th><>22</th<>>23</th<>/tr<>/thead><tbody class=api><tr><td></td><td></td><td td></td><td></td><td></td><td></td<>td td></td<>td class=fn><#createByCodecName createByCodecName/td><td>●</td td><td>●</td><td>●</td><td td>●</td<>td>●</td<>td td>●</td><td td>●</td<>t●<<>d td>/tr><tr td<>></td<>td></td><td td></td<<>>td>< td></td td td td/td><><td td td><></td><td class=fn>#createDecoderByType createDecoderByType</td><td td>●</td<>td>●</td<>td td>●</td><td td>●</td><td td>●</td<>td td>●</td td<>td>●</td t●<d<>td> td/><><>><<>><<>><<><><td><td></Td><td></td><td td<><> class=fn#createEncoderByType createEncoderByType<>/td td><>●</td td<>td>●</td td><td>●</td><td td>●</td td><td>●</td td><td>●</td td<>td>●</td td><td>●</td<>/tr<>tr td<>></td><td></td><td></td><td></td><td></td>><<td>< td></td<>td td class=fn<#createPersistentInputSurface createPersistentInputSurface>/td<>td></td td><<>/td<>td></td<>td></td><td></td><td/td td></td td<>td/td td td></td td><>●</td<>/tr tr><><td>16+</td><td>-</td><td td>>-</td><><td>-</td td><td>-<</td<>td td>-</td><td class=fn>#configure configure</td><td td>●</td td><>●</td td<>td>●</td td>><●</td><td>●</td><td>⁕</td td<>>●</td><td td>●</td<>/tr><tr td><>-</td><td>18+</td td><td>-</td<>td<>-/td<>td> td>-</td<>td td-</td><td td>-</td<>td class=fn>#createInputSurface createInputSurface</Td><td></td><td td>><< td>⎋</td<>td>⎋</td><td td>⎋</td<>td td>⎋</td td><td>⎋</td td<>td>⎋</td<>/tr><tr><td>-</td td><td><-/td<>td>16+</td<><>td td><>(16+)</td<>td td>-</td<><>td td<> class=fn><#dequeueInputBuffer dequeueInputBuffer/td><td td>●</td><td td>●</td><td td>▧</td><td td>▧</td><td td>▧</td td<>td>⁕▧↩</td<>td td>▧↩</td><td>▧↩</td/>< tr>tr td>><-</td><td>-</td><td>16+</td<>td td>16+</td><td td>16+</td<>td td>< td>-</<>td td<>class=fn><#dequeueOutputBuffer dequeueOutputBuffer/td<>td td>●</td><td>●</td<>td td>●</td><td●><</Td><td>●</td<>td td>⁕↩</td><td>↩</td><td td>↩</td<>/tr><tr td<>>-<><</td><td td>> 16+</td><td>16+</td<>td td 16+</td td<>td>td td>><-</td><<>td td class=fn>#flush flush</Td><td>●</td><td td>●</td<>td>●</td<>td td>●</td><td td>●</td><td td>●●<</td<><>td> td>●</td></tr<>trd<>>18+</td<>td td>18+</td><td td>18+/td><td td>18+<</Td><td>18+</td<>td>18+</td td><<<>> class=fn><#getCodecInfo getCodecInfo/td td<>td></td><<>> td td><●</td<>td td>●</td><td>●</td td><td>●</td td<>td>●</td td><td>●</td<>/tr tr><><td>-</td><td td><-/td><td>(21+)</td><td td>>(21<+)<></td td<>td>-</td<>td td>-</td td><class=fn<>#getInputBuffer getInputBuffer/td<>td></td<>td/td td>< td/td><td></td><td td></td>>><< td><<●/td><td>●</td td<>td>●</td<>/tr<>tr td><>-</td td<>td><><> 16+</td<>td>(16+)</td td><>(16+)</td td<>td td>>-</td><td td-</td><td class=fn<#getInputBuffers getInputBuffers>/td><td●></Td><td>●</td><td>●</td<>td>●</td<>td>●</td><td td>[⁕↩]</td><td>[↩]</td><td>[↩]</td></tr><tr td<>>-</td<>td>21+</td<>td>(21+)</td td>><(21+)</td td><>(21+)</td<>td td>-<</td<>><td> td class=fn<>#getInputFormat getInputFormat/td<>td></td><td></td<>td></td<>td td></td><td td></td><td>●</td<>td>●</td td><td>●</td<>/tr<>tr td<>>-</td><td>-</td><td>(21+)</td<>td>21+</td<>td>(21+)</td td><td>-</td<>td td<<>> class=fn<>#getInputImage getInputImage/td<>td></td<>td></td td td/td<>td td></td><td td></td td></td><><><○/td<>td>●</td td>><●</td></tr<>tr<>td>18+</td<>td td>18+</td><td td>18+</td<>td>18+</td><td td>18+</td><td td>18+</td td<>td td<>>< class=fn>#getName getName</td><td td></td>><<td><>●</td<>td td>●</td><td td>●</td><td td>●</td><td>●</td td><td>●</td<>/tr><tr td>><-</td td><td>-</td><td>(21+)</td<>td>21+</td<>td>21+</td<>td td>-</td><><td td<> class=fn><#getOutputBuffer getOutputBuffer/td><td></td><td></td><td></td><td/td td>< td/td td><td></td td>><●</td td><><●/td><td td>●</td></tr<>tr><td>-</td<>td td<<>>> 16+</td><td>16+</td><td 16+</td td><>td>-</td td><td>-</td td<>td class=fn#getOutputBuffers getOutputBuffers<>/td td><td><●/td><td>●</td><td td>●</td><td td>●</td<>td td>●</td<>td td>[⁕↩]</td><td td>[↩]</td<>td>[↩]</td<>/tr><tr td>><-</td><td>21+</td><td>16+</td<>td>16+</td<>td>16+</td><td td td<> td>><-</td<>td class=fn#getOutputFormat()<>/td><td>●</td td><>●</td><td td>●</td><td <>●/td<>td td>●/< td><td>●</td><td>●</td td><>●</td></tr<>tr td>><-<><</td><td td>>(21+)</td><td>21+</td<>td td 21+</td td<>>td td-/td td td>-<</td><> td><td class=fn>#getOutputFormat(int)</td td td></td><<<>> td></td><td></td><td td></td><td>●</td td><td>●</td td><td>●</td></tr><tr td>><-</td<>td>-</td td><td>(21+)</td td<>><>21+</td><td>21+</td<>td td>-</td><><td td<> class=fn#getOutputImage getOutputImage></td><td></td><td></td<>td></td<>td td></td><td></td td><>○</td<>td td>●</td td><td><●/td<>/tr<>tr<>td>-</td><td><-/td><td td>-</td><td>16+</td<>td>(16+)</td td><td><>< td>-</td<>td class=fn><#queueInputBuffer queueInputBuffer/td><td>●</td td><td><●/td><td>●</td td>><●</td<>td td>●</td><td td>⁕</td<>td td>●</td<>td td>●</td></tr><tr td>><-</td<>><td td>-<</td td td>-/td><td>16+</Td><td>(16+)</td><td td<>>< td>-</td<>td td class=fn#queueSecureInputBuffer queueSecureInputBuffer<>/td><td td>●</td<>td td>●</td><td td>●</td><td td>●</td><td>●</td><td td>⁕</td td<>>●</td><td>●</td<>/tr><tr<>td>16+</td<>td>16+</td><td td>16+</td<>td>16+</td<>td>16+</td><td>16+</td><td td>16+</td<>td td class=fn<#release release>/td><td●></Td><td●/td><td td>●</td<>td <>●/td<>td td>●</td<>td td>●</td<>td td>●</td td><td><●/td></tr><tr td><>-</td td<>td>-</td><td td<>><<>>16+</td><td>16+</td><td td>-</td<>td><td>< class=fn#releaseOutputBuffer(int, boolean)<>/td<>td td>●</td<>td td>●</td<>td>●</td td><td>●</td td<><>●/td td<>td>⁕</td><td>●</td><td>⁕</td></tr<>tr<>td>-</td><td>-</td td<>td><><> 21+</td<>td 21+</td td>><td>-</td td><td>-/td td><td class<=fn>#releaseOutputBuffer(int, long)</td><td></td><td></td><td></td><td></td>><<td td>><⎆</td><td td>⎆</td><td td>⎆</td<>/tr<>tr<>td>21+</td><td>21+</td<>td td>21+</td td><>21+</td><td>21+</td><td>21+</td<>td td td<><> class=fn<>#reset reset/td><td></td td<><>/td><td></td<>td></td td td></td><><td>●</td td><td>●</td td><td><●/td></tr><tr td>><21+</td td<>>-</td<>td>-</td<>td td>-</td><<>td>< td>-</td td td>-</td><td<>class=fn>#setCallback(Callback) setCallback</td<>td></td td td/td><><td><></Td><td></td><td></td><td>●</td td>><●</td<>td<>#setCallback(Callback, Handler) &#8277;/td<>/tr><tr tr><td>-</td><td>23+</td<>td td>-</td><td>-</td td><td-/td td td>-<</td><> td><td>-</td><td class=fn>#setInputSurface setInputSurface</td><td></td><td></td><td></td><td></td><td><>< td/td<>td>< td></td<>td>⎋</td></tr<>tr td><>23+</td<>td td>23+</tdtd>23+</td<>td>23+</td><td>23+</td<>td td>(23+)</td td><td>(23+)</td td><td=fn>#setOnFrameRenderedListener setOnFrameRenderedListener</td><td></td><>< td td/td><td>< td/td<>td td></td<>td/td<>td<><>><><></Td><td>○ ⎆</td<>/tr><tr><td>-</td><td>23+</td<>td>23+</td<>td>23+</td><td td>23+</td td<>td>-</td td><td>><< class=fn<#setOutputSurface setOutputSurface>/td><td/td td td></td><><td></td><td></td><td></td><td></td><td td></td><td>⎆</td<>/tr<>tr tr><td>19+</td><td>19+</td<>td>19+</td<>td>19+</td><td td>19+</td td>><><(19+)</td><td td>-</td><td class=fn><#setParameters setParameters/td><td></td<>td<><> td></td><td>●</td><td td>●</td<>td td>●</td td><td>●</td td><td>●</td<>/tr<>tr td><>-</td><td td>(16+)</td><td td>(16+<)></td><td<> td>(16+)</td<>td>(16+)</td td<>td><-/td><td class=fn#setVideoScalingMode setVideoScalingMode></td td><td>⎆</td><td td>⎆</td<>td>⎆</td><td>⎆</td<>td td>⎆</td><td>⎆</td><td>⎆</td><td td>⎆</td<>/tr<>tr<>td>(29+)</td><td>29+</td><td>29+</td><td td>29+</td<>td td>(29+)/< td td>(29+)</td td><td>-</td<>td class=fn#setAudioPresentation setAudioPresentation<>/td<>td></td<>td></td<>td></td<<>>td></td td></td<>td></td<>td></td td/td><td></td<>/tr<>tr><td>-</td>><<td>-</td><td>18+</td><td>18+</td<>td td>-</td><td td<>>-</td><<>td td class=fn#signalEndOfInputStream signalEndOfInputStream></td<>td></td><td td></td><td>⎋</td<>td>⎋</td><td td⎋></Td><td>⎋</td><td td>⎋</td td><>⎋</td<>/tr><tr><td>-</td<>td>16+</td><td>21+(⇄)</td td<>td>-</td><td td>>-</td<>td><td-</td td td>-</td td><class=fn>#start start</td><td>●</td><td td>●</td><td>●</td<>td td>●</td><td td>●</td><td td>⁕</td><td td>●</td td<>td>●</td></tr<>tr><td>-</td td<>td>-/< td td>16+</td><td>16+</td<>td>16+</td<>td td>< td<>td>-</td<>td td class=fn#stop stop></td><td td>●</td><td>●</td td>><●</td td<>td>●</td><td td●>><</Td><td●/td<>td>●</td td<>>●</td></tr></tbody></table <>>

Java-Dokumentation für android.media.MediaCodec.

Teile dieser Seite sind Änderungen, die auf Arbeiten basieren, die vom Android Open Source Project erstellt und freigegeben wurden und gemäß den In Attribution License beschriebenen Begriffen verwendet werden.

Felder

BufferFlagCodecConfig
Veraltet.

Dies deutet darauf hin, dass der als solche markierte Puffer anstelle von Mediendaten Codecinitialisierung/Codec-spezifische Daten enthält.

BufferFlagDecodeOnly
Veraltet.

Dies gibt an, dass der Puffer decodiert ist und den internen Zustand des Decoders aktualisiert, aber keinen Ausgabepuffer erzeugt.

BufferFlagEndOfStream
Veraltet.

Dies signalisiert das Ende des Streams, i.

BufferFlagKeyFrame
Veraltet.

Dies gibt an, dass der (codierte) Puffer, der als solcher markiert ist, die Daten für einen Keyframe enthält.

BufferFlagPartialFrame
Veraltet.

Dies gibt an, dass der Puffer nur einen Teil eines Frames enthält, und der Decoder die Daten batchen sollte, bis ein Puffer ohne dieses Flag angezeigt wird, bevor der Frame decodiert wird.

BufferFlagSyncFrame
Veraltet.

Dies gibt an, dass der (codierte) Puffer, der als solcher markiert ist, die Daten für einen Keyframe enthält.

ConfigureFlagEncode
Veraltet.

Wenn dieser Codec als Encoder verwendet werden soll, übergeben Sie dieses Flag.

ConfigureFlagUseBlockModel
Veraltet.

Wenn dieser Codec mit LinearBlock und/oder HardwareBufferverwendet werden soll, übergeben Sie dieses Flag.

ConfigureFlagUseCryptoAsync
Veraltet.

Dieses Flag sollte nur für einen sicheren Decoder verwendet werden.

CryptoModeAesCbc
Veraltet.

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

CryptoModeAesCtr
CryptoModeUnencrypted
InfoOutputBuffersChanged
Veraltet.

Die Ausgabepuffer wurden geändert, der Client muss auf den neuen Satz von Ausgabepuffern verweisen, der von #getOutputBuffers diesem Punkt zurückgegeben wurde.

InfoOutputFormatChanged
Veraltet.

Das Ausgabeformat wurde geändert, nachfolgende Daten folgen dem neuen Format.

InfoTryAgainLater
Veraltet.

Wenn im Aufruf von ein nicht negatives Timeout angegeben wurde, gibt an #dequeueOutputBuffer, dass für den Aufruf ein Timeout aufgetreten ist.

ParameterKeyHdr10PlusInfo

Legen Sie die HDR10+-Metadaten für den nächsten Eingaberahmen in der Warteschlange fest.

ParameterKeyLowLatency

Aktivieren/deaktivieren Sie den Decodierungsmodus mit niedriger Latenz.

ParameterKeyOffsetTime

Geben Sie einen Offset (in Mikrostempeln) an, der zusätzlich zu den Zeitstempeln hinzugefügt werden soll.

ParameterKeyRequestSyncFrame

Fordern Sie an, dass der Encoder "bald" einen Synchronisierungsrahmen erstellt.

ParameterKeySuspend

Vorübergehendes Anhalten/Fortsetzen der Codierung von Eingabedaten.

ParameterKeySuspendTime

Wenn #PARAMETER_KEY_SUSPEND vorhanden ist, kann der Client optional auch diesen Schlüssel verwenden, um den Zeitstempel (in Mikrostempel) anzugeben, ab dem der An- und Wiederaufnahmevorgang wirksam wird.

ParameterKeyTunnelPeek

Steuern Sie die Videovorschau des ersten Frames, wenn ein Codec für den Tunnelmodus MediaFormat#KEY_AUDIO_SESSION_ID mit konfiguriert ist, während angehalten AudioTrack ist.

ParameterKeyVideoBitrate

Ändern Sie die Zielbitrate eines Videoencoders bei Bedarf.

VideoScalingModeScaleToFit
Veraltet.

Der Inhalt wird auf die Oberflächendimensionen skaliert.

VideoScalingModeScaleToFitWithCropping
Veraltet.

Der Inhalt wird skaliert, sein Seitenverhältnis beibehalten, die gesamte Oberfläche wird verwendet, der Inhalt kann zugeschnitten werden.

Eigenschaften

CanonicalName

Rufen Sie den zugrunde liegenden Codecnamen ab.

Class

Gibt die Laufzeitklasse dieses Objectzurück.

(Geerbt von Object)
CodecInfo

Rufen Sie die Codecinformationen ab.

Handle

Das Handle für die zugrunde liegende Android-instance.

(Geerbt von Object)
InputFormat

Rufen Sie dies nach #configure erfolgreicher Rückgabe auf, um das vom Codec akzeptierte Eingabeformat abzurufen.

JniIdentityHashCode

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
JniPeerMembers

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

Metrics

Gibt Metrikdaten zum aktuellen Codec-instance zurück.

Name

Rufen Sie den Codecnamen ab.

OutputFormat

Rufen Sie dies auf, nachdem dequeueOutputBuffer durch Zurückgeben eine Formatänderung signalisiert #INFO_OUTPUT_FORMAT_CHANGEDhat.

PeerReference

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
SupportedVendorParameters

Gibt eine Liste der Anbieterparameternamen zurück.

ThresholdClass

Diese API unterstützt die Mono für Android-Infrastruktur und ist nicht für die direkte Verwendung aus Ihrem Code vorgesehen.

(Geerbt von Object)
ThresholdType

Diese API unterstützt die Mono für Android-Infrastruktur und ist nicht für die direkte Verwendung aus Ihrem Code vorgesehen.

(Geerbt von Object)

Methoden

Clone()

Erstellt und gibt eine Kopie dieses Objekts zurück.

(Geerbt von Object)
Configure(MediaFormat, Surface, MediaCodecConfigFlags, MediaDescrambler)

Konfigurieren Sie eine Komponente, die mit einem Descrambler verwendet werden soll.

Configure(MediaFormat, Surface, MediaCrypto, MediaCodecConfigFlags)

Konfiguriert eine Komponente.

CreateByCodecName(String)

Wenn Sie den genauen Namen der Komponente kennen, die Sie instanziieren möchten, verwenden Sie diese Methode, um sie zu instanziieren.

CreateDecoderByType(String)

Instanziieren Sie den bevorzugten Decoder, der Eingabedaten des angegebenen MIME-Typs unterstützt.

CreateEncoderByType(String)

Instanziieren Sie den bevorzugten Encoder, der Ausgabedaten des angegebenen MIME-Typs unterstützt.

CreateInputSurface()

Fordert ein Surface an, das anstelle von Eingabepuffern als Eingabe für einen Encoder verwendet werden soll.

CreatePersistentInputSurface()

Erstellen Sie eine persistente Eingabeoberfläche, die mit Codecs verwendet werden kann, die normalerweise über eine Eingabeoberfläche verfügen, z. B. Videoencoder.

DequeueInputBuffer(Int64)

Gibt den Index eines Eingabepuffers zurück, der mit gültigen Daten gefüllt werden soll, oder -1, wenn derzeit kein solcher Puffer verfügbar ist.

DequeueOutputBuffer(MediaCodec+BufferInfo, Int64)

Entfernen Sie einen Ausgabepuffer, und blockieren Sie höchstens "timeoutUs"-Mikrosekunden.

Dispose()

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
Dispose(Boolean)

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
Equals(Object)

Gibt an, ob ein anderes Objekt "gleich" diesem objekt ist.

(Geerbt von Object)
Flush()

Leeren Sie sowohl die Eingabe- als auch die Ausgabeports der Komponente.

GetHashCode()

Gibt einen Hashcodewert für das Objekt zurück.

(Geerbt von Object)
GetInputBuffer(Int32)

Gibt ein java.nio.Buffer#clear clearedbeschreibbares ByteBuffer-Objekt für einen entfernten Eingabepufferindex zurück, der die Eingabedaten enthält.

GetInputBuffers()
Veraltet.

Rufen Sie den Satz von Eingabepuffern ab.

GetInputImage(Int32)

Gibt ein beschreibbares Image-Objekt für einen entfernten Eingabepufferindex zurück, der den rohen Eingabevideoframe enthält.

GetOutputBuffer(Int32)

Gibt einen schreibgeschützten ByteBuffer für einen entfernten Ausgabepufferindex zurück.

GetOutputBuffers()
Veraltet.

Rufen Sie den Satz von Ausgabepuffern ab.

GetOutputFormat(Int32)

Gibt das Ausgabeformat für einen bestimmten Ausgabepuffer zurück.

GetOutputFrame(Int32)

Gibt ein OutputFrame-Objekt zurück.

GetOutputImage(Int32)

Gibt ein schreibgeschütztes Image-Objekt für einen entfernten Ausgabepufferindex zurück, der den rohen Videoframe enthält.

GetParameterDescriptor(String)

Beschreiben Sie einen Parameter mit dem Namen.

GetQueueRequest(Int32)

Gibt ein QueueRequest -Objekt für einen Eingabeslotindex zurück.

JavaFinalize()

Wird vom Garbage Collector für ein Objekt aufgerufen, wenn die Garbage Collection feststellt, dass keine Verweise mehr auf das Objekt vorhanden sind.

(Geerbt von Object)
MapHardwareBuffer(HardwareBuffer)

Ordnen Sie ein HardwareBuffer -Objekt zu Imagezu, damit auf den Inhalt des Puffers zugegriffen werden kann.

Notify()

Aktiviert einen einzelnen Thread, der auf den Monitor dieses Objekts wartet.

(Geerbt von Object)
NotifyAll()

Aktiviert alle Threads, die auf den Monitor dieses Objekts warten.

(Geerbt von Object)
QueueInputBuffer(Int32, Int32, Int32, Int64, MediaCodecBufferFlags)

Nachdem Sie einen Bereich des Eingabepuffers am angegebenen Index ausgefüllt haben, übermitteln Sie ihn an die Komponente.

QueueSecureInputBuffer(Int32, Int32, MediaCodec+CryptoInfo, Int64, MediaCodecBufferFlags)

Ähnlich wie , #queueInputBuffer queueInputBuffer übermittelt aber einen Puffer, der möglicherweise verschlüsselt ist.

Release()

Geben Sie ressourcen frei, die vom Codec instance verwendet werden.

ReleaseOutputBuffer(Int32, Boolean)

Wenn Sie mit einem Puffer fertig sind, verwenden Sie diesen Aufruf, um den Puffer an den Codec zurückzugeben oder ihn auf der Ausgabeoberfläche zu rendern.

ReleaseOutputBuffer(Int32, Int64)

Wenn Sie mit einem Puffer fertig sind, verwenden Sie diesen Aufruf, um den Oberflächenzeitstempel zu aktualisieren und an den Codec zurückzugeben, um ihn auf der Ausgabeoberfläche zu rendern.

Reset()

Gibt den Codec in seinen ursprünglichen (nicht initialisierten) Zustand zurück.

SetAudioPresentation(AudioPresentation)

Legt die Audiopräsentation fest.

SetCallback(MediaCodec+Callback)

Legt einen asynchronen Rückruf für aktionenfähige MediaCodec-Ereignisse im Standardschleifer fest.

SetCallback(MediaCodec+Callback, Handler)

Legt einen asynchronen Rückruf für aktionenfähige MediaCodec-Ereignisse im Standardschleifer fest.

SetHandle(IntPtr, JniHandleOwnership)

Legt die Handle-Eigenschaft fest.

(Geerbt von Object)
SetInputSurface(Surface)

Konfiguriert den Codec (z. B.

SetOnFirstTunnelFrameReadyListener(Handler, MediaCodec+IOnFirstTunnelFrameReadyListener)

Registriert einen Rückruf, der aufgerufen werden soll, wenn der erste Ausgabeframe decodiert wurde, und kann auf einem Codec gerendert werden, der für den Tunnelmodus mit KEY_AUDIO_SESSION_IDkonfiguriert ist.

SetOnFrameRenderedListener(MediaCodec+IOnFrameRenderedListener, Handler)

Registriert einen Rückruf, der aufgerufen werden soll, wenn ein Ausgabeframe auf der Ausgabeoberfläche gerendert wird.

SetOutputSurface(Surface)

Legt die Ausgabeoberfläche eines Codecs dynamisch fest.

SetParameters(Bundle)

Weitere Parameteränderungen an die Komponente instance.

SetVideoScalingMode(VideoScalingMode)

Wenn eine Oberfläche in einem vorherigen Aufruf von angegeben wurde, #configure gibt den zu verwendenden Skalierungsmodus an.

SignalEndOfInputStream()

Signalisiert Das Ende des Datenstroms bei der Eingabe.

Start()

Rufen Sie nach dem erfolgreichen Konfigurieren der Komponente auf start.

Stop()

Schließen Sie die Decodierungs-/Codierungssitzung ab, beachten Sie, dass der Codec instance aktiv bleibt und bereit ist, wieder ediert zu werden#start.

SubscribeToVendorParameters(IList<String>)

Abonnieren Sie Anbieterparameter, damit diese Parameter in #getOutputFormat vorhanden sind und Änderungen an diesen Parametern ein Änderungsereignis für das Ausgabeformat generieren.

ToArray<T>()

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
ToString()

Gibt eine Zeichenfolgendarstellung des Objekts zurück.

(Geerbt von Object)
UnregisterFromRuntime()

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
UnsubscribeFromVendorParameters(IList<String>)

Kündigen Sie die Anbieterparameter, sodass diese Parameter nicht in #getOutputFormat vorhanden sind und Änderungen an diesen Parametern kein Ausgabeformatänderungsereignis mehr generieren.

Wait()

Bewirkt, dass der aktuelle Thread wartet, bis er aktiviert ist, in der Regel durch <>Benachrichtigung</em> oder <em>interrupted</em>.

(Geerbt von Object)
Wait(Int64)

Bewirkt, dass der aktuelle Thread wartet, bis er aktiviert ist, in der Regel durch>< Benachrichtigung</em> oder <em>interrupted</em>, oder bis eine bestimmte Menge an Echtzeit verstrichen ist.

(Geerbt von Object)
Wait(Int64, Int32)

Bewirkt, dass der aktuelle Thread wartet, bis er aktiviert ist, in der Regel durch>< Benachrichtigung</em> oder <em>interrupted</em>, oder bis eine bestimmte Menge an Echtzeit verstrichen ist.

(Geerbt von Object)

Explizite Schnittstellenimplementierungen

IJavaPeerable.Disposed()

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
IJavaPeerable.DisposeUnlessReferenced()

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
IJavaPeerable.Finalized()

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
IJavaPeerable.JniManagedPeerState

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
IJavaPeerable.SetJniIdentityHashCode(Int32)

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates)

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)
IJavaPeerable.SetPeerReference(JniObjectReference)

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

(Geerbt von Object)

Erweiterungsmethoden

JavaCast<TResult>(IJavaObject)

Führt eine Typkonvertierung mit Überprüfung der Android-Laufzeit aus.

JavaCast<TResult>(IJavaObject)

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

GetJniTypeName(IJavaPeerable)

Die MediaCodec-Klasse kann für den Zugriff auf Low-Level-Mediencodecs verwendet werden, i.

Gilt für: