MediaCodec Klasse
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, 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
- Attribute
Hinweise
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs mit niedriger Ebene zuzugreifen, d. h. Encoder-/Decoderkomponenten. Es ist Teil der Android Low-Level Multimedia-Unterstützungsinfrastruktur (normalerweise zusammen mit MediaExtractor
, MediaSync
, , MediaMuxer
, , MediaCrypto
, MediaDrm
, Image
, Surface
und AudioTrack
.)
<center><img src=".. /.. /.. /images/media/mediacodec_buffers.svg" style="width: 540px; height: 205px" alt="MediaCodec buffer flow diagram"></center>
Im Allgemeinen verarbeitet ein Codec Eingabedaten, um Ausgabedaten zu generieren. Sie verarbeitet Daten asynchron und verwendet eine Reihe von Eingabe- und Ausgabepuffern. Auf einer vereinfachten Ebene fordern (oder empfangen) Sie einen leeren Eingabepuffer an, füllen ihn mit Daten aus, und senden sie zur Verarbeitung an den Codec. Der Codec verwendet die Daten und wandelt sie in einen der leeren Ausgabepuffer um. Schließlich fordern Sie einen gefüllten Ausgabepuffer an (oder empfangen), verbrauchen den Inhalt und lassen ihn wieder an den Codec zurück.
<h3 id=quality Floor"quality Floor>">Minimum Quality Floor for Video Encoding</h3>
Beginnend mit android.os.Build.VERSION_CODES#S
, Erzwingen von Android Video MediaCodecs eine Mindestqualität. Die Absicht besteht darin, videocodierungen mit schlechter Qualität zu beseitigen. Diese Qualitätsstufe wird angewendet, wenn sich der Codec im Modus variabler Bitrate (VBR) befindet. sie wird nicht angewendet, wenn sich der Codec im CBR-Modus (Constant Bitrate) befindet. Die Qualität der Bodendurchsetzung ist auch auf einen bestimmten Größenbereich beschränkt; Dieser Größenbereich ist derzeit für Videoauflösungen größer als 320x240 bis 1920x1080.
Wenn dieser Qualitätsboden wirksam ist, funktioniert 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 wichtig für Videos, die mit sehr niedrigen Bitraten konfiguriert wurden; Der Codec verwendet eine Bitrate, die bestimmt ist, dass ein "faires" oder "gutes" Video wahrscheinlicher generiert wird. Eine andere Situation ist, dass ein Video sehr komplizierte Inhalte enthält (viel Bewegung und Detail); in solchen Konfigurationen verwendet der Codec bei Bedarf zusätzliche Bitrate, um zu vermeiden, dass alle Details des Inhalts verloren gehen.
Dieser Qualitätsboden wirkt sich nicht auf Inhalte aus, die bei hohen Bitraten erfasst werden (eine hohe Bitrate sollte den Codec bereits mit ausreichender Kapazität bereitstellen, um alle Details zu codieren). Der Qualitätsboden funktioniert nicht für CBR-Codierungen. Der Qualitätsboden funktioniert derzeit nicht mit Auflösungen von 320x240 oder niedriger, noch auf Videos mit Auflösung über 1920x1080.
<h3>Datentypen</h3>
Codecs funktionieren auf drei Arten von Daten: komprimierte Daten, rohe Audiodaten und rohe Videodaten. Alle drei Arten von Daten können mithilfe ByteBuffer ByteBuffers
von Daten verarbeitet werden. Sie sollten jedoch eine Surface
Für unformatierte Videodaten verwenden, um die Codec-Leistung zu verbessern. Surface verwendet systemeigene Videopuffer ohne Zuordnung oder Kopieren in ByteBuffers; daher ist es viel effizienter. Normalerweise können Sie nicht auf die rohen Videodaten 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 systemeigene Puffer möglicherweise in ByteBuffer#isDirect direct ByteBuffers zugeordnet werden. Wenn Sie den ByteBuffer-Modus verwenden, können Sie mithilfe der Klasse und #getInputImage getInput
/#getOutputImage OutputImage(int)
der Image
Klasse auf rohe Videoframes zugreifen.
<h4>Komprimierte Puffer</h4>
Eingabepuffer (für Decoder) und Ausgabepuffer (für Encoder) enthalten komprimierte Daten gemäß mediaFormat#KEY_MIME Formattyp. Bei Videotypen ist dies normalerweise ein einzelner komprimierter Videoframe. Bei Audiodaten ist dies normalerweise eine einzige Zugriffseinheit (ein codiertes Audiosegment, das normalerweise einige Millisekunden von Audio enthält, wie vom Formattyp vorgegeben), aber diese Anforderung ist etwas entspannt, da ein Puffer möglicherweise mehrere codierte Zugriffseinheiten von Audio enthalten kann. In beiden Fällen starten oder enden Puffer nicht mit beliebigen Bytegrenzen, sondern auf Frame-/Zugriffseinheitsgrenzen, es sei denn, sie werden mit #BUFFER_FLAG_PARTIAL_FRAME
gekennzeichnet.
<h4>Raw Audio Buffers</h4>
Unformatierte 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 ganzzahlige 16-Bit-Ganzzahl oder ein Gleitkomma in systemeigener Bytereihenfolge. Unformatierte Audiopuffer in der Float-PCM-Codierung sind nur möglich, wenn mediaFormat#KEY_PCM_ENCODING während mediaCodec #configure configure(…)
auf "AudioFormat#ENCODING_PCM_FLOAT" festgelegt ist und von #getOutputFormat
Decodern oder #getInputFormat
Encodern 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-ganzzahlige Audiodaten 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 < 0 || channelIx >= numChannels) {
return null;
}
short[] res = new short[samples.remaining() / numChannels];
for (int i = 0; i < 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 aus #getCodecInfo
.
.
MediaCodecInfo#getCapabilitiesForType getCapabilitiesForType(…)
CodecCapabilities#colorFormats colorFormats
abrufen. Videocodecs unterstützen möglicherweise drei Arten von Farbformaten: <ul><li><strong>natives raw-Videoformat:</strong> Dies ist gekennzeichnet und CodecCapabilities#COLOR_FormatSurface
kann mit einer Eingabe oder Ausgabe surface verwendet werden.</li li>><<starke flexible>YUV-Puffer</starke> (zCodecCapabilities#COLOR_FormatYUV420Flexible
. B.): Diese können mit einem Eingabe-/Ausgabe-Surface sowie im ByteBuffer-Modus verwendet werden.#getInputImage getInput
/#getOutputImage OutputImage(int)
</li li>><<stark>andere, spezifische Formate:</strong> Diese werden normalerweise nur im ByteBuffer-Modus unterstützt. Einige Farbformate sind herstellerspezifisch. Andere sind definiert in CodecCapabilities
. Bei Farbformaten, die einem flexiblen Format entsprechen, können Sie weiterhin verwenden #getInputImage getInput
/#getOutputImage OutputImage(int)
.</li></ul>
Alle Videocodecs unterstützen flexible YUV 4:2:0-Puffer seit android.os.Build.VERSION_CODES#LOLLIPOP_MR1
.
<h4>Zugreifen auf unformatierte 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
Format und MediaFormat#KEY_SLICE_HEIGHT
die Ausgabe verwenden, um das Layout der rohen Ausgabepuffer zu verstehen. <p class=note> Note that on some devices the slice-height is advertised as 0. Dies kann entweder bedeuten, dass die Datenschnitthöhe identisch mit der Framehöhe ist oder dass die Datenschnitthöhe die Framehöhe an einem bestimmten Wert ausgerichtet ist (in der Regel eine Potenz von 2). Leider gibt es in diesem Fall keine Standard- und einfache Möglichkeit, die tatsächliche Segmenthöhe zu ermitteln. Darüber hinaus ist die vertikale Stride der U
Ebene in planaren Formaten nicht angegeben oder definiert, obwohl es in der Regel die Hälfte der Segmenthöhe ist.
Die MediaFormat#KEY_WIDTH
Tasten und MediaFormat#KEY_HEIGHT
die Tasten geben die Größe der Videoframes an. Bei den meisten Encondings belegt das Video (Bild) jedoch nur einen Teil des Videoframes. Dies wird durch das "Zuschneiderechteck" dargestellt.
Sie müssen die folgenden Tasten 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 Ausgabeframe <>em verstanden, bevor</em> eine MediaFormat#KEY_ROTATION Drehung angewendet wird. <table style="width: 0%"><thead><tr<>th>Format Key</th>><Type</th><>Beschreibung/th/th Beschreibung</th<>/tr></thead<>td td<<>>MediaFormat#KEY_CROP_LEFT
>< td<>td>Integer</td><td>Die linke Koordinate (x) des Zuschneiderechtecks</td/tr><td><<>><MediaFormat#KEY_CROP_TOP
/td td<>>Integer/< td td>The top-coordinate (y) of the crop rectangle</td<>/tr tr><><td/td><MediaFormat#KEY_CROP_RIGHT
td>><<>>< The right-coordinate (x) <strong MINUS 1</strong>> of the crop rectangle</td<>/tr><>>MediaFormat#KEY_CROP_BOTTOM
<< td/td<>td>Integer</td><td>The bottom-coordinate (y) <strong>MINUS 1</strong><> des Zuschneiderechtecks</td<>/tr><td><colspan=3> Die rechten und unteren Koordinaten können als Koordinaten der am weitesten rechts gültigen Spalte/untersten Zeile des zugeschnittenen Ausgabebilds verstanden werden. </td></tr></tbody></table>
Die Größe des Videoframes (vor drehung) kann wie folgt berechnet werden:
MediaFormat format = decoder.getOutputFormat(…);
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 auf allen Geräten konsistent war. Auf einigen Geräten verweist der Offset auf das obere linke Pixel des Zuschneiderechtecks, während er auf den meisten Geräten auf das obere linke Pixel des gesamten Frames verweist.
<h3>Staaten</h3>
Während der Lebensdauer ist ein Codec konzeptionell in einem von drei Zuständen vorhanden: "Beendet", "Ausführen" oder "Losgelassen". Der kollektive Zustand "Beendet" ist tatsächlich die Konglomeration von drei Zuständen: "Nicht initialisiert", "Konfiguriert" und "Fehler", während der Ausführungszustand konzeptionell durch drei Unterzustände voranschreitet: Flushed, Running 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 Zustand "Nicht initialisiert". Zuerst müssen Sie sie über #configure configure(…)
konfigurieren, wodurch sie in den Zustand "Konfiguriert" versetzt wird, und rufen Sie dann auf #start
, um sie in den Zustand "Ausführen" zu verschieben. In diesem Zustand können Sie Daten über die oben beschriebene Manipulation der Pufferwarteschlange verarbeiten.
Der Ausführungsstatus weist drei Unterzustände auf: "Flushed", "Running" und "End-of-Stream". Unmittelbar nachdem #start
sich der Codec im Unterzustand "Flushed" befindet, in dem er alle Puffer enthält. Sobald der erste Eingabepuffer entqueuiert wird, wechselt der Codec in den Unterzustand "Ausführen", in dem er den größten Teil seiner Lebensdauer verbringt. Wenn Sie einen Eingabepuffer mit der Markierung "#BUFFER_FLAG_END_OF_STREAM Ende des Datenstroms" in die Warteschlange stellen, wechselt der Codec in den Unterzustand "End-of-Stream". In diesem Zustand akzeptiert der Codec keine weiteren Eingabepuffer mehr, generiert aber weiterhin Ausgabepuffer, bis das Ende des Datenstroms auf der Ausgabe erreicht ist. Bei Decodern können Sie jederzeit wieder in den Unterzustand "Geleert" wechseln, während Sie den Zustand "Ausführen" verwenden #flush
. <p class=note><strong>Note:</strong> Going back to Flushed state is only supported for decoders, may not work for encoders (the behavior is undefined).
Rufen Sie #stop
den Codec auf, um den Nicht initialisierten Zustand zurückzugeben, wobei er möglicherweise erneut konfiguriert wird. Wenn Sie mit der Verwendung eines Codecs fertig sind, müssen Sie ihn durch Aufrufen #release
freigeben.
In seltenen Fällen kann der Codec auf einen Fehler stoßen und zum Fehlerzustand wechseln. Dies wird mithilfe eines ungültigen Rückgabewerts aus einem Warteschlangenvorgang oder manchmal über eine Ausnahme kommuniziert. Rufen Sie #reset
auf, um den Codec wieder verwendbar zu machen. Sie können ihn aus jedem Zustand aufrufen, um den Codec zurück in den nicht initialisierten Zustand zu verschieben. Andernfalls rufen Sie #release
auf, um zum Status "Freigegeben" des Terminals zu wechseln.
<h3>Creation</h3>
Dient MediaCodecList
zum Erstellen eines MediaCodec für eine bestimmte MediaFormat
. Beim Decodieren einer Datei oder eines Datenstroms können Sie das gewünschte Format abrufen.MediaExtractor#getTrackFormat MediaExtractor.getTrackFormat
Fügen Sie bestimmte Features ein, die Sie hinzufügen MediaFormat#setFeatureEnabled MediaFormat.setFeatureEnabled
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>Note:</strong> On android.os.Build.VERSION_CODES#LOLLIPOP
, das Format darf MediaCodecList.findDecoder
/EncoderForFormat
keine MediaFormat#KEY_FRAME_RATE Framerate enthalten. Wird verwendet format.setString(MediaFormat.KEY_FRAME_RATE, null)
, um alle vorhandenen Bildfrequenzeinstellungen im Format zu löschen.
Sie können auch den bevorzugten Codec für einen bestimmten MIME-Typ mithilfe von #createDecoderByType createDecoder
/#createEncoderByType EncoderByType(String)
. Dies kann jedoch nicht zum Einfügen von Features verwendet werden und kann einen Codec erstellen, der das gewünschte Medienformat nicht verarbeiten kann.
<h4>Erstellen sicherer Decoder</h4>
Auf Versionen und früheren Versionen android.os.Build.VERSION_CODES#KITKAT_WATCH
sind sichere Codecs möglicherweise nicht aufgeführt MediaCodecList
, sind aber weiterhin auf dem System verfügbar. Sichere Codecs, die vorhanden sind, können nur anhand des Namens instanziiert werden, indem der Name eines regulären Codecs angefügt ".secure"
wird (der Name aller sicheren Codecs muss auf ".secure"
.) endenIOException
, #createByCodecName
wenn der Codec nicht auf dem System vorhanden ist.
Ab android.os.Build.VERSION_CODES#LOLLIPOP
jetzt 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 festlegen #setCallback setCallback
, wenn Sie Daten asynchron verarbeiten möchten. Anschließend #configure den Codec mithilfe des spezifischen Medienformats konfigurieren. Dies ist der Fall, wenn Sie die Ausgabe Surface
für Videohersteller – Codecs angeben können, die rohe Videodaten 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 ausgeführt werden können, müssen Sie angeben, ob sie als Decoder oder Encoder funktionieren soll.
Da android.os.Build.VERSION_CODES#LOLLIPOP
kö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 rohe Eingabevideopuffer nativ mit einem Video-Consumer und -ndash verarbeiten möchten; ein Codec, der rohe Videoeingaben verarbeitet, z. B. einen Video-Encoder und einen Ndash; Erstellen Sie ein Ziel-Surface für Ihre Eingabedaten nach #createInputSurface
der Konfiguration. Richten Sie alternativ den Codec so ein, dass er eine zuvor erstellte #createPersistentInputSurface persistente Eingabeoberfläche verwendet, indem Sie aufrufen #setInputSurface
.
<h4 id=CSD>"CSD">Codec-specific Data</h4>
Bei einigen Formaten, insbesondere AAC-Audio- und MPEG4-, H.264- und H.265-Videoformaten, müssen die tatsächlichen Daten einer Reihe von Puffern mit Setupdaten oder codecspezifischen Daten vorangestellt werden. Bei der Verarbeitung solcher komprimierter Formate müssen diese Daten nach #start
und vor Framedaten an den Codec übermittelt werden. Diese Daten müssen mit der Kennzeichnung #BUFFER_FLAG_CODEC_CONFIG
in einem Aufruf #queueInputBuffer queueInputBuffer
gekennzeichnet werden.
Codecspezifische Daten können auch in das Format einbezogen werden, das in ByteBuffer-Einträgen mit Schlüsseln "csd-0", "csd-1" usw. übergeben #configure configure
wird. Diese Schlüssel sind immer in der Spur MediaFormat
enthalten, die von der MediaExtractor#getTrackFormat MediaExtractor
. Codecspezifische Daten im Format werden automatisch an den Codec #start
übermittelt; Sie <>müssen diese Daten explizit nicht</stark> übermitteln. Wenn das Format keine codecspezifischen Daten enthält, können Sie es gemäß den Formatanforderungen mithilfe der angegebenen Anzahl von Puffern in der richtigen Reihenfolge übermitteln. Bei H.264 AVC können Sie auch alle codecspezifischen Daten verketten und als einzelner Codec-Konfigurationspuffer übermitteln.
Android verwendet die folgenden codecspezifischen Datenpuffer. Diese müssen auch im Track-Format für die richtige MediaMuxer
Trackkonfiguration festgelegt werden. Jeder Parametersatz und die codecspezifischen Datenabschnitte, die mit (<sup*</sup>>) gekennzeichnet sind, müssen mit einem Startcode beginnen."\x00\x00\x00\x01"
<Formatvorlage>td. NA { background: #ccc; } .mid > tr > td { vertical-align: middle; }</style><table><thead><th>Format</th><>CSD buffer #0</th><>CSD buffer #1</th<>CSD>buffer #2</th<>/thead><tbody class=mid><tr<>td>AAC</td td>><decoder-specific information from ESDS<sup>*</sup></td td><td class=NA>Not Used</td td td class=NA Not Used/td><td class=NA>Not Used</Td></tr>td>><VORBIS</td<>td td>Identification header</td<>td>Setup header</td td<>class=NA>Not Used</td<>/tr><td><>OPUS</td><td td>Identification header</td<>td>Pre-skip in nanosecs<br> (unsigned 64-bit ByteOrder#nativeOrder nativeOrder-integer.)<<br> Überschreibt den Vorsprungwert im Identifikationsheader.</td td>><Seek Pre-roll in nanosecs<br> (nicht signierte 64-Bit ByteOrder#nativeOrder native-order integer.)</td></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 td><class=NA>Not Used</td/td/tr<>td<><>> MPEG-4</td><Td>Decoderspezifische Informationen von ESDS sup*/sup></td td><class=NA>Not Used</td td<>class=NA>Not Used</td/tr tr><<>td><> H.264 AVC</td td><>SPS (Sequence Parameter Sets<sup>*</sup>)</td td>><PPS (Picture Parameter Sets<sup>*</sup>)</td td><<>< class=NA>Not Used</td></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><class=NA>Not Used/td><td class=NA>Not Used/<< td></tr td<<>>>VP9</td td><>VP9 CodecPrivate Data (optional)</td td td><class=NA>Not Used</td<>td td class=NA>Not Used</td></tr><td>><AV1</td><td>AV1 AV1CodecConfigurationRecord Data (optional) </td<>td class=NA>Not Used/< td><td class=NA>Not Used</td></tr></tbody></table>
<p class=note><strong>Note:</strong> care must be taken if the codec is flushed immediately or shortly after start, before any output buffer or output format change has been returned, as the codec specific data may be lost during the flush. Sie müssen die Daten erneut übermitteln, indem Sie Puffer verwenden, die nach der entsprechenden Leerung gekennzeichnet #BUFFER_FLAG_CODEC_CONFIG
sind, um einen ordnungsgemäßen Codecvorgang 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 sinnvollen Zeitstempel auf.
<h3>Datenverarbeitung</h3>
Jeder Codec verwaltet einen Satz von Eingabe- und Ausgabepuffern, auf die von einer Puffer-ID in API-Aufrufen verwiesen wird. Nach einem erfolgreichen Aufruf des #start
Clients "besitzt" weder Eingabe- noch Ausgabepuffer. Rufen Sie im synchronen Modus einen #dequeueInputBuffer dequeueInput
/#dequeueOutputBuffer OutputBuffer(…)
Eingabe- oder Ausgabepuffer aus dem Codec auf, um einen Eingabe- oder Ausgabepuffer abzurufen (abrufen). Im asynchronen Modus erhalten Sie automatisch verfügbare Puffer über die Callback#onInputBufferAvailable MediaCodec.Callback.onInput
/Callback#onOutputBufferAvailable OutputBufferAvailable(…)
Rückrufe.
Wenn Sie einen Eingabepuffer abrufen, füllen Sie ihn mit Daten aus, und übermitteln Sie ihn mithilfe von #queueInputBuffer queueInputBuffer
"&ndash" an den Codec, oder #queueSecureInputBuffer queueSecureInputBuffer
wenn sie entschlüsselt wird. Senden Sie nicht mehrere Eingabepuffer mit demselben Zeitstempel (es sei denn, es handelt sich um codecspezifische 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 dem Verarbeiten des Ausgabepuffers eine der #releaseOutputBuffer releaseOutputBuffer
Methoden auf, um den Puffer an den Codec zurückzugeben.
Es ist zwar nicht erforderlich, Puffer sofort an den Codec erneut zu übermitteln/freizugeben, während das Halten an Eingabe- und/oder Ausgabepuffern den Codec anhalten kann, und dieses Verhalten ist geräteabhängig. <stark,>es ist möglich, dass ein Codec das Generieren von Ausgabepuffern anhalten kann, bis <em>alle</em> ausstehenden Puffer freigegeben/erneut ausgegeben wurden.</strong> Versuchen Sie daher, die verfügbaren Puffer so wenig wie möglich zu halten.
Je nach API-Version können Sie Daten auf drei Arten verarbeiten: Tabelle>thead><tr><th>Verarbeitungsmodus</th<>>API-Version <= 20<br>Jelly Bean/KitKat</th th><>API Version >= 21<br>Lollipop und höher</th></tr></thead<>td tbody<>tr<>td>Synchron-API mit Pufferarrays</td td>><Supported</td<<><td>Deprecated</td></tr><td><>Synchron API using buffers</td td td<>class=NA>Not Available</td td td<>>Supported</td/tr td>><<><> Asynchronous API using buffers</td td<>td class=NA>Not Available</td><td>Supported</td<>/tr<>/tbody></table>
<h4>Asynchrone Verarbeitung mit Puffern</h4>
Da android.os.Build.VERSION_CODES#LOLLIPOP
die bevorzugte Methode die asynchrone Verarbeitung von Daten durch Festlegen eines Rückrufs vor dem Aufrufen #configure configure
ist. Der asynchrone Modus ändert die Zustandsübergänge geringfügig, da Sie nach #flush
dem Übergang des Codecs in den Unterzustand "Ausführen" aufrufen #start
und mit dem Empfangen von Eingabepuffern beginnen müssen. Entsprechend wird bei einem anfänglichen 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 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
…
codec.queueInputBuffer(inputBufferId, …);
}
{@literal @Override}
void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {
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.
…
codec.releaseOutputBuffer(outputBufferId, …);
}
{@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(…) {
…
}
{@literal @Override}
void onCryptoError(…) {
…
}
});
codec.configure(format, …);
mOutputFormat = codec.getOutputFormat(); // option B
codec.start();
// wait for processing to complete
codec.stop();
codec.release();
<h4>Synchrone Verarbeitung mit Puffern</h4>
Da android.os.Build.VERSION_CODES#LOLLIPOP
sollten Sie Eingabe- und Ausgabepuffer mithilfe #getInputBuffer getInput
/#getOutputBuffer OutputBuffer(int)
und/oder #getInputImage getInput
/#getOutputImage OutputImage(int)
sogar bei Verwendung des Codecs im synchronen Modus abrufen. Dies ermöglicht bestimmte Optimierungen durch das Framework, z. B. bei der Verarbeitung dynamischer Inhalte. Diese Optimierung ist deaktiviert, wenn Sie anrufen #getInputBuffers getInput
/#getOutputBuffers OutputBuffers()
.
<p class=note><strong>Note:</strong> do not mix the methods of using buffers and buffer arrays at the same time. Rufen Sie getInput
/OutputBuffers
insbesondere nur direkt nach #start
oder nach der Dequeuierung einer Ausgabepuffer-ID mit dem Wert von .#INFO_OUTPUT_FORMAT_CHANGED
MediaCodec wird in der Regel wie folgt im synchronen Modus verwendet:
MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
MediaFormat outputFormat = codec.getOutputFormat(); // option B
codec.start();
for (;;) {
int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
if (inputBufferId >= 0) {
ByteBuffer inputBuffer = codec.getInputBuffer(…);
// fill inputBuffer with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
int outputBufferId = codec.dequeueOutputBuffer(…);
if (outputBufferId >= 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.
…
codec.releaseOutputBuffer(outputBufferId, …);
} 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 mit Pufferarrays (veraltet)</h4>
In Versionen android.os.Build.VERSION_CODES#KITKAT_WATCH
und vorn werden die Eingabe- und Ausgabepuffer durch die ByteBuffer[]
Arrays dargestellt. Rufen Sie nach einem erfolgreichen Aufruf #start
die Pufferarrays mithilfe von/#getInputBuffers getInput
#getOutputBuffers OutputBuffers()
. Verwenden Sie die Puffer-ID als Indizes für diese Arrays (wenn nicht negativ), wie im folgenden Beispiel gezeigt. 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 obere Grenze bereitstellt.
MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();
for (;;) {
int inputBufferId = codec.dequeueInputBuffer(…);
if (inputBufferId >= 0) {
// fill inputBuffers[inputBufferId] with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
int outputBufferId = codec.dequeueOutputBuffer(…);
if (outputBufferId >= 0) {
// outputBuffers[outputBufferId] is ready to be processed or rendered.
…
codec.releaseOutputBuffer(outputBufferId, …);
} 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>Ende-of-Stream-Verarbeitung</h4>
Wenn Sie das Ende der Eingabedaten erreichen, müssen Sie sie an den Codec signalisieren, indem Sie das #BUFFER_FLAG_END_OF_STREAM
Flag im Aufruf #queueInputBuffer queueInputBuffer
angeben. Sie können dies für den letzten gültigen Eingabepuffer oder durch Senden eines zusätzlichen leeren Eingabepuffers mit dem End-of-Stream-Flagsatz tun. Wenn Sie einen leeren Puffer verwenden, wird der Zeitstempel ignoriert.
Der Codec gibt weiterhin Ausgabepuffer zurück, bis es schließlich das Ende des Ausgabedatenstroms signalisiert, indem das gleiche End-of-Stream-Flag im Set #dequeueOutputBuffer dequeueOutputBuffer
angegeben BufferInfo
oder über Callback#onOutputBufferAvailable onOutputBufferAvailable
diese zurü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 nach dem Signalisieren des Endes des Eingabedatenstroms keine zusätzlichen Eingabepuffer, es sei denn, der Codec wurde geleert oder beendet und neu gestartet.
<h4>Using an Output Surface</h4>
Die Datenverarbeitung ist nahezu identisch mit dem ByteBuffer-Modus bei Verwendung einer Ausgabe Surface
. Auf die Ausgabepuffer kann jedoch nicht zugegriffen werden und werden als null
Werte dargestellt. Beispielsweise #getOutputBuffer getOutputBuffer
/#getOutputImage Image(int)
wird ein Array zurückgegeben null
, #getOutputBuffers
das nur null
-s enthält.
Bei Verwendung einer Ausgabeoberfläche können Sie auswählen, ob jeder Ausgabepuffer auf der Oberfläche gerendert werden soll. Sie haben drei Auswahlmöglichkeiten: <ul><li><strong>Rendern Sie den Puffer nicht:</strong> Call #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, false)
.</li li>><<strong>Rendern Sie den Puffer mit dem Standardzeitstempel:</strong> Call.<#releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, true)
/li li><><strong>Rendern Sie den Puffer mit einem bestimmten Zeitstempel:</strong> Call.<#releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp)
/li></ul>
Da android.os.Build.VERSION_CODES#M
der Standardzeitstempel der BufferInfo#presentationTimeUs-Präsentationsstempel des Puffers ist (in Nanosekunden konvertiert). Sie wurde zuvor nicht definiert.
Außerdem android.os.Build.VERSION_CODES#M
können Sie die Ausgabeoberfläche dynamisch mithilfe von #setOutputSurface setOutputSurface
Surface ändern.
Beim Rendern der Ausgabe auf einem Surface kann das Surface so konfiguriert werden, dass übermäßige Frames fallen (die vom Surface nicht rechtzeitig verbraucht werden). Oder es kann so konfiguriert werden, dass keine übermäßigen Frames fallen. Im letzteren Modus wird der Decoder blockiert, wenn das Surface keine Ausgabeframes schnell genug verbraucht. android.os.Build.VERSION_CODES#Q
Vor dem genauen Verhalten wurde nicht definiert, mit der Ausnahme, dass View-Oberflächen (SurfaceView oder TextureView) immer übermäßige Frames verworfen haben. Da android.os.Build.VERSION_CODES#Q
das Standardverhalten darin besteht, übermäßige Frames abzulegen. 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
adressieren und den Schlüssel MediaFormat#KEY_ALLOW_FRAME_DROP
0
in ihrem Konfigurationsformat festlegen.
<h4-Transformationen>beim Rendern auf Surface</h4>
Wenn der Codec im Surface-Modus konfiguriert ist, werden alle Zuschneiderechtecke, MediaFormat#KEY_ROTATION Drehung 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 möglicherweise nicht angewendet, wenn sie auf einem Surface gerendert wird. Leider gibt es keine Standard- und einfache Möglichkeit zum Identifizieren von Softwaredecodern oder wenn sie die Drehung anwenden, als es auszuprobieren.
Es gibt auch einige Vorbehalte. <p class=note> : The pixel aspect ratio is not considered when displaying the output to the Surface. Dies bedeutet, dass Sie, wenn Sie den Modus verwenden #VIDEO_SCALING_MODE_SCALE_TO_FIT
, die Ausgabeoberfläche so positionieren müssen, dass es das richtige endgültige Seitenverhältnis für die Anzeige aufweist. Umgekehrt können Sie den Modus nur für Inhalte mit Quadratpixeln (Pixelseitenverhältnis oder 1:1) verwenden #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
. <p class=note> Beachten Sie auch, dass der Modus ab der android.os.Build.VERSION_CODES#N
Veröffentlichung für Videos, die um 90 oder 270 Grad gedreht wurden, #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
möglicherweise nicht ordnungsgemäß funktioniert. <p class=note> When setting the video scaling mode, note that it must be reset after when the output buffers change. 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>
Bei Verwendung einer Eingabeoberfläche gibt es keine barrierefreien Eingabepuffer, da Puffer automatisch von der Eingabeoberfläche an den Codec übergeben werden. Das Aufrufen #dequeueInputBuffer dequeueInputBuffer
löst ein IllegalStateException
, und #getInputBuffers
gibt ein gefälschtes ByteBuffer[]
Array zurück, in das <starke>NICHT/stark> geschrieben werden muss<.
Anruf #signalEndOfInputStream
zum Signalende des Datenstroms. Die Eingabeoberfläche beendet das Senden von Daten an den Codec unmittelbar nach diesem Aufruf.
<h3>Suchen & Unterstützung< für adaptive Wiedergabe/h3>
Videodecoder (und in allgemeinen Codecs, die komprimierte Videodaten nutzen) verhalten sich anders hinsichtlich der Such- und Formatänderung, unabhängig davon, ob sie diese 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)
. Die Unterstützung der adaptiven Wiedergabe für Videodecoder wird nur aktiviert, wenn Sie den Codec so konfigurieren, dass er auf ein Surface
Decodierungszeichen gesetzt wird.
<h4 id=KeyFrames>"KeyFrames">Stream Boundary and KeyFrames</h4>
Es ist wichtig, dass die Eingabedaten nach #start
oder #flush
an einer geeigneten Datenstromgrenze beginnen: Der erste Frame muss ein Keyframe sein. Ein <em>keyframe</em> kann vollständig eigenständig decodiert werden (für die meisten Codecs bedeutet dies ein I-Frame), und keine Frames, die nach einem Keyframe auf Frames vor dem Keyframe angezeigt werden sollen.
In der folgenden Tabelle sind geeignete Keyframes für verschiedene Videoformate zusammengefasst. <table>thead><tr><th>Format</th<>>Passender Keyframe</th<>/tr<>/thead><tbody class=mid<>tr<>td>VP9/VP8</td td><>a suitable intraframe where no subsequent frames refer to frames prior to this frame.<<br>(Für diesen Keyframe gibt es keinen spezifischen Namen.)</td></tr td><<>>H.265 HEVC</td td>><IDR or CRA</td/tr<>td>><<> H.264 AVC</td><td>IDR</td<>/tr><<>td>MPEG-4<br>H.263<br>MPEG-2</td td td<>>a suitable I-frame where no subsequent frames refer to frames prior to this frame.<br>(Für diesen Keyframe gibt es keinen spezifischen Namen.)</td></tr></tbody></table>
<h4>Für Decoder, die die adaptive Wiedergabe nicht unterstützen (einschließlich der Decodierung auf einem Surface)</h4>
Um mit der Decodierung von Daten zu beginnen, die nicht neben zuvor übermittelten Daten (d. h. nach einer Suche) stehen, müssen>< Sie <den Decoder stark>leeren. Da alle Ausgabepuffer sofort an der Stelle des Leerens widerrufen werden, sollten Sie zuerst auf das Ende des Datenstroms warten, bevor Sie aufrufen flush
. Es ist wichtig, dass die Eingabedaten nach einem Leeren an einer geeigneten Datenstromgrenze/keyframe beginnen. <p class=note>strong Note:</strong> the format of the data submitted after a flush must not change; #flush
does not support format diskities; for that, a full #stop
- #start
#configure configure(…)
- cycle is necessary.><
<p class=note><strong>Also note:</strong> if you flush the codec too soon after #start
– generally, before the first output buffer or output format change is received – you will need to resubmit the codec-specific-data to the codec. Weitere Informationen finden Sie im Abschnitt "Codecspezifische Daten".
<h4>Für Decoder, die adaptive Wiedergabe</h4 unterstützen und konfiguriert sind>
Um mit der Decodierung von Daten zu beginnen, die nicht neben zuvor übermittelten Daten (d. h. nach einer Suche) stehen, ist <>es nicht erforderlich</em>, den Decoder zu leeren. Eingabedaten nach der Einstellung müssen jedoch bei einer geeigneten Datenstromgrenze/keyframe beginnen.
Bei einigen Videoformaten – h.264, H.265, VP8 und VP9 – ist es auch möglich, die Bildgröße oder Die Konfiguration mitte des Datenstroms zu ändern. Dazu müssen Sie die gesamten neuen codecspezifischen 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 #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>Note:</strong> just as the case for codec-specific data, be careful when calling #flush
shortly after you have changed the picture size. Wenn Sie keine Bestätigung der Ä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
Auslösen IOException
eines Fehlers, den Sie abfangen oder deklarieren müssen, um die Übergabe durchzuführen. MediaCodec-Methoden werden ausgelöst IllegalStateException
, wenn die Methode aus einem Codecstatus aufgerufen wird, der sie nicht zulässt. Dies liegt in der Regel an einer falschen Anwendungs-API-Verwendung. Methoden mit sicheren Puffern können ausgelöst CryptoException
werden, die weitere Fehlerinformationen enthalten, die abgerufen CryptoException#getErrorCode
werden können.
Interne Codecfehler führen zu einer CodecException
Beschädigung von Medieninhalten, Hardwarefehlern, Ressourcenausschöpfung usw. auch dann, wenn die Anwendung die API ordnungsgemäß verwendet. Die empfohlene Aktion beim Empfang einer CodecException
Aktion kann durch Aufrufen CodecException#isRecoverable
und CodecException#isTransient
: <ul<>li><starke>wiederherstellbare Fehler bestimmt werden:</strong> Wenn isRecoverable()
wahr, dann aufrufen #stop
, #configure configure(…)
aufrufen und #start
wiederherstellen.</li li><><starke>vorübergehende Fehler:</strong> Wenn isTransient()
"true" zurückgegeben wird, sind Ressourcen vorübergehend nicht verfügbar, und die Methode kann zu einem späteren Zeitpunkt erneut überprüft werden.</li li><><starke>schwerwiegende Fehler:</strong> Wenn beide isRecoverable()
und isTransient()
"false" zurückgegeben werden, ist dies CodecException
schwerwiegend, und der Codec muss #reset zurückgesetzt oder #release freigegeben werden.</li></ul>
Beide isRecoverable()
und isTransient()
geben nicht gleichzeitig wahr 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. Informationen zu 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: bottom left 0; width: 30px; height: 20px; } .deg45 > div div > 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/th></tr></thead<>tbody class=sml><tr><td>●</td td><>Supported</td></tr>><<td>⁕</td><td>Semantics changed</td></tr td>><<>○</td><td>Experimental support</td></tr td><>><[ ]</td td td><>Deprecated</td/tr td><<><>&td>⎋</td td>><Restricted to 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><td>><↩</td td Eingeschränkt auf synchronen Modus</td></tr td><>><⇄<><>/td td>><Restricted to asynchron mode</td></tr td>><><( )</td td td><>Can be called, but shouldn'td</td></tr<>/tbody></table>
<Tabellenformat="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 th<>class=deg45><div div><style="background:#e67c73"><div>Flushed</div></div><></th><class=deg45><div div><style="background:#0f9d58"><div>Running</div></div/div><></th><class=deg45><div div><style="background:#f7cb4d"><div>End of Stream</div></div><></th th<>class=deg45><div div><style="background:#db4437"><div Error</div><>/div></div></th th><class=deg45><div div><style="background:#666"><div style="div>Released</div></div></div></th th>><</th<>colspan="8">SDK Version</th></tr tr><><th colspan="7">State</<>th th><<> 16/th>16</th><17</<>>th>18</<>>th 19/th 19</<>th>20</th><21</th 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><class=fn#createByCodecName createByCodecName
<>/td td td td>><●</td><>●</td><>●</td><>●</td><>●</td><>●</td><>●</td><>●</td></tr><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></tr><td<><>/td<>td></td<>td></td td<>/td><<> td/td><<> td td/td td></td><><>< td class=fn><#createEncoderByType createEncoderByType
/td td td<>>●</td><>●</td><>●</td><>●</td><>●</td><>●</td><>●</td><>●</td></tr><><td></td<>td></><td>< td/td td>><</td<>td></td><td>< td/td<>td></td><td<<><>><><><<><><#createPersistentInputSurface createPersistentInputSurface
<>><>>/td td td/td td/td td/td><>< td/td td/td td/td><>< td/td><td>●</td></tr><td<>>16+</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></tr><><td>-</td<>td>18+</td td><>-</td<>td>-/td td>-</td><td>-</><td td>-</td<>td-</td<<#createInputSurface createInputSurface
><>> td>><</td><td><>⎋</td><>⎋</td><>⎋</td><>⎋</td><>⎋</td><>⎋</td></tr><<>td>-</td><td>-</td<>td>16+</td<>td>16+</td td>(16+)</td>><<td>-</td<>> td-</td<>td class=fn<#dequeueInputBuffer dequeueInputBuffer
>/td td td><>●</td><>●</td><>▧</td><>▧</td><>▧</td><>⁕ ▧ ↩</td><>▧ ↩</td><>▧ ↩</td></tr>><<td>-</td><td>-</td><td>16+</td><td>16+</td><td>16+</td><td>-/td td-<</><><>td td class=fn><#dequeueOutputBuffer dequeueOutputBuffer
/td td<>td>●</td><>●</td><>●</td><>●</td><>●</td><>⁕ ↩</td><>↩</td><>↩</td></tr>><<td>-</td><td>-</td><td>16+</td><td>16+</td><td>16+</td><td>-/td td-<</><><>td td class=fn><#flush flush
/td td<>td>●</td><>●</td><>●</td><>●</td><>●</td><>●</td><>●</td><>●</td></tr td><<>>18+</td><td>18+</td td><>18+</td td<>>18+</td td<>>18+</td><td>18+</td td><td>-</td><td class=fn>#getCodecInfo getCodecInfo
</td<>td></td><td>><&><#9679;</td><>●</td><>●</td><>●</td><>●</td><>●</td></tr><td><>-</td><td>-</td><td>(21+)</td td><td>21+</td><td>(21+)</td><td>-</<>>td td-</td><td class=fn>#getInputBuffer getInputBuffer
</td td>><</td><td></td><td></td td/<>td><><td></td><>●</td><>●</td><>●</td></tr><><td>-</td<>td>-</td<>td>16+</td td><>(16+)</td><td>(16+)</td td><> td-</td<>> td-</td<>td class=fn<>#getInputBuffers getInputBuffers
/td td td>><●</td><>●</td><>●</td><>●</td><>●</td><>[⁕ ↩]</td><>[↩]</td><>[↩]</td></tr><td>><-</td><td>21+</td td><>(21+)</td td>><(21+)</td><td>(21+)</><td td>-</td<>td> td-</td<>td class=fn><#getInputFormat getInputFormat
/td><td></td<>td></td><>< td/td td/><><td><td></td><>●</td><>●</td><>●</td></tr><><td>-</td><td>-</td><td>(21+)</td><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></tr td>>><<18+</td<>td>18+</td td<>>18+</td><td>18+</td><td>18+</td><td>18+</td td<>td>-</td><td class=fn>#getName getName
</td<>td></td t><<>><>●</td><>●</td><>●</td><>●</td><>●</td><>●</td></tr><<>td>-</td<>td>-</td<>td>(21+)</td td td>><21+</td td>21+</td>><<td>-</td>>< td td-</td><td class=fn>#getOutputBuffer getOutputBuffer
</td td<>td></td<>td td><><></Td><td></td><td><>< td>●</td><>●</td><>●</td></tr>><<td>-</td><td>-</td><td>16+</td><td>16+</td><td>16+</td><td>-/td td-<</><><>td td class=fn><#getOutputBuffers getOutputBuffers
/td td<>td>●</td><>●</td><>●</td><>●</td><>●</td><>[⁕ ↩]</td><>[↩]</td><>[↩]</td></tr><><td>-</td<>td>21+</td td><>16+</td td><td>16+</td><td>16+</td><td>-</td<>td>-</td td><class=fn><#getOutputFormat()
/td td td<>>●</td><>●</td><>●</td><>●</td><>●</td><>●</td><>●</td><>●</td></tr><<>td>-</td<>td>-</td<>td>(21+)</td td td>><21+</td td>21+</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></tr><<>td>-</td<>td>-</td<>td>(21+)</td td td>><21+</td td>21+</td>><<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></tr><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></tr><td><>-</td<>td>-</td><td-</td<>> td>16+</td td>><(16+)</td><td>-/td><td>-<</><td td class=fn><#queueSecureInputBuffer queueSecureInputBuffer
/td td<>>●</td><>●</td><>●</td><>●</td><>●</td><>⁕</td><>●</td><>●</td></tr td<>><>16+</td<>td>16+</td td>><16+</td td<>>16+</td td>16+</td<>><td>16+</td<>td>16+</td td td><class=fn><#release release
/td td td<>>●</td><>●</td><>●</td><>●</td><>●</td><>●</td><>●</td><>●</td></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></tr><><td>-</td<>td>-</td><td>-</td<>td>21+</td><td>21+</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 td<<>>>21+</td><td>21+</td td><>21+</td><td>21+/td td><>21+<</><td td>21+</td td<>td>-</td><td class=fn>#reset reset
</td<>td></td t><<>><></Td><td></td><td><>< td>●</td><>●</td><>●</td></tr><td><>21+</td<>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><#setCallback(Callback, Handler) ⁕
/td></tr>><<t td>-</td><td>23+</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/td td><><>⎋</td></tr td<>>><23+</td><td>23+</td td>><23+</td td><>23+</td td<>>23+</td><td>(23+)</td td><>(23+)</td td<>td class=fn><#setOnFrameRenderedListener setOnFrameRenderedListener
/td><td></td<>td/td><><td></td><td></td><td></td><td></td td><td/td<>td><>○ ⎆</td></tr><><td>-</td<>td>23+</td td><>23+</td td><td>23+</td><td>23+</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>><⎆</td></tr td><>><19+</td><td>19+</td td>><19+</td<>td>19+</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></tr><td>><-</td td>><(16+)</td td>><(16+)</td td><>16+</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></tr td><><>(29+)</td><td>29+</td><td td>29+</td><td>29+</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></tr><td>><><-/td td><td td><-</td><td>18+</><<<>>td td td-/td td>-</td td 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></tr td<>>><-</td><td>16+</td td><>21+(⇄)</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></tr>><<td>-</td><td>-</td><td>16+</td><td>16+</td><td>16+</td><td>-/td td-<</><><>td td class=fn><#stop stop
/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 auf der Grundlage von Arbeiten, die vom Android Open Source-Projekt erstellt und freigegeben werden und gemäß den in der Creative Commons 2.5 Attribution License beschriebenen Begriffen verwendet werden.
Felder
BufferFlagCodecConfig |
Veraltet.
Dies hat angegeben, dass der als solche markierte Puffer Codecinitialisierung /Codec-spezifische Daten anstelle von Mediendaten 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 Datenstroms, i. |
BufferFlagKeyFrame |
Veraltet.
Dies gibt an, dass der (codierte) Puffer, der als solche gekennzeichnet 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 sollte die Daten stapeln, bis ein Puffer ohne dieses Flag vor der Decodierung des Frames angezeigt wird. |
BufferFlagSyncFrame |
Veraltet.
Dies gibt an, dass der (codierte) Puffer, der als solche gekennzeichnet 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 |
ConfigureFlagUseCryptoAsync |
Veraltet.
Dieses Kennzeichen sollte nur für einen sicheren Decoder verwendet werden. |
CryptoModeAesCbc |
Veraltet.
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. |
CryptoModeAesCtr | |
CryptoModeUnencrypted | |
InfoOutputBuffersChanged |
Veraltet.
Die Ausgabepuffer haben sich geändert, der Client muss auf den neuen Satz von Ausgabepuffern verweisen, der |
InfoOutputFormatChanged |
Veraltet.
Das Ausgabeformat wurde geändert, nachfolgende Daten folgen dem neuen Format. |
InfoTryAgainLater |
Veraltet.
Wenn im Aufruf |
ParameterKeyHdr10PlusInfo |
Legen Sie die HDR10+-Metadaten für den nächsten in die Warteschlange eingereihten Eingabeframe fest. |
ParameterKeyLowLatency |
Aktivieren/Deaktivieren des Decodierungsmodus mit geringer Latenz. |
ParameterKeyOffsetTime |
Geben Sie einen Offset (in Mikro-Sekunde) an, der über den Zeitstempeln hinzugefügt werden soll. |
ParameterKeyRequestSyncFrame |
Fordern Sie an, dass der Encoder einen Synchronisierungsrahmen "bald" erzeugt. |
ParameterKeySuspend |
Vorübergehendes Anhalten/Fortsetzen der Codierung von Eingabedaten. |
ParameterKeySuspendTime |
Wenn |
ParameterKeyTunnelPeek |
Steuern des Videopopups des ersten Frames, wenn ein Codec für den Tunnelmodus konfiguriert ist, |
ParameterKeyVideoBitrate |
Ändern Sie die Zielbitrate eines Video-Encoders unterwegs. |
VideoScalingModeScaleToFit |
Veraltet.
Der Inhalt wird auf die Oberflächenabmessungen skaliert. |
VideoScalingModeScaleToFitWithCropping |
Veraltet.
Der Inhalt wird skaliert, das Seitenverhältnis beibehalten, der gesamte Oberflächenbereich wird verwendet, der Inhalt kann zugeschnitten werden. |
Eigenschaften
CanonicalName |
Rufen Sie den zugrunde liegenden Codecnamen ab. |
Class |
Gibt die Laufzeitklasse dieses Werts |
CodecInfo |
Rufen Sie die Codec-Informationen ab. |
Handle |
Das Handle für die zugrunde liegende Android-Instanz. (Geerbt von Object) |
InputFormat |
Rufen Sie dies nach |
JniIdentityHashCode |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
JniPeerMembers |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. |
Metrics |
Gibt Metrikdaten zur aktuellen Codecinstanz zurück. |
Name |
Rufen Sie den Codecnamen ab. |
OutputFormat |
Rufen Sie dies nach dequeueOutputBuffer signalisiert eine Formatänderung durch Zurückgeben |
PeerReference |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
SupportedVendorParameters |
Gibt eine Liste der Lieferantenparameternamen 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 für die Verwendung mit einem Descrambler. |
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 an einen Encoder verwendet werden soll. |
CreatePersistentInputSurface() |
Erstellen Sie eine dauerhafte Eingabeoberfläche, die mit Codecs verwendet werden kann, die normalerweise über eine Eingabeoberfläche verfügen, z. B. Video-Encoder. |
DequeueInputBuffer(Int64) |
Gibt den Index eines Eingabepuffers zurück, der mit gültigen Daten oder -1 gefüllt werden soll, wenn derzeit kein solcher Puffer verfügbar ist. |
DequeueOutputBuffer(MediaCodec+BufferInfo, Int64) |
Dequeue an output buffer, block at most "timeoutUs" microseconds. |
Dispose() |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
Dispose(Boolean) |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
Equals(Object) |
Gibt an, ob ein anderes Objekt "gleich" diesem Objekt ist. (Geerbt von Object) |
Flush() |
Leeren Sie die Eingabe- und Ausgabeports der Komponente. |
GetHashCode() |
Gibt einen Hashcodewert für das Objekt zurück. (Geerbt von Object) |
GetInputBuffer(Int32) |
Gibt ein |
GetInputBuffers() |
Veraltet.
Dient zum Abrufen des Satzes von Eingabepuffern. |
GetInputImage(Int32) |
Gibt ein schreibbares Image -Objekt für einen entqueuierten Eingabepufferindex zurück, der den rohen Eingabevideoframe enthalten soll. |
GetOutputBuffer(Int32) |
Gibt einen schreibgeschützten ByteBuffer für einen dequeuierten Ausgabepufferindex zurück. |
GetOutputBuffers() |
Veraltet.
Ruft den Satz von Ausgabepuffern ab. |
GetOutputFormat(Int32) |
Gibt das Ausgabeformat für einen bestimmten Ausgabepuffer zurück. |
GetOutputFrame(Int32) |
Gibt ein |
GetOutputImage(Int32) |
Gibt ein schreibgeschütztes Image -Objekt für einen dequeuierten Ausgabepufferindex zurück, der den rohen Videoframe enthält. |
GetParameterDescriptor(String) |
Beschreiben Sie einen Parameter mit dem Namen. |
GetQueueRequest(Int32) |
Zurückgeben eines |
JavaFinalize() |
Wird vom Garbage Collector für ein Objekt aufgerufen, wenn die Garbage Collection bestimmt, dass keine weiteren Verweise auf das Objekt vorhanden sind. (Geerbt von Object) |
MapHardwareBuffer(HardwareBuffer) |
Ordnen Sie ein |
Notify() |
Aktiviert einen einzelnen Thread, der auf dem Monitor dieses Objekts wartet. (Geerbt von Object) |
NotifyAll() |
Aktiviert alle Threads, die auf dem Monitor dieses Objekts warten. (Geerbt von Object) |
QueueInputBuffer(Int32, Int32, Int32, Int64, MediaCodecBufferFlags) |
Nach dem Ausfüllen eines Bereichs des Eingabepuffers am angegebenen Index übermitteln sie an die Komponente. |
QueueSecureInputBuffer(Int32, Int32, MediaCodec+CryptoInfo, Int64, MediaCodecBufferFlags) |
Ähnlich wie |
Release() |
Freigeben von Ressourcen, die von der Codecinstanz 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 auf der Ausgabeoberfläche zu rendern. |
ReleaseOutputBuffer(Int32, Int64) |
Wenn Sie mit einem Puffer fertig sind, verwenden Sie diesen Aufruf, um den Zeitstempel der Oberfläche zu aktualisieren und an den Codec zurückzugeben, um ihn auf der Ausgabeoberfläche zu rendern. |
Reset() |
Gibt den Codec an den ursprünglichen (nicht initialisierten) Zustand zurück. |
SetAudioPresentation(AudioPresentation) |
Legt die Audiopräsentation fest. |
SetCallback(MediaCodec+Callback) |
Legt einen asynchronen Rückruf für Aktionen erfordernde MediaCodec-Ereignisse für die Standardschleife fest. |
SetCallback(MediaCodec+Callback, Handler) |
Legt einen asynchronen Rückruf für Aktionen erfordernde MediaCodec-Ereignisse für die Standardschleife fest. |
SetHandle(IntPtr, JniHandleOwnership) |
Legt die Handle-Eigenschaft fest. (Geerbt von Object) |
SetInputSurface(Surface) |
Konfiguriert den Codec (e. |
SetOnFirstTunnelFrameReadyListener(Handler, MediaCodec+IOnFirstTunnelFrameReadyListener) |
Registriert einen Rückruf, der aufgerufen werden soll, wenn der erste Ausgabeframe decodiert wurde und bereit ist, auf einem für den Tunnelmodus |
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 Codec dynamisch fest. |
SetParameters(Bundle) |
Kommunizieren Sie zusätzliche Parameteränderungen an der Komponenteninstanz. |
SetVideoScalingMode(VideoScalingMode) |
Wenn in einem vorherigen Aufruf eine Oberfläche angegeben wurde, um |
SignalEndOfInputStream() |
Signal des Endes des Datenstroms bei der Eingabe. |
Start() |
Rufen Sie nach der erfolgreichen Konfiguration der Komponente auf |
Stop() |
Beenden Sie die Decodierungs-/Codierungssitzung, beachten Sie, dass die Codecinstanz aktiv bleibt und wieder ed werden |
SubscribeToVendorParameters(IList<String>) |
Abonnieren Sie Lieferantenparameter, damit diese Parameter vorhanden |
ToArray<T>() |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
ToString() |
Gibt eine Zeichenfolgendarstellung des Objekts zurück. (Geerbt von Object) |
UnregisterFromRuntime() |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
UnsubscribeFromVendorParameters(IList<String>) |
Kündigen Sie das Abonnement von Lieferantenparametern, damit diese Parameter nicht vorhanden |
Wait() |
Bewirkt, dass der aktuelle Thread wartet, bis er wach ist, in der Regel durch em benachrichtigt/em> oder <em>unterbrochen</em>.<>< (Geerbt von Object) |
Wait(Int64) |
Bewirkt, dass der aktuelle Thread wartet, bis er wach ist, in der Regel durch <em>benachrichtigt</em> oder <em>unterbrochen</em> oder bis eine bestimmte Menge an Echtzeit verstrichen ist. (Geerbt von Object) |
Wait(Int64, Int32) |
Bewirkt, dass der aktuelle Thread wartet, bis er wach ist, in der Regel durch <em>benachrichtigt</em> oder <em>unterbrochen</em> oder bis eine bestimmte Menge an Echtzeit verstrichen ist. (Geerbt von Object) |
Explizite Schnittstellenimplementierungen
IJavaPeerable.Disposed() |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
IJavaPeerable.DisposeUnlessReferenced() |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
IJavaPeerable.Finalized() |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
IJavaPeerable.JniManagedPeerState |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
IJavaPeerable.SetJniIdentityHashCode(Int32) |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
IJavaPeerable.SetPeerReference(JniObjectReference) |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. (Geerbt von Object) |
Erweiterungsmethoden
JavaCast<TResult>(IJavaObject) |
Führt eine android-laufzeitgecheckte Typkonvertierung aus. |
JavaCast<TResult>(IJavaObject) |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. |
GetJniTypeName(IJavaPeerable) |
MediaCodec-Klasse kann verwendet werden, um auf Mediencodecs auf niedriger Ebene zuzugreifen, i. |