Condividi tramite


MediaCodec Classe

Definizione

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, 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
Ereditarietà
MediaCodec
Attributi

Commenti

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, ad esempio i componenti codificatore/decodificatore. Fa parte dell'infrastruttura di supporto multimediale di basso livello di Android (normalmente usata insieme a MediaExtractor, MediaMuxerMediaSync, MediaCrypto, MediaDrm, Image, Surfacee AudioTrack.)

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

In termini generali, un codec elabora i dati di input per generare dati di output. Elabora i dati in modo asincrono e usa un set di buffer di input e output. A livello semplicistico, si richiede (o si riceve) un buffer di input vuoto, lo si riempie di dati e lo si invia al codec per l'elaborazione. Il codec usa i dati e lo trasforma in uno dei relativi buffer di output vuoti. Infine, richiedi (o ricevi) un buffer di output riempito, utilizzane il contenuto e rilascialo al codec.

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

android.os.Build.VERSION_CODES#SA partire da , Video MediaCodecs di Android applica un piano di qualità minimo. Lo scopo è eliminare le codifiche video di qualità scarsa. Questo piano di qualità viene applicato quando il codec è in modalità VBR (Variable Bitrate); non viene applicato quando il codec è in modalità CBR (Constant Bitrate). L'applicazione del piano di qualità è limitata anche a un determinato intervallo di dimensioni; questo intervallo di dimensioni è attualmente destinato alle risoluzioni video superiori a 320x240 fino a 1920x1080.

Quando questo piano di qualità è attivo, il codec e il codice del framework di supporto funzioneranno per garantire che il video generato sia di almeno una qualità "equa" o "buona". La metrica usata per scegliere queste destinazioni è la funzione VMAF (Video Multi-method Assessment Function) con un punteggio di destinazione pari a 70 per le sequenze di test selezionate.

L'effetto tipico è che alcuni video genereranno una velocità in bit superiore a quella originariamente configurata. Questo sarà più importante per i video configurati con velocità in bit molto bassa; il codec userà una velocità in bit determinata per generare un video di qualità "equo" o "buono". Un'altra situazione è la posizione in cui un video include contenuti molto complessi (un sacco di movimento e dettagli); in tali configurazioni, il codec userà una velocità in bit aggiuntiva in base alle esigenze per evitare di perdere tutti i dettagli più dettagliati del contenuto.

Questo piano di qualità non influirà sul contenuto acquisito a velocità in bit elevata (una velocità in bit elevata dovrebbe già fornire al codec una capacità sufficiente per codificare tutti i dettagli). Il piano di qualità non opera sulle codifiche CBR. Il pavimento di qualità attualmente non funziona su risoluzioni di 320x240 o inferiore, né su video con risoluzione superiore a 1920x1080.

<h3>Tipi di< dati/h3>

I codec operano su tre tipi di dati: dati compressi, dati audio non elaborati e dati video non elaborati. È possibile elaborare tutti e tre i tipi di dati usando ByteBuffer ByteBuffers, ma è consigliabile usare per Surface i dati video non elaborati per migliorare le prestazioni del codec. Surface usa buffer video nativi senza eseguirne il mapping o copiarli in ByteBuffers; così, è molto più efficiente. Normalmente non è possibile accedere ai dati video non elaborati quando si usa un dispositivo Surface, ma è possibile usare la ImageReader classe per accedere a fotogrammi video non protetti decodificati (non elaborati). Questo può essere ancora più efficiente rispetto all'uso di ByteBuffers, perché è possibile eseguire il mapping di alcuni buffer nativi in ByteBuffer#isDirect direct ByteBuffers. Quando si usa la modalità ByteBuffer, è possibile accedere ai fotogrammi video non elaborati usando la Image classe e/#getInputImage getInput#getOutputImage OutputImage(int) .

<h4>Compressed Buffers</h4>

I buffer di input (per decodificatori) e i buffer di output (per i codificatori) contengono dati compressi in base al tipo di formato MediaFormat#KEY_MIME. Per i tipi di video si tratta in genere di un singolo fotogramma video compresso. Per i dati audio si tratta in genere di una singola unità di accesso (un segmento audio codificato che contiene in genere alcuni millisecondi di audio come dettato dal tipo di formato), ma questo requisito è leggermente rilassato in quanto un buffer può contenere più unità di accesso codificate dell'audio. In entrambi i casi, i buffer non iniziano o terminano su limiti di byte arbitrari, ma piuttosto sui limiti di unità di frame/accesso, a meno che non siano contrassegnati con #BUFFER_FLAG_PARTIAL_FRAME.

<h4>Buffer< audio non elaborati/h4>

I buffer audio non elaborati contengono interi fotogrammi di dati audio PCM, un esempio per ogni canale in ordine di canale. Ogni esempio audio PCM è un intero con segno a 16 bit o float, in ordine di byte nativo. I buffer audio non elaborati nella codifica PCM float sono possibili solo se MediaFormat#KEY_PCM_ENCODING è impostato su AudioFormat#ENCODING_PCM_FLOAT durante MediaCodec #configure configure(&hellip;) e confermato da #getOutputFormat per decodificatori o #getInputFormat codificatori. Un metodo di esempio per verificare la presenza di PCM float in MediaFormat è il seguente:

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

Per estrarre, in una matrice breve, un canale di un buffer contenente dati audio audio con segno a 16 bit, è possibile usare il codice seguente:

// 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>Buffer< video non elaborati/h4>

I buffer video in modalità ByteBuffer vengono disposti in base al formato di colore MediaFormat#KEY_COLOR_FORMAT. È possibile ottenere i formati di colore supportati come matrice da #getCodecInfo..MediaCodecInfo#getCapabilitiesForType getCapabilitiesForType(&hellip;)CodecCapabilities#colorFormats colorFormats. I codec video possono supportare tre tipi di formati di colore: ul>li strong native video format:</strong> Questo è contrassegnato da CodecCapabilities#COLOR_FormatSurface e può essere usato con un surface di input o output.<>><<<Buffer YUV/strong flessibili /li li><><(>ad esempioCodecCapabilities#COLOR_FormatYUV420Flexible): possono essere usati con una superficie di input/output, nonché in modalità ByteBuffer, usando #getInputImage getInput.#getOutputImage OutputImage(int)</></li><li><strong>other, specific formats:</strong> Questi sono in genere supportati solo in modalità ByteBuffer. Alcuni formati di colore sono specifici del fornitore. Altri sono definiti in CodecCapabilities. Per i formati di colore equivalenti a un formato flessibile, è comunque possibile usare #getInputImage getInput/#getOutputImage OutputImage(int).</li></ul>

Tutti i codec video supportano buffer YUV 4:2:0 flessibili a partire da android.os.Build.VERSION_CODES#LOLLIPOP_MR1.

<h4>Accesso a byteBuffer video non elaborati nei dispositivi< meno recenti/h4>

android.os.Build.VERSION_CODES#LOLLIPOP Prima di e supportare, è necessario usare i valori del MediaFormat#KEY_STRIDE formato di output e ImageMediaFormat#KEY_SLICE_HEIGHT per comprendere il layout dei buffer di output non elaborati. <p class=nota: in> alcuni dispositivi l'altezza della sezione viene pubblicizzata come 0. Ciò potrebbe significare che l'altezza della sezione corrisponde all'altezza del fotogramma o che l'altezza del fotogramma è l'altezza del fotogramma allineata a un valore (in genere una potenza di 2). Sfortunatamente, non esiste un modo standard e semplice per indicare l'altezza effettiva della sezione in questo caso. Inoltre, lo stride verticale del U piano in formati planari non è specificato o definito, anche se in genere è metà dell'altezza della sezione.

I MediaFormat#KEY_WIDTH tasti e MediaFormat#KEY_HEIGHT specificano le dimensioni dei fotogrammi video. Per la maggior parte dei casi, tuttavia, il video (immagine) occupa solo una parte del fotogramma video. Questo è rappresentato dal "rettangolo di ritaglio".

È necessario usare le chiavi seguenti per ottenere il rettangolo di ritaglio delle immagini di output non elaborate dal formato di output #getOutputFormat. Se queste chiavi non sono presenti, il video occupa l'intero fotogramma video. Il rettangolo di ritaglio viene compreso nel contesto del frame <di output em>prima< dell'applicazione> di qualsiasi rotazione MediaFormat#KEY_ROTATION. <table style="width: 0%">thead><tr<>th>Format Key</th>><Type</th th<>>Description</th/th<>/tr/thead><tbody><tr<<>> tdMediaFormat#KEY_CROP_LEFT<>/td td><>Integer</td td<>>La coordinata sinistra (x) del rettangolo di ritaglio</td<>/tr><><td<MediaFormat#KEY_CROP_TOP>/td td><>Integer/<< td><td>La coordinata superiore (y) del rettangolo di ritaglio</td></tr>><<td><MediaFormat#KEY_CROP_RIGHT Integer</>><td>><La coordinata destra (x) forte>MENO 1/forte> del rettangolo di ritaglio</td<>/tr<><>tr td<>MediaFormat#KEY_CROP_BOTTOM/td<>td Integer</td td>><>La coordinata inferiore (y) <<forte>MENO 1<</forte> del rettangolo di ritaglio</td></tr tr<><>td colspan=3> Le coordinate destra e inferiore possono essere interpretate come coordinate della colonna più valida o inferiore valida dell'immagine di output ritagliata. </td></tr></tbody></table>

Le dimensioni del fotogramma video (prima della rotazione) possono essere calcolate come segue:

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=nota Si noti> anche che il significato di BufferInfo#offset BufferInfo.offset non era coerente tra i dispositivi. In alcuni dispositivi l'offset puntava al pixel superiore sinistro del rettangolo di ritaglio, mentre nella maggior parte dei dispositivi puntava al pixel superiore sinistro dell'intero fotogramma.

<h3>States</h3>

Durante la sua vita esiste un codec concettualmente in uno dei tre stati: Arrestato, Esecuzione o Rilasciato. Lo stato collettivo Arrestato è in realtà il conglomerato di tre stati: Non inizializzato, Configurato ed Errore, mentre lo stato Di esecuzione avanza concettualmente attraverso tre stati secondari: Flushed, Running e End-of-Stream.

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

Quando si crea un codec usando uno dei metodi factory, il codec si trova nello stato Uninitialized. Prima di tutto, è necessario configurarlo tramite #configure configure(&hellip;), che lo porta allo stato Configurato, quindi chiamare #start per spostarlo nello stato In esecuzione. In questo stato è possibile elaborare i dati tramite la manipolazione della coda del buffer descritta in precedenza.

Lo stato Esecuzione ha tre stati secondari: Flushed, Running e End-of-Stream. Immediatamente dopo #start che il codec è nello stato secondario Flushed, in cui contiene tutti i buffer. Non appena viene dequeuato il primo buffer di input, il codec passa allo stato secondario In esecuzione, dove trascorre la maggior parte della durata. Quando si accoda un buffer di input con il marcatore di fine flusso #BUFFER_FLAG_END_OF_STREAM, il codec passa allo stato secondario End-of-Stream. In questo stato il codec non accetta più altri buffer di input, ma genera comunque buffer di output fino a quando non viene raggiunta la fine del flusso nell'output. Per i decodificatori, è possibile tornare allo stato secondario Flushed in qualsiasi momento durante lo stato In esecuzione usando #flush. <p class=nota><forte>Nota:</strong> Tornare allo stato scaricato è supportato solo per i decodificatori e potrebbe non funzionare per i codificatori (il comportamento non è definito).

Chiamare #stop per restituire il codec allo stato Non inizializzato, in cui potrebbe essere configurato di nuovo. Al termine dell'uso di un codec, è necessario rilasciarlo chiamando #release.

In rari casi il codec può riscontrare un errore e passare allo stato errore. Questa operazione viene comunicata usando un valore restituito non valido da un'operazione di accodamento o talvolta tramite un'eccezione. Chiamare #reset per rendere nuovamente utilizzabile il codec. È possibile chiamarlo da qualsiasi stato per riportare il codec allo stato Non inizializzato. In caso contrario, chiamare #release per passare allo stato rilasciato del terminale.

<h3>Creazione</h3>

Usare MediaCodecList per creare un oggetto MediaCodec per un oggetto specifico MediaFormat. Quando si decodifica un file o un flusso, è possibile ottenere il formato desiderato da MediaExtractor#getTrackFormat MediaExtractor.getTrackFormat. Inserire tutte le funzionalità specifiche da aggiungere usando MediaFormat#setFeatureEnabled MediaFormat.setFeatureEnabled, quindi chiamare MediaCodecList#findDecoderForFormat MediaCodecList.findDecoderForFormat per ottenere il nome di un codec in grado di gestire tale formato multimediale specifico. Infine, creare il codec usando #createByCodecName. <p class=note><strong>Note:</strong> On android.os.Build.VERSION_CODES#LOLLIPOP, il formato per MediaCodecList.findDecoder/EncoderForFormat non deve contenere una frequenza di fotogrammi MediaFormat#KEY_FRAME_RATE. Usare format.setString(MediaFormat.KEY_FRAME_RATE, null) per cancellare qualsiasi impostazione di frequenza dei fotogrammi esistente nel formato .

È anche possibile creare il codec preferito per un tipo MIME specifico usando #createDecoderByType createDecoder/#createEncoderByType EncoderByType(String). Tuttavia, non può essere usato per inserire funzionalità e può creare un codec che non può gestire il formato multimediale desiderato specifico.

<h4>Creazione di decodificatori< sicuri/h4>

Nelle versioni e versioni android.os.Build.VERSION_CODES#KITKAT_WATCH precedenti, i codec sicuri potrebbero non essere elencati in MediaCodecList, ma potrebbero essere ancora disponibili nel sistema. I codec sicuri esistenti possono essere create solo per nome, aggiungendo ".secure" al nome di un codec normale (il nome di tutti i codec sicuri deve terminare con ".secure".) #createByCodecName genererà un'eccezione IOException se il codec non è presente nel sistema.

Da android.os.Build.VERSION_CODES#LOLLIPOP poi, è consigliabile usare la CodecCapabilities#FEATURE_SecurePlayback funzionalità nel formato multimediale per creare un decodificatore sicuro.

<inizializzazione< h3>/h3>

Dopo aver creato il codec, è possibile impostare un callback usando #setCallback setCallback se si desidera elaborare i dati in modo asincrono. Quindi, #configure configurare il codec usando il formato multimediale specifico. Questo è quando è possibile specificare l'output Surface per i produttori video – codec che generano dati video non elaborati (ad esempio decodificatori video). Questo è anche quando è possibile impostare i parametri di decrittografia per i codec sicuri (vedere MediaCrypto). Infine, poiché alcuni codec possono funzionare in più modalità, è necessario specificare se si vuole che funzioni come decodificatore o codificatore.

Poiché android.os.Build.VERSION_CODES#LOLLIPOP, è possibile eseguire una query sul formato di input e output risultante nello stato Configurato. È possibile usarlo per verificare la configurazione risultante, ad esempio i formati di colore, prima di avviare il codec.

Se si desidera elaborare i buffer video di input non elaborati in modo nativo con un consumer video – codec che elabora l'input video non elaborato, ad esempio un codificatore video – creare un dispositivo Surface di destinazione per i dati di input usando #createInputSurface dopo la configurazione. In alternativa, configurare il codec per usare una superficie di input persistente creata in precedenza #createPersistentInputSurface chiamando #setInputSurface.

<h4 id=CSD>"CSD">Codec-specific Data</h4>

Alcuni formati, in particolare audio AAC e MPEG4, H.264 e H.265, richiedono che i dati effettivi siano preceduti da una serie di buffer contenenti dati di configurazione o dati specifici del codec. Durante l'elaborazione di tali formati compressi, questi dati devono essere inviati al codec dopo #start e prima di qualsiasi dato frame. Tali dati devono essere contrassegnati usando il flag #BUFFER_FLAG_CODEC_CONFIG in una chiamata a #queueInputBuffer queueInputBuffer.

I dati specifici del codec possono essere inclusi anche nel formato passato a #configure configure nelle voci ByteBuffer con chiavi "csd-0", "csd-1" e così via. Queste chiavi sono sempre incluse nella traccia MediaFormat ottenuta da MediaExtractor#getTrackFormat MediaExtractor. I dati specifici del codec nel formato vengono inviati automaticamente al codec su #start. È necessario che i <>dati non< vengano inviati in modo sicuro in> modo esplicito. Se il formato non contiene dati specifici del codec, è possibile scegliere di inviarlo usando il numero specificato di buffer nell'ordine corretto, in base ai requisiti di formato. Nel caso di AVC H.264, è anche possibile concatenare tutti i dati specifici del codec e inviarli come un singolo buffer di configurazione codec.

Android usa i buffer di dati specifici del codec seguenti. Questi sono necessari anche per essere impostati nel formato di traccia per la configurazione corretta MediaMuxer della traccia. Ogni set di parametri e le sezioni di dati specifiche del codec contrassegnate con (sup*/sup>) devono iniziare con un codice iniziale di "\x00\x00\x00\x01".<><

<stile>td. NA { background: #ccc; } .mid > tr > td { vertical-align: middle; }</style><table><thead><th>Format</th>><CSD buffer #0</th>><CSD buffer #1</th th><>CSD buffer #2</th<>/thead<>tbody class=mid><tr<>td>AAC</td<>td Td>Decoder-specific information from ESDS<sup>*</sup></td td td class=NA>Not Used</td<>><td class=NA>Not Used</Td></tr tr><<>td>VORBIS</td td><td>Identification header</td><td>Setup header</td<>td td class=NA>Not Used</td<>/tr tr<><>td>OPUS</td<>td>Td Pre-skip>><< in nanosecs<br> (unsigned 64-bit ByteOrder#nativeOrder native-order integer).)<br> Esegue l'override del valore di pre-skip nell'intestazione di identificazione.</td td>><Seek Pre-roll in nanosecs<br> (byteOrder#nativeOrder integer a 64 bit senza segno).)</td></tr tr><<>td>FLAC</td td>><"fLaC", l'indicatore di flusso FLAC in ASCII,br>< seguito dal blocco STREAMINFO (blocco di metadati obbligatorio),<br> facoltativamente seguito da un numero qualsiasi di altri blocchi< di metadati/td td<>class=NA Not Used</td td td><class=NA>>Not Used</td<>/tr tr<>><td>MPEG-4</td><Td>Informazioni specifiche del decodificatore da ESDS sup*/sup></td td<>class=NA>Not Used</td 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 td<>< class=NA>Not Used</td></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><class=NA>Not Used</td td td<>class=NA>Not Used/< td></tr tr><<>td>VP9</td td><>VP9 CodecPrivate Data (facoltativo)</td td><class=NA>Not Used</td><td td class=NA Not Used</td<>/tr tr<><>td AV1</td td>>><AV1 AV1CodecConfigurationRecord Data (facoltativo) </td><td class=NA>>Not Used/< td td class=NA>Not Used</td></tr></tbody></table><>

<p class=nota><forte>Nota:</attenzione avanzata> deve essere eseguita se il codec viene scaricato immediatamente o poco dopo l'avvio, prima che venga restituita una modifica del formato di output o del buffer di output, in quanto i dati specifici del codec potrebbero essere persi durante lo scaricamento. È necessario inviare di nuovo i dati usando buffer contrassegnati con #BUFFER_FLAG_CODEC_CONFIG dopo tale scaricamento per garantire un'operazione codec appropriata.

I codificatori (o codec che generano dati compressi) creeranno e restituiscono i dati specifici del codec prima di qualsiasi buffer di output valido nei buffer di output contrassegnati con il flag codec-config #BUFFER_FLAG_CODEC_CONFIG. I buffer contenenti dati specifici del codec non hanno timestamp significativi.

<h3>Elaborazione< dati/h3>

Ogni codec gestisce un set di buffer di input e output a cui fa riferimento un ID buffer nelle chiamate API. Dopo una chiamata riuscita al #start client "possiede" né i buffer di input né di output. In modalità sincrona, chiamare #dequeueInputBuffer dequeueInput/#dequeueOutputBuffer OutputBuffer(&hellip;) per ottenere (ottenere la proprietà di) un buffer di input o output dal codec. In modalità asincrona si riceveranno automaticamente i buffer disponibili tramite i Callback#onInputBufferAvailable MediaCodec.Callback.onInput/Callback#onOutputBufferAvailable OutputBufferAvailable(&hellip;) callback.

Dopo aver ottenuto un buffer di input, compilarlo con i dati e inviarlo al codec usando #queueInputBuffer queueInputBuffer – o #queueSecureInputBuffer queueSecureInputBuffer se si usa la decrittografia. Non inviare più buffer di input con lo stesso timestamp (a meno che non si tratti di dati specifici del codec contrassegnati come tali).

Il codec a sua volta restituirà un buffer di output di sola lettura tramite il Callback#onOutputBufferAvailable onOutputBufferAvailable callback in modalità asincrona o in risposta a una #dequeueOutputBuffer dequeueOutputBuffer chiamata in modalità sincrona. Dopo l'elaborazione del buffer di output, chiamare uno dei #releaseOutputBuffer releaseOutputBuffer metodi per restituire il buffer al codec.

Anche se non è necessario inviare nuovamente/rilasciare buffer immediatamente al codec, tenere premuto i buffer di input e/o output potrebbe bloccare il codec e questo comportamento dipende dal dispositivo. <forte>In particolare, è possibile che un codec possa tenere premuto la generazione di buffer di output fino a quando <non sono stati rilasciati/inviati tutti i<> buffer in sospeso em>.</strong> Pertanto, provare a mantenere i buffer disponibili il minor possibile.

A seconda della versione dell'API, è possibile elaborare i dati in tre modi: table>thead><tr<>th>Processing Mode</th th><>API version <= 20<br>Jelly Bean/KitKat</th th><>API version >= 21<br>Lollipop and later</th<>/tr></thead<>tbody<>tr<>td>Synchronous API using buffer arrays</td td><Supported</td><<><td>Deprecated</td></tr><><tr td>Synchronous API using buffers</td td td><class=NA>Not Available</td td<>td>Supported</td></tr tr><<>td>Asynchronous API using buffers</td td td><class=NA>Not Available</td td><td>Supported</td<>/tr<>/tbody></table>

<h4>Elaborazione asincrona con buffer</h4>

Poiché android.os.Build.VERSION_CODES#LOLLIPOP, il metodo preferito consiste nell'elaborare i dati in modo asincrono impostando un callback prima di chiamare #configure configure. La modalità asincrona modifica leggermente le transizioni di stato, perché è necessario chiamare #start dopo #flush per passare il codec allo stato secondario In esecuzione e iniziare a ricevere buffer di input. Analogamente, quando una chiamata iniziale al start codec passerà direttamente allo stato secondario In esecuzione e inizierà a passare i buffer di input disponibili tramite il callback.

<center><img src=".. /.. /.. /images/media/mediacodec_async_states.svg" style="width: 516px; altezza: 353px" alt="Diagramma dello stato MediaCodec per l'operazione asincrona"></center>

MediaCodec viene in genere usato come segue in modalità asincrona:

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>Elaborazione sincrona con buffer</h4>

Poiché android.os.Build.VERSION_CODES#LOLLIPOP, è necessario recuperare i buffer di input e di output usando #getInputBuffer getInput/#getOutputBuffer OutputBuffer(int) e/o #getInputImage getInput/#getOutputImage OutputImage(int) anche quando si usa il codec in modalità sincrona. Ciò consente alcune ottimizzazioni dal framework, ad esempio durante l'elaborazione di contenuto dinamico. Questa ottimizzazione è disabilitata se si chiama #getInputBuffers getInput/#getOutputBuffers OutputBuffers().

<p class=note><strong>Note:</strong> non combinare contemporaneamente i metodi di utilizzo di buffer e matrici di buffer. In particolare, chiamare getInput/OutputBuffers direttamente dopo #start o dopo aver dequeuato un ID del buffer di output con il valore di .#INFO_OUTPUT_FORMAT_CHANGED

MediaCodec viene in genere usato come segue in modalità sincrona:

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();

<elaborazione sincrona h4>con matrici di buffer (deprecato)</h4>

Nelle versioni android.os.Build.VERSION_CODES#KITKAT_WATCH e precedenti, il set di buffer di input e output è rappresentato dalle ByteBuffer[] matrici. Dopo una chiamata riuscita a #start, recuperare le matrici di buffer usando/#getInputBuffers getInput#getOutputBuffers OutputBuffers() . Usare l'ID buffer come indici in queste matrici (quando non negativo), come illustrato nell'esempio seguente. Si noti che non esiste alcuna correlazione intrinseca tra le dimensioni delle matrici e il numero di buffer di input e output usati dal sistema, anche se le dimensioni della matrice forniscono un limite superiore.

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>Gestione end-of-stream</h4>

Quando si raggiunge la fine dei dati di input, è necessario segnalarlo al codec specificando il #BUFFER_FLAG_END_OF_STREAM flag nella chiamata a #queueInputBuffer queueInputBuffer. È possibile eseguire questa operazione nell'ultimo buffer di input valido oppure inviando un buffer di input vuoto aggiuntivo con il flag end-of-stream impostato. Se si usa un buffer vuoto, il timestamp verrà ignorato.

Il codec continuerà a restituire i buffer di output fino a quando non segnala la fine del flusso di output specificando lo stesso flag end-of-stream nel BufferInfo set in #dequeueOutputBuffer dequeueOutputBuffer o restituito tramite Callback#onOutputBufferAvailable onOutputBufferAvailable. Può essere impostato sull'ultimo buffer di output valido o su un buffer vuoto dopo l'ultimo buffer di output valido. Il timestamp di tale buffer vuoto deve essere ignorato.

Non inviare buffer di input aggiuntivi dopo aver segnalato la fine del flusso di input, a meno che il codec non sia stato scaricato o arrestato e riavviato.

<h4>Uso di una superficie< di output/h4>

L'elaborazione dei dati è quasi identica alla modalità ByteBuffer quando si usa un output Surface, ma i buffer di output non saranno accessibili e sono rappresentati come null valori. Ad esempio #getOutputBuffer getOutputBuffer/#getOutputImage Image(int) , restituirà null e #getOutputBuffers restituirà una matrice contenente solo null-s.

Quando si usa un surface di output, è possibile selezionare se eseguire o meno il rendering di ogni buffer di output sulla superficie. Sono disponibili tre opzioni: <ul><li><strong>Non eseguire il rendering del buffer:</strong> Call #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, false).</li><strong><>Eseguire il rendering del buffer con il timestamp predefinito:</strong> Call #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, true).</li><><strong>Eseguire il rendering del buffer con un timestamp specifico:</strong> Call #releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp).</li></ul>

Poiché android.os.Build.VERSION_CODES#M, il timestamp predefinito è il timestamp di presentazione BufferInfo#presentationTimeUs del buffer (convertito in nanosecondi). Non è stato definito prima di questo.

Inoltre, android.os.Build.VERSION_CODES#Mpuoi modificare dinamicamente surface di output usando #setOutputSurface setOutputSurface.

Quando si esegue il rendering dell'output in un dispositivo Surface, è possibile configurare Surface per eliminare fotogrammi eccessivi (che non vengono utilizzati in modo tempestivo da Surface). Oppure potrebbe essere configurato per non eliminare fotogrammi eccessivi. In quest'ultima modalità se Surface non utilizza fotogrammi di output abbastanza veloci, alla fine bloccherà il decodificatore. android.os.Build.VERSION_CODES#Q Prima del comportamento esatto non è stato definito, con l'eccezione che le superfici di visualizzazione (SurfaceView o TextureView) hanno sempre eliminato fotogrammi eccessivi. Poiché android.os.Build.VERSION_CODES#Q il comportamento predefinito consiste nell'eliminare fotogrammi eccessivi. Le applicazioni possono rifiutare esplicitamente questo comportamento per le superfici non Visualizza (ad esempio ImageReader o SurfaceTexture) impostando come destinazione l'SDK android.os.Build.VERSION_CODES#Q e impostando la chiave MediaFormat#KEY_ALLOW_FRAME_DROP su 0 nel formato di configurazione.

<trasformazioni h4>durante il rendering in Surface</h4>

Se il codec è configurato in modalità Surface, qualsiasi rettangolo di ritaglio, MediaFormat#KEY_ROTATION rotazione e #setVideoScalingMode modalità di ridimensionamento video verrà applicato automaticamente con un'eccezione: <p class=nota> Prima del android.os.Build.VERSION_CODES#M rilascio, i decodificatori software potrebbero non aver applicato la rotazione quando ne viene eseguito il rendering in una superficie. Sfortunatamente, non esiste un modo standard e semplice per identificare decodificatori software o se applicano la rotazione diversa da provandola.

Ci sono anche alcune avvertenze. <p class=nota: si noti> che le proporzioni dei pixel non vengono considerate durante la visualizzazione dell'output in Surface. Ciò significa che se usi #VIDEO_SCALING_MODE_SCALE_TO_FIT la modalità, devi posizionare l'output Surface in modo che abbia le proporzioni finali appropriate. Al contrario, puoi usare #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING la modalità solo per il contenuto con pixel quadrati (proporzioni pixel o 1:1). <p class=nota Nota> anche che a partire dalla android.os.Build.VERSION_CODES#N versione, #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING la modalità potrebbe non funzionare correttamente per i video ruotati di 90 o 270 gradi. <p class=nota> Quando si imposta la modalità di ridimensionamento video, si noti che deve essere reimpostata dopo ogni modifica dei buffer di output. Poiché l'evento #INFO_OUTPUT_BUFFERS_CHANGED è deprecato, è possibile eseguire questa operazione dopo ogni modifica del formato di output.

<h4>Uso di una superficie< di input/h4>

Quando si usa una superficie di input, non ci sono buffer di input accessibili, poiché i buffer vengono passati automaticamente dalla superficie di input al codec. La chiamata #dequeueInputBuffer dequeueInputBuffer genera un'eccezione IllegalStateExceptione #getInputBuffers restituisce una matrice fittizia ByteBuffer[] in cui <deve essere scritto MUST NOT</strong> forte>.

Chiamare #signalEndOfInputStream per segnalare la fine del flusso. La superficie di input smetterà di inviare i dati al codec subito dopo questa chiamata.

<h3>Ricerca & Supporto per< la riproduzione adattiva/h3>

I decodificatori video (e in codec generali che utilizzano dati video compressi) si comportano in modo diverso per quanto riguarda la ricerca e il formato cambiano se supportano o meno e sono configurati per la riproduzione adattiva. È possibile verificare se un decodificatore supporta CodecCapabilities#FEATURE_AdaptivePlayback la riproduzione adattiva tramite CodecCapabilities#isFeatureSupported CodecCapabilities.isFeatureSupported(String). Il supporto per la riproduzione adattiva per i decodificatori video viene attivato solo se si configura il codec per decodificare in un oggetto Surface.

<h4 id=KeyFrames"KeyFrames>">Limite del flusso e fotogrammi< chiave/h4>

È importante che i dati di input dopo #start o #flush inizino in corrispondenza di un limite di flusso appropriato: il primo fotogramma deve essere un fotogramma chiave. Un <fotogramma< chiave em/em>> può essere decodificato completamente autonomamente (per la maggior parte dei codec significa un I-frame) e nessun frame che devono essere visualizzati dopo un fotogramma chiave si riferiscono ai fotogrammi prima del fotogramma chiave.

La tabella seguente riepiloga i fotogrammi chiave adatti per vari formati video. <table>thead><tr><th>Format</th th><>Adatta fotogramma< chiave/th<>/tr<>/thead><tbody class=mid<>tr<>td>VP9/VP8</td td><>un intraframe adatto in cui nessun frame successivo fa riferimento a fotogrammi prima di questo frame.<<br>(Non esiste un nome specifico per tale fotogramma chiave.</td></tr tr><<>td>H.265 HEVC/td td td><>IDR o CRA</td></tr tr<<>>td>H.264 AVC<</td>><IDR</td<>/tr tr><<>td>MPEG-4<br>H.263<br>MPEG-2</td td td<>>un I-frame adatto in cui nessun frame successivo fa riferimento a fotogrammi precedenti a questo frame.<br>(Non esiste un nome specifico per tale fotogramma chiave.</td></tr></tbody></table>

<h4>Per decodificatori che non supportano la riproduzione adattiva (inclusa la mancata decodifica in un dispositivo Surface)</h4>

Per iniziare a decodificare i dati che non sono adiacenti ai dati inviati in precedenza (ad esempio dopo una ricerca) è <necessario</>forte> scaricare il decodificatore. Poiché tutti i buffer di output vengono immediatamente revocati al punto dello scaricamento, è possibile che si voglia prima segnalare e attendere la fine del flusso prima di chiamare flush. È importante che i dati di input dopo uno scaricamento inizino in corrispondenza di un limite di flusso/fotogramma chiave appropriato. <p class=nota>forte Nota:</strong> il formato dei dati inviati dopo uno scaricamento non deve cambiare; #flush non supporta le discontinuità di formato; per questo, è necessario un ciclo completo#configure configure(&hellip;) - #start - #stop.><

<p class=nota><forte>Nota anche:</strong> se si scarica il codec troppo presto dopo #start – in genere, prima che venga ricevuta la prima modifica del formato di output o del buffer di output – sarà necessario inviare nuovamente i dati specifici del codec al codec. Per altre informazioni, vedi la sezione codec-specific-data.see the codec-specific-data section for more info.

<h4>Per decodificatori che supportano e sono configurati per la riproduzione< adattiva/h4>

Per iniziare a decodificare i dati che non sono adiacenti ai dati inviati in precedenza (ad esempio dopo una ricerca), non è <>necessario</em> per scaricare il decodificatore. Tuttavia, i dati di input dopo la discontinuità devono iniziare in corrispondenza di un limite di flusso/fotogramma chiave appropriato.

Per alcuni formati video, ovvero H.264, H.265, VP8 e VP9, è anche possibile modificare le dimensioni dell'immagine o il flusso medio della configurazione. A tale scopo, è necessario creare un pacchetto dell'intero nuovo dati di configurazione specifico del codec insieme al fotogramma chiave in un singolo buffer (inclusi i codici iniziali) e inviarli come <buffer di input normale</>sicuro sicuro>sicuro.

Riceverai un #INFO_OUTPUT_FORMAT_CHANGED valore restituito da #dequeueOutputBuffer dequeueOutputBuffer o un Callback#onOutputBufferAvailable onOutputFormatChanged callback subito dopo la modifica delle dimensioni dell'immagine e prima che vengano restituiti i fotogrammi con le nuove dimensioni. <p class=note><strong>Note:</strong> proprio come nel caso di dati specifici del codec, prestare attenzione quando si chiama #flush poco dopo aver modificato le dimensioni dell'immagine. Se non hai ricevuto conferma della modifica delle dimensioni dell'immagine, dovrai ripetere la richiesta per le nuove dimensioni dell'immagine.

<h3>Gestione degli errori</h3>

I metodi #createByCodecName createByCodecName factory e #createDecoderByType createDecoder/#createEncoderByType EncoderByType generano un errore IOException che è necessario intercettare o dichiarare di passare. I metodi MediaCodec generano IllegalStateException un'eccezione quando il metodo viene chiamato da uno stato codec che non lo consente. Ciò è in genere dovuto a un utilizzo errato dell'API dell'applicazione. I metodi che riguardano buffer sicuri possono generare CryptoException, con ulteriori informazioni sugli errori che possono essere ottenute da CryptoException#getErrorCode.

Gli errori codec interni generano un CodecException, che può essere dovuto al danneggiamento del contenuto multimediale, all'errore hardware, all'esaurimento delle risorse e così via, anche quando l'applicazione usa correttamente l'API. L'azione consigliata quando si riceve un CodecException oggetto può essere determinata chiamando CodecException#isRecoverable e CodecException#isTransient: <ul><li><strong>recoverable errors:</strong> If isRecoverable() restituisce true, quindi chiamare #stop, #configure configure(&hellip;)e #start per il ripristino.</li li><><strong>transient errors:</strong> If isTransient() restituisce true, le risorse sono temporaneamente non disponibili e il metodo può essere ritentato in un secondo momento.</li>li strong fatal errors:</strong> If both isRecoverable() and isTransient() return false, then CodecException is fatal and the codec must be #reset reset or #release released.<>><</li></ul>

Entrambi isRecoverable() e isTransient() non restituiscono true contemporaneamente.

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

Queste sezioni riepilogano le chiamate API valide in ogni stato e la cronologia API della classe MediaCodec. Per i numeri di versione dell'API, vedere 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; altezza: 83 px; } .deg45 > div { transform: skew(-45deg, 0deg) translate(1px, -67px); transform-origin: bottom left 0; width: 30px; height: 20px; } .deg45 > 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); }</stile>

<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><>Semantics changed</td/tr tr><<>td>><○</td><td>Experimental support</td></tr tr><><td>[ ]</td td td>><Deprecated</td></tr tr<><>td>⎋</td td><>Limitato alla modalità< di input della superficie/td/tr tr><><td><>⎆</td td>><Restricted to surface output mode</td/tr tr><><td><>▧</td td limitato alla modalità< di input ByteBuffer/td/tr td>><>><<↩<><>/td td limitato alla modalità< sincrona/td/tr td>><><><⇄<><>/td td>><limitato alla modalità< asincrona/td></tr tr<><>td>( )</td td td><>Può essere chiamato, ma non< deve/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 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></div/div><></th th><class=deg45><div div><style="background:#0f9d58"><div>Running</div/div></div><></th th<>class=deg45><div div><style="background:#f7cb4d"><div>End of Stream</div/div></div/div/div><></th th><class=deg45><div div><style="background:#db4437"><div>Error</div/div><></div></th th<>class=deg45><div><style="background:#666"><div>Released</div></div></div></th<><>/><th th colspan="8">SDK Version</th<>/tr>><<th colspan="7">State</th<>>th Method</th th<>16<>/><th th>17</th th><>18</th><th>19</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><class=fn><#createByCodecName createByCodecName/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#createDecoderByType createDecoderByType<>/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#createEncoderByType createEncoderByType<>/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 td<>class=fn><#createPersistentInputSurface createPersistentInputSurface/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><class=fn><#configure configure/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><class=fn#createInputSurface createInputSurface<>/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>><16+</td<>td>(16+)</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></tr tr><><td>-</td><td>-</td td>><16+</td td>><16+</td<>td>16+</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></tr tr><><td>-</td><td>-</td td>><16+</td td>><16+</td<>td>16+</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></tr tr><<>td>18+</td td>><18+</td td><>18+</td td<>>18+</td td><>18+</td td>18+</td><><td td>><< class=fn>#getCodecInfo getCodecInfo</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><td>(21+)</td<>td>-</td<><> td td<>class=fn<>#getInputBuffer getInputBuffer/td><td></td td></td><><><><><><td></td><td>●</td td><>●</td td><>●</td></tr tr>><<td>-</td><td>-</td td><>16+</td<>td>(16+)</td><td>(16+)</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></tr tr><><td>-</td td>><21+</td td>><(21+)</td><td>(21+)</td><td>(21+)</td><td>-</><<>td td<>class=fn><#getInputFormat getInputFormat/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><td>(21+)</td<>td>-><<</td>>< td td class=fn<#getInputImage getInputImage>/td><td></td td/<><><>td><><td></td><td></td td>><○</td td><>●</td td><>●</td></tr tr><><td>18+</td td><>18+</td td><>18+</td td td><>18+</td td><>18+</td td><>18+</td><>< td td><class=fn#getName getName></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<<>>>< class=fn><#getOutputBuffer getOutputBuffer/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>><16+</td<>td>16+</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></tr><tr><td>-</td td><>21+</td td<>>16+</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 td><>●</td td><>●</td td><>●</td></tr><tr><td>-</td><td>-</td td>><(21+)</td td>><21+</td td><>21+</td><td>-</td<<>>>< class=fn><#getOutputFormat(int)/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<<>>>< class=fn><#getOutputImage getOutputImage/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>-</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></tr tr>><<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 td><>●</td td><>⁕</td td><>●</td td><>●</td></tr><tr><td>16+</td td<>>16+</td td><>16+</td td<>>16+</td td><>16+</td td><>16+/td<>td>16+<</td td><class=fn><#release release/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><class=fn><#releaseOutputBuffer(int, boolean)/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><>< class=fn>#releaseOutputBuffer(int, long)</td<>td 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 td>><21+</td td>><21+</td td><>21+</td td><>21+</td<>td>< td<>class=fn><#reset reset/td><td>< td/><td><>< td></Td><td></td><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><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><><td>-</td td td><>23+</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><td>><23+</td td>><23+</td td>><23+</td td td><>23+</td td><>23+</td td><>(23+)</td<>td>(23+)</td<>td class=fn<>#setOnFrameRenderedListener setOnFrameRenderedListener/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<>>23+</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></tr><><td>19+</td td><>19+</td td><>19+</td td<>>19+</td td>><19+</td td><>(19+)</td<>td td><<> class=fn>#setParameters setParameters</td<>>< td td/<><><>td td></Td><td>●</td td><>●</td td><>●</td td><>●</td td><>●</td></tr><tr><td>-</td td>><(16+)</td td><>(16+)</td<>td>16+</td td>><(16+)</td td<>>(16+)</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></tr tr><<>td>(29+)/td td>><29+</td td><>29+</td<>td>29+</td td>><(29+)<</td td td><>(29+)</td><td>-</td<>td class=fn<>#setAudioPresentation setAudioPresentation/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></tr tr><<>td>-</td td>><16+</td td<>>21+(⇄)</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></tr tr><><td>-</td><td>-</td td>><16+</td td>><16+</td<>td>16+</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></tr></tbody></table>

Documentazione java per android.media.MediaCodec.

Le parti di questa pagina sono modifiche basate sul lavoro creato e condiviso dal progetto Open Source Android e usato in base ai termini descritti nella licenza Creative Commons 2.5 Attribuzione.

Campi

BufferFlagCodecConfig
Obsoleti.

Ciò ha indicato che il buffer contrassegnato come tale contiene dati specifici di codec inizializzazione/codec anziché dati multimediali.

BufferFlagDecodeOnly
Obsoleti.

Ciò indica che il buffer viene decodificato e aggiorna lo stato interno del decodificatore, ma non produce alcun buffer di output.

BufferFlagEndOfStream
Obsoleti.

Questo segnala la fine del flusso, i.

BufferFlagKeyFrame
Obsoleti.

Ciò indica che il buffer (codificato) contrassegnato come tale contiene i dati per un fotogramma chiave.

BufferFlagPartialFrame
Obsoleti.

Ciò indica che il buffer contiene solo parte di un frame e il decodificatore deve eseguire l'invio in batch dei dati fino a quando non viene visualizzato un buffer senza questo flag prima di decodificare il frame.

BufferFlagSyncFrame
Obsoleti.

Ciò indica che il buffer (codificato) contrassegnato come tale contiene i dati per un fotogramma chiave.

ConfigureFlagEncode
Obsoleti.

Se questo codec deve essere usato come codificatore, passare questo flag.

ConfigureFlagUseBlockModel
Obsoleti.

Se questo codec deve essere usato con LinearBlock e/o HardwareBuffer, passare questo flag.

ConfigureFlagUseCryptoAsync
Obsoleti.

Questo flag deve essere usato solo in un decodificatore sicuro.

CryptoModeAesCbc
Obsoleti.

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

CryptoModeAesCtr
CryptoModeUnencrypted
InfoOutputBuffersChanged
Obsoleti.

I buffer di output sono stati modificati, il client deve fare riferimento al nuovo set di buffer di output restituiti da #getOutputBuffers questo punto in poi.

InfoOutputFormatChanged
Obsoleti.

Il formato di output è stato modificato, i dati successivi seguiranno il nuovo formato.

InfoTryAgainLater
Obsoleti.

Se è stato specificato un timeout non negativo nella chiamata a #dequeueOutputBuffer, indica che si è verificato il timeout della chiamata.

ParameterKeyHdr10PlusInfo

Impostare i metadati HDR10+ nel fotogramma di input in coda successivo.

ParameterKeyLowLatency

Abilitare/disabilitare la modalità di decodifica a bassa latenza.

ParameterKeyOffsetTime

Specificare un offset (in micro-secondo) da aggiungere sopra i timestamp e versioni successive.

ParameterKeyRequestSyncFrame

Richiedere che il codificatore produca presto un frame di sincronizzazione.

ParameterKeySuspend

Sospendere/riprendere temporaneamente la codifica dei dati di input.

ParameterKeySuspendTime

Quando #PARAMETER_KEY_SUSPEND è presente, il client può anche usare questa chiave facoltativamente per specificare il timestamp (in micro-secondo) in corrispondenza del quale l'operazione di sospensione/ripresa diventa effettiva.

ParameterKeyTunnelPeek

Controllare la visualizzazione video del primo fotogramma quando un codec è configurato per la modalità tunnel con MediaFormat#KEY_AUDIO_SESSION_ID mentre AudioTrack è in pausa.

ParameterKeyVideoBitrate

Modificare la velocità in bit di destinazione di un codificatore video in tempo reale.

VideoScalingModeScaleToFit
Obsoleti.

Il contenuto viene ridimensionato in base alle dimensioni della superficie

VideoScalingModeScaleToFitWithCropping
Obsoleti.

Il contenuto viene ridimensionato, mantenendo le proporzioni, viene usata l'intera superficie di attacco, il contenuto può essere ritagliato.

Proprietà

CanonicalName

Recuperare il nome del codec sottostante.

Class

Restituisce la classe di runtime di questo Objectoggetto .

(Ereditato da Object)
CodecInfo

Ottenere le informazioni sul codec.

Handle

Handle per l'istanza di Android sottostante.

(Ereditato da Object)
InputFormat

Chiamare questa operazione dopo #configure che viene restituito correttamente per ottenere il formato di input accettato dal codec.

JniIdentityHashCode

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
JniPeerMembers

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

Metrics

Restituisce i dati delle metriche sull'istanza codec corrente.

Name

Recuperare il nome del codec.

OutputFormat

Chiamare questa operazione dopo che dequeueOutputBuffer segnala una modifica del formato restituendo #INFO_OUTPUT_FORMAT_CHANGED.

PeerReference

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
SupportedVendorParameters

Restituisce un elenco di nomi di parametri fornitore.

ThresholdClass

Questa API supporta l'infrastruttura Mono per Android e non deve essere usata direttamente dal codice.

(Ereditato da Object)
ThresholdType

Questa API supporta l'infrastruttura Mono per Android e non deve essere usata direttamente dal codice.

(Ereditato da Object)

Metodi

Clone()

Crea e restituisce una copia di questo oggetto.

(Ereditato da Object)
Configure(MediaFormat, Surface, MediaCodecConfigFlags, MediaDescrambler)

Configurare un componente da usare con un descrambler.

Configure(MediaFormat, Surface, MediaCrypto, MediaCodecConfigFlags)

Configura un componente.

CreateByCodecName(String)

Se si conosce il nome esatto del componente di cui si vuole creare un'istanza, usare questo metodo per crearne un'istanza.

CreateDecoderByType(String)

Creare un'istanza del decodificatore preferito che supporta i dati di input del tipo MIME specificato.

CreateEncoderByType(String)

Creare un'istanza del codificatore preferito che supporta i dati di output del tipo MIME specificato.

CreateInputSurface()

Richiede a un dispositivo Surface di usare come input a un codificatore, al posto dei buffer di input.

CreatePersistentInputSurface()

Creare una superficie di input persistente che può essere usata con codec che in genere hanno una superficie di input, ad esempio codificatori video.

DequeueInputBuffer(Int64)

Restituisce l'indice di un buffer di input da riempire con dati validi o -1 se tale buffer non è attualmente disponibile.

DequeueOutputBuffer(MediaCodec+BufferInfo, Int64)

Annullare la coda di un buffer di output, bloccando al massimo i microsecondi "timeoutUS".

Dispose()

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
Dispose(Boolean)

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
Equals(Object)

Indica se un altro oggetto è "uguale a" questo.

(Ereditato da Object)
Flush()

Scaricare sia le porte di input che di output del componente.

GetHashCode()

Restituisce un valore del codice hash per l'oggetto.

(Ereditato da Object)
GetInputBuffer(Int32)

Restituisce un java.nio.Buffer#clear clearedoggetto ByteBuffer scrivibile per un indice del buffer di input dequeued in modo da contenere i dati di input.

GetInputBuffers()
Obsoleti.

Recuperare il set di buffer di input.

GetInputImage(Int32)

Restituisce un oggetto Image scrivibile per un indice del buffer di input dequeued in modo da contenere il frame video di input non elaborato.

GetOutputBuffer(Int32)

Restituisce un ByteBuffer di sola lettura per un indice del buffer di output dequeued.

GetOutputBuffers()
Obsoleti.

Recuperare il set di buffer di output.

GetOutputFormat(Int32)

Restituisce il formato di output per un buffer di output specifico.

GetOutputFrame(Int32)

Restituisce un oggetto OutputFrame.

GetOutputImage(Int32)

Restituisce un oggetto Image di sola lettura per un indice del buffer di output dequeued che contiene il frame video non elaborato.

GetParameterDescriptor(String)

Descrivere un parametro con il nome.

GetQueueRequest(Int32)

Restituisce un QueueRequest oggetto per un indice dello slot di input.

JavaFinalize()

Chiamato dal Garbage Collector su un oggetto quando Garbage Collection determina che non sono presenti altri riferimenti all'oggetto .

(Ereditato da Object)
MapHardwareBuffer(HardwareBuffer)

Eseguire il mapping di un HardwareBuffer oggetto in Imagein modo che il contenuto del buffer sia accessibile.

Notify()

Riattiva un singolo thread in attesa del monitor dell'oggetto.

(Ereditato da Object)
NotifyAll()

Riattiva tutti i thread in attesa del monitor dell'oggetto.

(Ereditato da Object)
QueueInputBuffer(Int32, Int32, Int32, Int64, MediaCodecBufferFlags)

Dopo aver riempito un intervallo del buffer di input in corrispondenza dell'indice specificato, inviarlo al componente.

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

Simile a #queueInputBuffer queueInputBuffer ma invia un buffer potenzialmente crittografato.

Release()

Liberare le risorse usate dall'istanza codec.

ReleaseOutputBuffer(Int32, Boolean)

Se hai finito con un buffer, usa questa chiamata per restituire il buffer al codec o per eseguirne il rendering nell'area di output.

ReleaseOutputBuffer(Int32, Int64)

Se hai finito con un buffer, usa questa chiamata per aggiornare il timestamp di superficie e restituirlo al codec per eseguirne il rendering nell'area di output.

Reset()

Restituisce il codec allo stato iniziale (non inizializzato).

SetAudioPresentation(AudioPresentation)

Imposta la presentazione audio.

SetCallback(MediaCodec+Callback)

Imposta un callback asincrono per gli eventi MediaCodec interattivi nel looper predefinito.

SetCallback(MediaCodec+Callback, Handler)

Imposta un callback asincrono per gli eventi MediaCodec interattivi nel looper predefinito.

SetHandle(IntPtr, JniHandleOwnership)

Imposta la proprietà Handle.

(Ereditato da Object)
SetInputSurface(Surface)

Configura il codec (e.

SetOnFirstTunnelFrameReadyListener(Handler, MediaCodec+IOnFirstTunnelFrameReadyListener)

Registra un callback da richiamare quando il primo frame di output è stato decodificato ed è pronto per il rendering su un codec configurato per la modalità tunnel con KEY_AUDIO_SESSION_ID.

SetOnFrameRenderedListener(MediaCodec+IOnFrameRenderedListener, Handler)

Registra un callback da richiamare quando viene eseguito il rendering di un frame di output sulla superficie di output.

SetOutputSurface(Surface)

Imposta dinamicamente la superficie di output di un codec.

SetParameters(Bundle)

Comunicare modifiche aggiuntive ai parametri all'istanza del componente.

SetVideoScalingMode(VideoScalingMode)

Se una superficie è stata specificata in una chiamata precedente a specifica #configure la modalità di ridimensionamento da usare.

SignalEndOfInputStream()

Segnala la fine del flusso all'input.

Start()

Dopo aver configurato correttamente il componente, chiamare start.

Stop()

Completare la sessione di decodifica/codifica, si noti che l'istanza del codec rimane attiva e pronta per essere #startnuovamente terminata.

SubscribeToVendorParameters(IList<String>)

Sottoscrivere i parametri fornitore, in modo che questi parametri siano presenti in #getOutputFormat e le modifiche apportate a questi parametri generino un evento di modifica del formato di output.

ToArray<T>()

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
ToString()

Restituisce una rappresentazione di stringa dell'oggetto.

(Ereditato da Object)
UnregisterFromRuntime()

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
UnsubscribeFromVendorParameters(IList<String>)

Annullare la sottoscrizione ai parametri del fornitore, in modo che questi parametri non saranno presenti e #getOutputFormat le modifiche apportate a questi parametri non generano più l'evento di modifica del formato di output.

Wait()

Fa sì che il thread corrente attenda finché non viene risvegliato, in genere ricevendo <>una notifica</em> o <em>interrotto</em>.

(Ereditato da Object)
Wait(Int64)

Fa sì che il thread corrente attenda finché non viene risvegliato, in genere ricevendo>< una notifica</em> o <em>interrotto</em> o fino a quando non è trascorsa una determinata quantità di tempo reale.

(Ereditato da Object)
Wait(Int64, Int32)

Fa sì che il thread corrente attenda finché non viene risvegliato, in genere ricevendo>< una notifica</em> o <em>interrotto</em> o fino a quando non è trascorsa una determinata quantità di tempo reale.

(Ereditato da Object)

Implementazioni dell'interfaccia esplicita

IJavaPeerable.Disposed()

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
IJavaPeerable.DisposeUnlessReferenced()

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
IJavaPeerable.Finalized()

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
IJavaPeerable.JniManagedPeerState

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
IJavaPeerable.SetJniIdentityHashCode(Int32)

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates)

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)
IJavaPeerable.SetPeerReference(JniObjectReference)

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

(Ereditato da Object)

Metodi di estensione

JavaCast<TResult>(IJavaObject)

Esegue una conversione del tipo di tipo controllato dal runtime Android.

JavaCast<TResult>(IJavaObject)

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

GetJniTypeName(IJavaPeerable)

La classe MediaCodec può essere usata per accedere ai codec multimediali di basso livello, i.

Si applica a