MediaCodec Classe
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, 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
- Héritage
- Attributs
Remarques
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, c’est-à-dire les composants encodeur/décodeur. Il fait partie de l’infrastructure de prise en charge multimédia de bas niveau Android (normalement utilisée avec MediaExtractor
, , MediaSync
MediaMuxer
, MediaCrypto
, MediaDrm
, , Image
Surface
et AudioTrack
.)
<centre><img src=".. /.. /.. /images/media/mediacodec_buffers.svg » style="width : 540px ; height : 205px » alt="MediaCodec buffer flow diagram"></center>
En termes généraux, un codec traite les données d’entrée pour générer des données de sortie. Il traite les données de manière asynchrone et utilise un ensemble de mémoires tampons d’entrée et de sortie. Au niveau simpliste, vous demandez (ou recevez) une mémoire tampon d’entrée vide, remplissez-la avec des données et envoyez-la au codec pour traitement. Le codec utilise les données et les transforme en une de ses mémoires tampons de sortie vides. Enfin, vous demandez (ou recevez) une mémoire tampon de sortie remplie, consommez son contenu et relâchez-le dans le codec.
<h3 id=qualityFloor>"qualityFloor">Minimum Quality Floor for Video Encoding</h3>
android.os.Build.VERSION_CODES#S
À compter de , Video MediaCodecs d’Android applique un plancher de qualité minimum. L’intention est d’éliminer les encodages vidéo de qualité médiocre. Ce plancher de qualité est appliqué lorsque le codec est en mode vitesse de transmission variable (VBR) ; il n’est pas appliqué lorsque le codec est en mode CBR (Constant Bitrate). L’application du plancher de qualité est également limitée à une plage de tailles particulière ; Cette plage de tailles est actuellement destinée aux résolutions vidéo supérieures à 320x240 jusqu’à 1920x1080.
Lorsque ce plancher de qualité est en vigueur, le codec et le code du framework de prise en charge fonctionnent pour s’assurer que la vidéo générée est d’au moins une qualité « équitable » ou « bonne ». La métrique utilisée pour choisir ces cibles est la VMAF (Fonction d’évaluation multi-méthode vidéo) avec un score cible de 70 pour les séquences de test sélectionnées.
L’effet typique est que certaines vidéos génèrent une vitesse de transmission supérieure à celle configurée à l’origine. Cela sera le plus notable pour les vidéos qui ont été configurées avec des débits très faibles ; le codec utilisera une vitesse de transmission déterminée à être plus susceptible de générer une vidéo de qualité « équitable » ou « bonne ». Une autre situation est où une vidéo comprend du contenu très compliqué (beaucoup de mouvements et de détails) ; dans ces configurations, le codec utilise une vitesse de transmission supplémentaire si nécessaire pour éviter de perdre tous les détails plus précis du contenu.
Ce plancher de qualité n’aura pas d’impact sur le contenu capturé à des vitesses de transmission élevées (une vitesse de transmission élevée doit déjà fournir au codec une capacité suffisante pour encoder tous les détails). Le plancher de qualité ne fonctionne pas sur les encodages CBR. Le plancher de qualité ne fonctionne actuellement pas sur les résolutions de 320x240 ou inférieurs, ni sur les vidéos avec résolution supérieure à 1920x1080.
<Types< de données h3>/h3>
Les codecs fonctionnent sur trois types de données : données compressées, données audio brutes et données vidéo brutes. Les trois types de données peuvent être traités à l’aide ByteBuffer ByteBuffers
, mais vous devez utiliser une Surface
vidéo brute pour améliorer les performances des codecs. Surface utilise des mémoires tampons vidéo natives sans mappage ni copie sur ByteBuffers ; c’est donc beaucoup plus efficace. Vous ne pouvez normalement pas accéder aux données vidéo brutes lors de l’utilisation d’une Surface, mais vous pouvez utiliser la ImageReader
classe pour accéder aux images vidéo décodées non sécurisées (brutes). Cela peut toujours être plus efficace que l’utilisation de ByteBuffers, car certaines mémoires tampons natives peuvent être mappées dans ByteBuffer#isDirect direct ByteBuffers. Lorsque vous utilisez le mode ByteBuffer, vous pouvez accéder aux images vidéo brutes à l’aide de la Image
classe et/#getInputImage getInput
#getOutputImage OutputImage(int)
.
<Mémoires tampons compressées< h4>/h4>
Les mémoires tampons d’entrée (pour les décodeurs) et les mémoires tampons de sortie (pour les encodeurs) contiennent des données compressées en fonction du type de MediaFormat#KEY_MIME. Pour les types vidéo, il s’agit normalement d’une trame vidéo compressée unique. Pour les données audio, il s’agit normalement d’une unité d’accès unique (un segment audio encodé contenant généralement quelques millisecondes d’audio comme dicté par le type de format), mais cette exigence est légèrement assouplie dans la mesure où une mémoire tampon peut contenir plusieurs unités d’accès encodées de l’audio. Dans les deux cas, les mémoires tampons ne démarrent pas ou ne se terminent pas sur des limites d’octets arbitraires, mais plutôt sur les limites d’unité d’image/d’accès, sauf si elles sont marquées par #BUFFER_FLAG_PARTIAL_FRAME
un indicateur .
<Mémoires tampons audio brutes< h4>/h4>
Les mémoires tampons audio brutes contiennent des images entières de données audio PCM, qui est un exemple pour chaque canal dans l’ordre des canaux. Chaque exemple audio PCM est un entier signé 16 bits ou un float, dans l’ordre d’octets natif. Les mémoires tampons audio brutes dans l’encodage PCM float ne sont possibles que si MediaFormat#KEY_PCM_ENCODING de MediaFormat#ENCODING_PCM_FLOAT est défini sur AudioFormat#ENCODING_PCM_FLOAT pendant MediaCodec #configure configure(…)
et confirmé par les #getOutputFormat
décodeurs ou #getInputFormat
pour les encodeurs. Un exemple de méthode permettant de vérifier le PCM float dans MediaFormat est le suivant :
static boolean isPcmFloat(MediaFormat format) {
return format.getInteger(MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_16BIT)
== AudioFormat.ENCODING_PCM_FLOAT;
}
Pour extraire, dans un tableau court, un canal d’une mémoire tampon contenant des données audio entières signées 16 bits, le code suivant peut être utilisé :
// 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;
}
<Mémoires tampons vidéo brutes< h4>/h4>
En mode ByteBuffer, les mémoires tampons vidéo sont disposées en fonction de leur format de couleur MediaFormat#KEY_COLOR_FORMAT. Vous pouvez obtenir les formats de couleur pris en charge en tant que tableau à partir de #getCodecInfo
CodecCapabilities#colorFormats colorFormats
.
MediaCodecInfo#getCapabilitiesForType getCapabilitiesForType(…)
.
. Les codecs vidéo peuvent prendre en charge trois types de formats de couleurs : <ul<>li strong>><native raw format :</strong> Ceci est marqué par CodecCapabilities#COLOR_FormatSurface
et il peut être utilisé avec une entrée ou une surface de sortie.</li li><strong>><tampons YUV flexibles</strong> (par exempleCodecCapabilities#COLOR_FormatYUV420Flexible
) : ceux-ci peuvent être utilisés avec une Surface d’entrée/sortie, ainsi que en mode ByteBuffer, à l’aide#getOutputImage OutputImage(int)
#getInputImage getInput
/ de .</li strong><>><other, specific formats :</strong> Ces formats sont normalement pris en charge uniquement en mode ByteBuffer. Certains formats de couleur sont spécifiques au fournisseur. D’autres sont définis dans CodecCapabilities
. Pour les formats de couleur équivalents à un format flexible, vous pouvez toujours utiliser #getInputImage getInput
/#getOutputImage OutputImage(int)
.</li></ul>
Tous les codecs vidéo prennent en charge les mémoires tampons YUV flexibles 4:2:0 depuis android.os.Build.VERSION_CODES#LOLLIPOP_MR1
.
<h4>Accès aux octets vidéo bruts sur les anciens appareils</h4>
android.os.Build.VERSION_CODES#LOLLIPOP
Avant et Image
prise en charge, vous devez utiliser les valeurs de MediaFormat#KEY_STRIDE
format et MediaFormat#KEY_SLICE_HEIGHT
de sortie pour comprendre la disposition des mémoires tampons de sortie brutes. <p class=remarque Notez> que sur certains appareils, la hauteur de tranche est annoncée comme 0. Cela peut signifier que la hauteur de tranche est la même que la hauteur du cadre, ou que la hauteur de tranche est la hauteur du cadre alignée sur une valeur (généralement une puissance de 2). Malheureusement, il n’existe pas de méthode standard et simple pour indiquer la hauteur de tranche réelle dans ce cas. En outre, le pas vertical du U
plan dans les formats planaires n’est pas spécifié ou défini, bien qu’il s’agit généralement de la moitié de la hauteur de tranche.
Les MediaFormat#KEY_WIDTH
clés et MediaFormat#KEY_HEIGHT
les touches spécifient la taille des images vidéo ; toutefois, pour la plupart des éléments concondants, la vidéo (image) occupe uniquement une partie du cadre vidéo. Ceci est représenté par le « rectangle de rognage ».
Vous devez utiliser les clés suivantes pour obtenir le rectangle de rognage des images de sortie brutes à partir du format de sortie #getOutputFormat. Si ces clés ne sont pas présentes, la vidéo occupe toute la trame vidéo. Le rectangle de rognage est compris dans le contexte de l’image <de sortie em>avant</em> appliquant une rotation MediaFormat#KEY_ROTATION. <table style="width : 0%">thead<>tr><th>Format Key</th><>th Type</th th><>Description</th<>/tr/thead><tbody><tr>><< td><MediaFormat#KEY_CROP_LEFT
/td<>td<> Td>><The left-coordinate (x) of the crop rectangle</td></tr tr><><td<MediaFormat#KEY_CROP_TOP
>/td td/ td td/ td td/><><<><td td>La coordonnée supérieure (y) du rectangle< de rognage/td>< tr<>><td><MediaFormat#KEY_CROP_RIGHT
/>><td td Entier</td<>>Td La coordonnée droite (x) <forte>MOINS 1/forte> du rectangle< de rognage/td<>/tr tr<>><tdMediaFormat#KEY_CROP_BOTTOM
></td<><> td Entier/td>><Td La coordonnée inférieure (y) <forte>MOINS 1<</strong> du rectangle< de rognage/td<>/tr tr><td><colspan=3> Les coordonnées droite et inférieure peuvent être comprises comme les coordonnées de la colonne la plus valide à droite/ligne la plus valide de l’image de sortie rognée. </td></tr/tbody><></table>
La taille de l’image vidéo (avant la rotation) peut être calculée comme suit :
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=remarque> Notez également que la signification de BufferInfo#offset BufferInfo.offset
n’était pas cohérente entre les appareils. Sur certains appareils, le décalage pointait vers le pixel supérieur gauche du rectangle de rognage, tandis que sur la plupart des appareils, il pointait vers le pixel supérieur gauche de l’ensemble du cadre.
<États< h3>/h3>
Pendant sa vie, un codec existe conceptuellement dans l’un des trois états suivants : Arrêté, En cours d’exécution ou Libéré. L’état collectif Arrêté est en fait le regroupement de trois états : non initialisé, configuré et error, tandis que l’état en cours d’exécution progresse conceptuellement dans trois sous-états : Vidé, En cours d’exécution et fin de flux.
<centre><img src=".. /.. /.. /images/media/mediacodec_states.svg » style="width : 519px ; height : 356px » alt="MediaCodec state diagram"></center>
Lorsque vous créez un codec à l’aide de l’une des méthodes de fabrique, le codec est dans l’état non initialisé. Tout d’abord, vous devez le configurer via #configure configure(…)
, ce qui l’amène à l’état configuré, puis appeler #start
pour le déplacer vers l’état en cours d’exécution. Dans cet état, vous pouvez traiter les données via la manipulation de file d’attente de mémoires tampons décrite ci-dessus.
L’état en cours d’exécution a trois sous-états : Vidé, En cours d’exécution et fin de flux. Immédiatement après #start
que le codec se trouve dans le sous-état vidé, où il contient toutes les mémoires tampons. Dès que la première mémoire tampon d’entrée est mise en file d’attente, le codec passe à l’état sous-état En cours d’exécution, où il passe la majeure partie de sa vie. Lorsque vous placez une mémoire tampon d’entrée avec le marqueur de fin de flux #BUFFER_FLAG_END_OF_STREAM, le codec passe à l’état de fin de flux. Dans cet état, le codec n’accepte plus de mémoires tampons d’entrée, mais génère toujours des mémoires tampons de sortie jusqu’à ce que la fin du flux soit atteinte sur la sortie. Pour les décodeurs, vous pouvez revenir à l’état sous-état vidé à tout moment lors de l’exécution à l’aide #flush
de . <p class=note><forte>Remarque :</strong> Retour à l’état Vidé n’est pris en charge que pour les décodeurs et peut ne pas fonctionner pour les encodeurs (le comportement n’est pas défini).
Appelez #stop
pour renvoyer le codec à l’état non initialisé, où il peut être configuré à nouveau. Lorsque vous avez terminé d’utiliser un codec, vous devez le libérer en appelant #release
.
Dans de rares cas, le codec peut rencontrer une erreur et passer à l’état d’erreur. Cela est communiqué à l’aide d’une valeur de retour non valide à partir d’une opération de mise en file d’attente, ou parfois via une exception. Appelez #reset
à nouveau le codec utilisable. Vous pouvez l’appeler à partir de n’importe quel état pour revenir au codec vers l’état non initialisé. Sinon, appelez #release
pour passer à l’état De sortie du terminal.
<h3>Création</h3>
Permet MediaCodecList
de créer un MediaCodec pour un élément spécifique MediaFormat
. Lors du décodage d’un fichier ou d’un flux, vous pouvez obtenir le format souhaité à partir de MediaExtractor#getTrackFormat MediaExtractor.getTrackFormat
. Injectez les fonctionnalités spécifiques que vous souhaitez ajouter à l’aide MediaFormat#setFeatureEnabled MediaFormat.setFeatureEnabled
, puis appelez MediaCodecList#findDecoderForFormat MediaCodecList.findDecoderForFormat
pour obtenir le nom d’un codec qui peut gérer ce format multimédia spécifique. Enfin, créez le codec à l’aide #createByCodecName
de . <p class=note><strong>Remarque :</strong> On android.os.Build.VERSION_CODES#LOLLIPOP
, le format à MediaCodecList.findDecoder
/EncoderForFormat
ne pas contenir de MediaFormat#KEY_FRAME_RATE fréquence d’images. Permet format.setString(MediaFormat.KEY_FRAME_RATE, null)
d’effacer tout paramètre de fréquence d’images existant au format.
Vous pouvez également créer le codec préféré pour un type MIME spécifique à l’aide #createDecoderByType createDecoder
/#createEncoderByType EncoderByType(String)
de . Toutefois, cela ne peut pas être utilisé pour injecter des fonctionnalités et peut créer un codec qui ne peut pas gérer le format de média souhaité spécifique.
<h4>Création de décodeurs sécurisés</h4>
Sur les versions android.os.Build.VERSION_CODES#KITKAT_WATCH
et les versions antérieures, les codecs sécurisés peuvent ne pas être répertoriés dans MediaCodecList
, mais peuvent toujours être disponibles sur le système. Les codecs sécurisés qui existent peuvent être instanciés uniquement par nom, en ajoutant ".secure"
au nom d’un codec normal (le nom de tous les codecs sécurisés doit se terminer par ".secure"
.) #createByCodecName
lève un IOException
si le codec n’est pas présent sur le système.
À partir de android.os.Build.VERSION_CODES#LOLLIPOP
là, vous devez utiliser la CodecCapabilities#FEATURE_SecurePlayback
fonctionnalité au format multimédia pour créer un décodeur sécurisé.
<Initialisation< h3>/h3>
Après avoir créé le codec, vous pouvez définir un rappel en utilisant #setCallback setCallback
si vous souhaitez traiter les données de manière asynchrone. Ensuite, #configure configurer le codec à l’aide du format multimédia spécifique. C’est le cas lorsque vous pouvez spécifier la sortie Surface
pour les producteurs de vidéos &ndash ; codecs qui génèrent des données vidéo brutes (par exemple, des décodeurs vidéo). C’est également le cas lorsque vous pouvez définir les paramètres de déchiffrement pour les codecs sécurisés (voir MediaCrypto
). Enfin, étant donné que certains codecs peuvent fonctionner dans plusieurs modes, vous devez spécifier si vous souhaitez qu’il fonctionne en tant que décodeur ou encodeur.
Étant donné que android.os.Build.VERSION_CODES#LOLLIPOP
vous pouvez interroger le format d’entrée et de sortie résultant dans l’état configuré. Vous pouvez l’utiliser pour vérifier la configuration résultante, par exemple les formats de couleur, avant de démarrer le codec.
Si vous souhaitez traiter des mémoires tampons vidéo d’entrée brutes en mode natif avec un consommateur vidéo &ndash ; codec qui traite l’entrée vidéo brute, telle qu’un encodeur vidéo &ndash ; créez une Surface de destination pour vos données d’entrée à l’aide #createInputSurface
de la configuration après la configuration. Vous pouvez également configurer le codec pour utiliser une surface d’entrée persistante précédemment créée #createPersistentInputSurface en appelant #setInputSurface
.
<h4 id=CSD"CSD>">Codec-specific Data</h4>
Certains formats, notamment les formats audio AAC et MPEG4, H.264 et H.265, nécessitent que les données réelles soient préfixées par un certain nombre de mémoires tampons contenant des données d’installation ou des données spécifiques au codec. Lors du traitement de ces formats compressés, ces données doivent être envoyées au codec après #start
et avant toute donnée de trame. Ces données doivent être marquées à l’aide de l’indicateur #BUFFER_FLAG_CODEC_CONFIG
dans un appel à #queueInputBuffer queueInputBuffer
.
Les données spécifiques au codec peuvent également être incluses dans le format transmis aux #configure configure
entrées ByteBuffer avec des clés « csd-0 », « csd-1 », etc. Ces clés sont toujours incluses dans la piste MediaFormat
obtenue à partir du MediaExtractor#getTrackFormat MediaExtractor
. Les données spécifiques aux codecs au format sont automatiquement envoyées au codec dès #start
lors ; vous>< devez fort NE PAS</fort> envoyer ces données explicitement. Si le format ne contenait pas de données spécifiques au codec, vous pouvez choisir de l’envoyer à l’aide du nombre spécifié de mémoires tampons dans l’ordre correct, en fonction des exigences de format. Dans le cas de H.264 AVC, vous pouvez également concaténer toutes les données spécifiques au codec et les soumettre en tant que mémoire tampon de configuration de codec unique.
Android utilise les mémoires tampons de données spécifiques au codec suivantes. Ces éléments doivent également être définis dans le format de piste pour une configuration de piste appropriée MediaMuxer
. Chaque jeu de paramètres et les sections de données spécifiques au codec marquées avec (sup*/sup>) doivent commencer par un code de début de "\x00\x00\x00\x01"
.<><
<style>td. NA { background : #ccc ; } .mid > tr td > { vertical-align : middle ; }</style><table><thead><th>Format</><>th CSD buffer #0</th><th>CSD buffer #1</th th><>CSD buffer #2</th></thead<>tbody class=mid<>tr td<>>AAC</td td>><Decoder-specific information from ESDS<sup>*</sup></td td class><=NA Not Used/td td class=NA>Not Used/td><class=NA Not Used<></Td></tr tr><><td>VORBIS</td<>>Identification< header/td td><>Setup< header/td<>class=NA Not>Used</td></tr tr<>>><td OPUS</td>><Identification header</td td>><Pre-skip in nanosecs<br> (unsigned byteOrder#nativeOrder native Order integer.)<br> Remplace la valeur de pré-ignorer dans l’en-tête d’identification.</td td>><seek pre-roll in nanosecs<br> (unsigned byteOrder#nativeOrder native-order integer.)</td>/tr tr>>><<td PST</td><>"fLaC », marqueur de flux ASCII,< br> suivi du bloc STREAMINFO (bloc de métadonnées obligatoire),< br> éventuellement suivi d’un nombre quelconque de blocs de métadonnées</td td><class=NA>Not Used</td<>class=NA Not Used/td td class=NA>Not Used</td<>/tr><tr<>>mpeg-4</td td><<Td>Informations spécifiques du décodeur à partir de ESDS sup*/sup/td td<>class=NA>Not Used</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 class=NA Not Used/ td><class=NA>Not>Used/<< td>/tr tr>><<>td VP9</td><>TD VP9 CodecPrivate Data (facultatif)</td><td class=NA Not Used</td td<>class=NA>>Not Used/td/<>tr tr>><<td>AV1</td>><td AV1 AV1 AV1 AV1CodecConfigurationRecord Data (facultatif) </td<>td class=NA>Not Used/<<< td><td class=NA Not>Used</td></tr></tbody></table>
<p class=note><forte Remarque :</le soin fort>> doit être pris si le codec est vidé immédiatement ou peu après le démarrage, avant que toute modification du format de sortie ou de mémoire tampon de sortie ait été retournée, car les données spécifiques au codec peuvent être perdues pendant le vidage. Vous devez soumettre à nouveau les données à l’aide de mémoires tampons marquées après #BUFFER_FLAG_CODEC_CONFIG
ce vidage pour garantir une opération de codec appropriée.
Les encodeurs (ou codecs qui génèrent des données compressées) créent et retournent les données spécifiques du codec avant toute mémoire tampon de sortie valide dans les mémoires tampons de sortie marquées avec l’indicateur #BUFFER_FLAG_CODEC_CONFIG codec-config. Les mémoires tampons contenant des données spécifiques au codec n’ont aucun horodatage significatif.
<traitement des données< h3>/h3>
Chaque codec gère un ensemble de mémoires tampons d’entrée et de sortie référencées par un ID de mémoire tampon dans les appels d’API. Après un appel réussi au #start
client « possède » ni les mémoires tampons d’entrée ni de sortie. En mode synchrone, appelez #dequeueInputBuffer dequeueInput
/#dequeueOutputBuffer OutputBuffer(…)
pour obtenir (obtenir la propriété de) une mémoire tampon d’entrée ou de sortie à partir du codec. En mode asynchrone, vous recevrez automatiquement des mémoires tampons disponibles via les Callback#onInputBufferAvailable MediaCodec.Callback.onInput
/Callback#onOutputBufferAvailable OutputBufferAvailable(…)
rappels.
Lors de l’obtention d’une mémoire tampon d’entrée, remplissez-la avec des données et envoyez-la au codec à l’aide #queueInputBuffer queueInputBuffer
de &ndash ; ou #queueSecureInputBuffer queueSecureInputBuffer
si vous utilisez le déchiffrement. N’envoyez pas plusieurs mémoires tampons d’entrée avec le même horodatage (sauf s’il s’agit de données spécifiques au codec marquées comme telles).
Le codec retourne à son tour une mémoire tampon de sortie en lecture seule via le Callback#onOutputBufferAvailable onOutputBufferAvailable
rappel en mode asynchrone, ou en réponse à un #dequeueOutputBuffer dequeueOutputBuffer
appel en mode synchrone. Une fois la mémoire tampon de sortie traitée, appelez l’une des #releaseOutputBuffer releaseOutputBuffer
méthodes pour renvoyer la mémoire tampon au codec.
Même si vous n’êtes pas obligé de renvoyer/libérer immédiatement des mémoires tampons vers le codec, la conservation des mémoires tampons d’entrée et/ou de sortie peut bloquer le codec, et ce comportement dépend de l’appareil. <Plus précisément>, il est possible qu’un codec puisse différer la génération de mémoires tampons de sortie jusqu’à ce>< que les mémoires tampons en attente em toutes</em> aient été libérées/resubmises.</strong> Par conséquent, essayez de conserver les mémoires tampons disponibles aussi peu que possible.
Selon la version de l’API, vous pouvez traiter les données de trois façons : table>thead><tr<>th>Processing Mode</th><>API version <= 20<br>Jelly Bean/KitKat</th th><>API version >= 21<br>Lollipop et ultérieur</th></tr/thead><tbody><tr>><< td>Synchronous API using buffer arrays</td<>td Supported</td td><<><td>Déprécié</td<>/tr tr><td><>Synchronous API using buffers</td<>td class=NA Not>Available</td td>><supported</><tr tr<<>>>asynchrone api using buffers</td td td class><=NA>Not Available</td td<>>Supported</tr<<>>/tbody></table>
<Traitement asynchrone h4>à l’aide de mémoires tampons</h4>
Étant donné que android.os.Build.VERSION_CODES#LOLLIPOP
la méthode préférée consiste à traiter les données de manière asynchrone en définissant un rappel avant d’appeler #configure configure
. Le mode asynchrone modifie légèrement les transitions d’état, car vous devez appeler #start
après #flush
la transition du codec vers le sous-état en cours d’exécution et commencer à recevoir des mémoires tampons d’entrée. De même, lors d’un appel initial au start
codec, vous passez directement à l’état sous-état en cours d’exécution et commencez à transmettre des mémoires tampons d’entrée disponibles via le rappel.
<centre><img src=".. /.. /.. /images/media/mediacodec_async_states.svg » style="width : 516px ; height : 353px » alt="MediaCodec state diagram for asynchrone operation"></center>
MediaCodec est généralement utilisé comme suit en mode asynchrone :
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();
<Traitement synchrone h4>à l’aide de mémoires tampons</h4>
Étant donné que android.os.Build.VERSION_CODES#LOLLIPOP
vous devez récupérer des mémoires tampons d’entrée et de sortie à l’aide #getInputBuffer getInput
/#getOutputBuffer OutputBuffer(int)
et/ou #getInputImage getInput
/#getOutputImage OutputImage(int)
même lors de l’utilisation du codec en mode synchrone. Cela permet certaines optimisations par l’infrastructure, par exemple lors du traitement du contenu dynamique. Cette optimisation est désactivée si vous appelez #getInputBuffers getInput
/#getOutputBuffers OutputBuffers()
.
<p class=note><forte>Remarque :</strong> ne mélangent pas les méthodes d’utilisation de mémoires tampons et de tableaux de mémoires tampons en même temps. Plus précisément, appelez getInput
/OutputBuffers
uniquement directement après #start
ou après avoir mis en file d’attente un ID de mémoire tampon de sortie avec la valeur de .#INFO_OUTPUT_FORMAT_CHANGED
MediaCodec est généralement utilisé comme ceci en mode synchrone :
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();
<traitement synchrone h4>à l’aide de tableaux de mémoires tampons (déconseillé)</h4>
Dans les versions android.os.Build.VERSION_CODES#KITKAT_WATCH
et avant, l’ensemble de mémoires tampons d’entrée et de sortie est représenté par les ByteBuffer[]
tableaux. Après un appel réussi, #start
récupérez les tableaux de mémoires tampons à l’aide #getInputBuffers getInput
/#getOutputBuffers OutputBuffers()
de . Utilisez les ID de mémoire tampon comme index dans ces tableaux (lorsqu’ils ne sont pas négatifs), comme illustré dans l’exemple ci-dessous. Notez qu’il n’existe aucune corrélation inhérente entre la taille des tableaux et le nombre de mémoires tampons d’entrée et de sortie utilisées par le système, bien que la taille du tableau fournisse une limite supérieure.
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();
<Gestion de fin de flux< h4>/h4>
Lorsque vous atteignez la fin des données d’entrée, vous devez le signaler au codec en spécifiant l’indicateur #BUFFER_FLAG_END_OF_STREAM
dans l’appel à #queueInputBuffer queueInputBuffer
. Pour ce faire, vous pouvez effectuer cette opération sur la dernière mémoire tampon d’entrée valide ou en envoyant une mémoire tampon d’entrée vide supplémentaire avec l’indicateur de fin de flux défini. Si vous utilisez une mémoire tampon vide, l’horodatage est ignoré.
Le codec continue de retourner des mémoires tampons de sortie jusqu’à ce qu’il signale finalement la fin du flux de sortie en spécifiant le même indicateur de fin de flux dans le BufferInfo
jeu ou #dequeueOutputBuffer dequeueOutputBuffer
retourné via Callback#onOutputBufferAvailable onOutputBufferAvailable
. Cela peut être défini sur la dernière mémoire tampon de sortie valide ou sur une mémoire tampon vide après la dernière mémoire tampon de sortie valide. L’horodatage de cette mémoire tampon vide doit être ignoré.
N’envoyez pas de mémoires tampons d’entrée supplémentaires après avoir signalé la fin du flux d’entrée, sauf si le codec a été vidé ou arrêté et redémarré.
<h4>à l’aide d’une surface< de sortie/h4>
Le traitement des données est presque identique au mode ByteBuffer lors de l’utilisation d’une sortie Surface
; toutefois, les mémoires tampons de sortie ne sont pas accessibles et sont représentées en tant que null
valeurs. Par exemple, #getOutputBuffer getOutputBuffer
/#getOutputImage Image(int)
retourne null
et #getOutputBuffers
retourne un tableau contenant uniquement null
-s.
Lorsque vous utilisez une surface de sortie, vous pouvez sélectionner s’il faut afficher ou non chaque mémoire tampon de sortie sur la surface. Vous avez trois choix : <ul><li><strong>Ne pas afficher la mémoire tampon :</strong> Call #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, false)
.</li li>><<strong>Render the buffer with the default timestamp :</strong> Call #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, true)
.</li li>><<strong>Render the buffer with a specific timestamp :</strong> Call #releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp)
.</li></ul>
Étant donné android.os.Build.VERSION_CODES#M
que l’horodatage par défaut est l’horodatage de présentation BufferInfo#presentationTimeUs de la mémoire tampon (converti en nanosecondes). Il n’a pas été défini avant cela.
android.os.Build.VERSION_CODES#M
En outre, vous pouvez modifier dynamiquement la surface de sortie à l’aide #setOutputSurface setOutputSurface
de .
Lors du rendu de la sortie sur une Surface, la surface peut être configurée pour supprimer des images excessives (qui ne sont pas consommées par surface en temps voulu). Ou il peut être configuré pour ne pas supprimer des images excessives. Dans ce dernier mode, si la Surface ne consomme pas suffisamment de trames de sortie, elle bloque finalement le décodeur. android.os.Build.VERSION_CODES#Q
Avant le comportement exact n’a pas été défini, à l’exception que les surfaces d’affichage (SurfaceView ou TextureView) ont toujours supprimé des images excessives. Étant donné que android.os.Build.VERSION_CODES#Q
le comportement par défaut consiste à supprimer des images excessives. Les applications peuvent refuser ce comportement pour les surfaces non-Affichage (telles que ImageReader ou SurfaceTexture) en ciblant le KIT DE développement logiciel (SDK android.os.Build.VERSION_CODES#Q
) et en définissant la clé MediaFormat#KEY_ALLOW_FRAME_DROP
0
dans leur format de configuration.
<Transformations h4>lors du rendu sur Surface</h4>
Si le codec est configuré en mode Surface, tout rectangle de rognage, MediaFormat#KEY_ROTATION rotation et #setVideoScalingMode mode de mise à l’échelle vidéo sont automatiquement appliqués à une exception : <p class=remarque> Avant la android.os.Build.VERSION_CODES#M
mise en production, les décodeurs logiciels n’ont peut-être pas appliqué la rotation lors de l’affichage sur une Surface. Malheureusement, il n’existe aucun moyen standard et simple d’identifier les décodeurs logiciels, ou s’ils appliquent la rotation autre qu’en l’essayant.
Il y a aussi des mises en garde. <p class=remarque Notez> que le rapport d’aspect de pixels n’est pas pris en compte lors de l’affichage de la sortie sur la Surface. Cela signifie que si vous utilisez #VIDEO_SCALING_MODE_SCALE_TO_FIT
le mode, vous devez positionner la surface de sortie afin qu’elle dispose du rapport d’aspect d’affichage final approprié. À l’inverse, vous pouvez uniquement utiliser #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
le mode pour le contenu avec des pixels carrés (rapport d’aspect de pixels ou 1:1). <p class=remarque> Notez également que, à partir de la android.os.Build.VERSION_CODES#N
version, #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
le mode peut ne pas fonctionner correctement pour les vidéos pivotées de 90 ou 270 degrés. <p class=remarque> Lors de la définition du mode de mise à l’échelle vidéo, notez qu’il doit être réinitialisé après chaque modification des mémoires tampons de sortie. Étant donné que l’événement #INFO_OUTPUT_BUFFERS_CHANGED
est déconseillé, vous pouvez le faire après chaque modification du format de sortie.
<h4>à l’aide d’une surface< d’entrée/h4>
Lorsque vous utilisez une surface d’entrée, il n’existe aucune mémoire tampon d’entrée accessible, car les mémoires tampons sont transmises automatiquement de la surface d’entrée au codec. L’appel #dequeueInputBuffer dequeueInputBuffer
lève un IllegalStateException
tableau et #getInputBuffers
retourne un tableau factice ByteBuffer[]
dans lequel <la valeur forte>NE DOIT PAS</forte> être écrite.
Appelez #signalEndOfInputStream
à la fin du flux de signal. La surface d’entrée cesse d’envoyer des données au codec immédiatement après cet appel.
<h3>Recherche & Prise en charge< de la lecture adaptative/h3>
Les décodeurs vidéo (et en général les codecs qui consomment des données vidéo compressées) se comportent différemment en ce qui concerne la recherche et le format, qu’ils prennent en charge ou non et soient configurés pour la lecture adaptative. Vous pouvez vérifier si un décodeur prend en charge CodecCapabilities#FEATURE_AdaptivePlayback lecture adaptative via CodecCapabilities#isFeatureSupported CodecCapabilities.isFeatureSupported(String)
. La prise en charge de la lecture adaptative pour les décodeurs vidéo est activée uniquement si vous configurez le codec pour décoder sur un Surface
.
<h4 id=KeyFrames"KeyFrames>"KeyFrames">Stream Boundary and Key Frames</h4>
Il est important que les données d’entrée après #start
ou #flush
commencent à une limite de flux appropriée : la première image doit être une trame clé. Une <image< clé em>> peut être décodée complètement par elle-même (pour la plupart des codecs, cela signifie qu’une image I) et aucune trame qui ne doit être affichée après qu’un frame clé fait référence à des images avant le frame clé.
Le tableau suivant récapitule les images clés appropriées pour différents formats vidéo. <table>thead><tr><th>Format</th>><Approprié frame< clé/th<>/tr<>/thead<>tbody class=mid<>tr td>><VP9/VP8</td td<>a>approprié intraframe où aucune trame suivante ne fait référence à des images antérieures à ce cadre.<<br>(Il n’existe aucun nom spécifique pour ce frame clé.)</td>/tr tr>><<tr td>H.265 HEVC</td IDR><>ou CRA</td></tr tr><><td>H.264 AVC</td td<>>IDR/td td IDR</td>< tr<>><tr>MPEG-4<br H.263<br>>MPEG-2</td td<>td>a une image I appropriée où aucune trame ultérieure ne fait référence à des images antérieures à ce cadre.<<br>(Il n’existe aucun nom spécifique pour ce frame clé.)</td></tr/tbody><></table>
<h4>Pour les décodeurs qui ne prennent pas en charge la lecture adaptative (y compris lorsqu’ils ne décodent pas sur une Surface)</h4>
Pour commencer le décodage des données qui ne sont pas adjacentes aux données précédemment envoyées (par exemple, après une recherche), vous <>devez< /fort> vider le décodeur. Étant donné que toutes les mémoires tampons de sortie sont immédiatement révoquées au moment de la vidage, vous pouvez d’abord signaler que vous attendez la fin du flux avant d’appeler flush
. Il est important que les données d’entrée après un vidage commencent à une limite de flux/trame clé appropriée. <p class=note>forte Remarque :</strong> le format des données envoyées après un vidage ne doit pas changer ; #flush
ne prend pas en charge les discontinuités de format ; pour cela, un cycle complet#start
- - #stop
#configure configure(…)
est nécessaire.><
<p class=note><strong>Notez également :</strong> si vous videz le codec trop tôt après #start
&ndash ; généralement, avant que la première modification du format de sortie ou de la mémoire tampon de sortie soit reçue &ndash ; vous devrez soumettre à nouveau les données spécifiques du codec au codec. Pour plus d’informations, consultez la section des données spécifiques au codec.
<h4>Pour les décodeurs qui prennent en charge et sont configurés pour la lecture< adaptative/h4>
Pour commencer le décodage des données qui ne sont pas adjacentes aux données précédemment envoyées (par exemple, après une recherche), il n’est <>pas nécessaire</em> de vider le décodeur ; toutefois, les données d’entrée après la discontinuité doivent commencer à une limite de flux/trame clé appropriée.
Pour certains formats vidéo - à savoir H.264, H.265, VP8 et VP9 - il est également possible de modifier la taille de l’image ou la configuration mid-stream. Pour ce faire, vous devez empaqueter l’intégralité des nouvelles données de configuration spécifiques au codec avec l’image clé dans une mémoire tampon unique (y compris les codes de démarrage) et la soumettre en tant que <mémoire tampon d’entrée régulière</forte forte>>.
Vous recevrez une #INFO_OUTPUT_FORMAT_CHANGED
valeur de retour à partir ou #dequeueOutputBuffer dequeueOutputBuffer
un Callback#onOutputBufferAvailable onOutputFormatChanged
rappel juste après la modification de la taille de l’image et avant que les images avec la nouvelle taille aient été retournées. <p class=note><forte>Remarque :</strong> , tout comme le cas pour les données spécifiques au codec, soyez prudent lors de l’appel #flush
peu de temps après avoir modifié la taille de l’image. Si vous n’avez pas reçu la confirmation de la modification de la taille de l’image, vous devez répéter la demande de nouvelle taille d’image.
<gestion des< erreurs h3>/h3>
Méthodes d’usine #createByCodecName createByCodecName
et#createEncoderByType EncoderByType
#createDecoderByType createDecoder
/levées IOException
en cas d’échec que vous devez intercepter ou déclarer pour passer. Les méthodes MediaCodec lèvent IllegalStateException
lorsque la méthode est appelée à partir d’un état de codec qui ne l’autorise pas ; cela est généralement dû à une utilisation incorrecte de l’API d’application. Les méthodes impliquant des mémoires tampons sécurisées peuvent lever CryptoException
, qui contient d’autres informations d’erreur obtenues à partir de CryptoException#getErrorCode
.
Les erreurs de codec interne entraînent une CodecException
altération du contenu multimédia, une défaillance matérielle, une épuisement des ressources, et ainsi de suite, même lorsque l’application utilise correctement l’API. L’action recommandée lors de la réception d’un CodecException
peut être déterminée en appelant CodecException#isRecoverable
et CodecException#isTransient
: <ul><li><strong>recoverable errors :</strong> If isRecoverable()
retourne true, puis appelez #stop
, #configure configure(…)
et #start
pour récupérer.</li li><><fort>erreurs temporaires :</strong> Si isTransient()
retourne true, les ressources sont temporairement indisponibles et la méthode peut être retentée ultérieurement.</li li><><strong>fatal errors :</strong> If both isRecoverable()
and isTransient()
return false, the CodecException
is fatal and the codec must be #reset reset or #release released.</li></ul>
Les deux isRecoverable()
et isTransient()
ne retournent pas true en même temps.
<h2 id=History"History>">Valid API Calls and API History</h2>
Cette section récapitule les appels d’API valides dans chaque état et l’historique des API de la classe MediaCodec. Pour connaître les numéros de version de l’API, consultez 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 ; hauteur : 83 px ; } .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 > div > { transform : skew(45deg, 0deg) translate(-55px, 55px) rotate(-45deg) ; }</style>
<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><tr><td>○ ;</td td>><Experimental support</td></tr tr><tr><td>[ ]</td td><>Deprecated</td></tr tr<><>td>⎋ ;</td td><restricted to surface input mode</td></tr tr tr>><><⎆ ;<>/td td><restricted to surface output mode</td></tr tr tr>><><▧ ;<>/td td>><restricted to ByteBuffer input mode</td></tr tr><<>td>↩ ;</td td><restricted to synchronous mode</td></tr tr tr>><><⇄ ;<>/td td>><restricted to asynchrone mode</td></tr tr><tr><(> )</td td>><peut être appelée, mais ne doit pas</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 div><style="background :#f4b400"divConfig>/<div/div></div><></th<>th class=deg45><div div><style="><background :#e67c73"><div>Flushed</div></div/div><></th 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/div></div/div>< /th><class=deg45><div><div style="background :#db4437"><div>Error</div/div><></div/div></th th<>class=deg45><div div><div style="background :#666"><div>Publication</div></div/div><></><<>th/><th th colspan="8">SDK Version</th></tr<>tr<>th colspan="7">State</<<>>><>th 16</<>>th th 17</th<>th>18</th<>th>19</th th<>>20</>><th th 21</th th th><>22</th 23>><</th></tr></thead<>tbody class=api><tr><td></><<>td/><><td/td><<>/td/><><td td/td><<>/td td/td><><td>< class=fn><#createByCodecName createByCodecName
/td td<>>● ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td></tr tr>><<td></td>><</td><>><<<> td/><<><>><td td/td td/><><td/td td/td><td class=fn><#createDecoderByType createDecoderByType
/td td<>>● ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td></tr tr>><<td></td>><</td><>><<<> td/><<><>><td td/td td/><><td/td td/td><td class=fn><#createEncoderByType createEncoderByType
/td td<>>● ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr><><>< 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>/tr tr<>td>><16+</td<>td>-</td-/<>>td>>< td<-</td td-/>><td-</><>td td-</td-/<>>td-</td><td class=fn<#configure configure
>/td td><>● ;<</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><>⁕ ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr>><<td>-</td td>><18+</td<>>-/td td<-</>><td td-/><>td td-</><>td td-</><>td-/td><td class<=fn>#createInputSurface createInputSurface
</td td></td><<> td></td td/td><>⎋ ;<</td><>⎋ ;</td><>⎋ ;</td><>⎋ ;</td><>⎋ ;</td><>⎋ ;</td>/tr 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><&>#9679 ;</td><&>#9639 ;</td><&>#9639 ;</td><&>#9639 ;</td><>⁕ ; ▧ ; ↩ ;</td><&>#9639 ; ↩ ;</td><&>#9639 ; ↩ ;</td>/tr tr><<>td>-</td><td>-</td td><>16+</td td>><16+</td td><>16+</td<>> td-</td td>-/td<>td-</td td<>class=fn<#dequeueOutputBuffer dequeueOutputBuffer
>/td td><>#9679 ;<</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><>⁕ ; ↩ ;</td><&>#8617 ;</td><&>#8617 ;</td>/tr tr><<>td>-</td><td>-</td td><>16+</td td>><16+</td td><>16+</td<>> td-</td td>-/td<>td-</td td<>class=fn<#flush flush
>/td td><>#9679 ;<</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td></tr tr><<>td>18+</td td><>18+</td td>><18+</td td><>18+</><td td>18+</td td><>18+</td td<>>-</td<>td class=fn>#getCodecInfo getCodecInfo
</td<>>< td/>><<td td/td<>>● ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr>><<td>-</td><> td-</<>>td(21+)</>><td td 21+</><>td td(21+)</td><td>-</td-/td<>-/td td>-</td><class=fn><#getInputBuffer getInputBuffer
/td><></><>>><><<><<td/td><<td></td td>><● ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr><<>td>-</td><> td-</td td>><16+</<>>td(16+)</<>td td>(16+)</td><td>-</td-/td>>< td-</td<>class=fn<#getInputBuffers getInputBuffers
>/td><>● ;<</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td td><>[⁕ ; ↩ ;]</td td><>[↩ ;]</td td><>[↩ ;]</td></tr tr><><td>-</td td><>21+</td>>< td(21+)</>><td(21+)/td<>>(21+)</td(21+)</td><>-</td><><<> td class=fn#getInputFormat getInputFormat
<>/td><<> td/><<>td td/<>><><><td/><td></td td>><● ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr>><<td>-</td><> td-</>><td(21+)</<>>td td 21+</><>td td(21+)</td<>td>-</td td-/td><td-</td><class>=fn#getInputImage getInputImage
<>/td/>><><><<<>><><<><td/td><></td td><>○ ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr<>td><>18+</td td>><18+</td td>><18+</<>>td td 18+</><td td>18+</td td<>>18+/td td 18+</td>><<>< class=fn>#getName getName
</><<>td td/>><<td td><<>● ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr><><td>-</td><td>-</td><>(21+)</><>td td 21+</><>td td 21+</td>>< td-/td td-</td><> td-</td><td class=fn><#getOutputBuffer getOutputBuffer
/td><td></><<>><td td td<></Td><><td/td><></td td><>● ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr><<>td>-</td><td>-</td td><>16+</td td>><16+</td td><>16+</td<>> td-</td td>-/td<>td-</td td<>class=fn<#getOutputBuffers getOutputBuffers
>/td td><>#9679 ;<</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</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><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr><><td>-</td><td>-</td><>(21+)</><>td td 21+</><>td td 21+</td>>< td-/td td-</td><> td-</td><td class=fn><#getOutputFormat(int)
/td><td></><<>><td td td<></Td><><td/td><></td td><>● ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr><><td>-</td><td>-</td><>(21+)</><>td td 21+</><>td td 21+</td>>< td-/td td-</td><> td-</td><td class=fn><#getOutputImage getOutputImage
/td><td></><<>><td td td<></Td><><td/td><></td td><>○ ;</td><&>#9679 ;</td><&>#9679 ;</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><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><>⁕ ;</td><&>#9679 ;</td><&>#9679 ;</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><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><>⁕ ;</td><&>#9679 ;</td><&>#9679 ;</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><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr><><td>-</td>><-</>><td td-</td td><>16+</td><td>16+</<>td td>-/td-</td>><-</td><td class=fn><#releaseOutputBuffer(int, boolean)
/td td><>● ;<</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><>⁕ ;</td><&>#9679 ;</td><>⁕ ;</td>/tr 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>/tr tr><td>><21+</td td>><21+</>><td td 21+</><>td td 21+</><td td>21+</td td<>>21+/td td 21+</td>><< td-/td><td class=fn><#reset reset
/td>><< td/>><<td td><<></Td><><td/td><></td td><>● ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr 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><&>#9679 ;</td><td><#setCallback(Callback, Handler) ⁕
/td></tr tr><<>td>-</td td><>23+</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>/tr tr><td>><23+</td td>><23+</td td>><23+</<>>td td 23+</><td td>23+</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>/tr tr><><td>-</td td>><23+</td td><>23+</<>>td td 23+</><>td td 23+</td td><>-</td td-/td><td-</td><class>=fn<#setOutputSurface setOutputSurface
>/td><td></<>><td td/td td><<></Td><><td/><<>td/td>><</td/td><td></td/td td<>>⎆ ;</td>/tr tr<>td>><19+</td td><>19+</td td>><19+</>><td td 19+</<>td td>19+</td>><(19+)</td><> td-</td><td class=fn>#setParameters setParameters
</><<>td td/<>><td td/td td><<></Td><td>● ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td></tr tr><<>td>-</td>><(16+)</><td td>(16+)</><>td td 16+</td<>>(16+)/td>><(16+)<</td-/td><>-</td><td class=fn<#setVideoScalingMode setVideoScalingMode
>/td<>>⎆ ;</td><>⎆ ;</td><>⎆ ;</td><>⎆ ;</td><>⎆ ;</td><>⎆ ;</td><>⎆ ;</td><>⎆ ;</td>/tr tr>>><<(29+)</td><>td 29+</><>td td 29+</>><td td 29+</td>><(29+)/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/><><td/td/td/<>tr tr><><> td-</td td-</>><<>>td td 18+</td td><>18+</td td>-/td<>-/td-</td<>>-/><<>td-</td><td class=fn><#signalEndOfInputStream signalEndOfInputStream
/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><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><>⁕ ;</td><&>#9679 ;</td><&>#9679 ;</td>/tr tr><<>td>-</td><td>-</td td><>16+</td td>><16+</td td><>16+</td<>> td-</td td>-/td<>td-</td td<>class=fn<#stop stop
>/td td><>#9679 ;<</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td><&>#9679 ;</td></tr/tbody><></table>
Documentation Java pour android.media.MediaCodec
.
Les parties de cette page sont des modifications basées sur le travail créé et partagé par le projet Android Open Source et utilisés en fonction des termes décrits dans la licence d’attribution Creative Commons 2.5.
Champs
BufferFlagCodecConfig |
Obsolète.
Cela a indiqué que la mémoire tampon marquée comme telle contient l’initialisation des codecs/ les données spécifiques au codec au lieu de données multimédias. |
BufferFlagDecodeOnly |
Obsolète.
Cela indique que la mémoire tampon est décodée et met à jour l’état interne du décodeur, mais ne produit aucune mémoire tampon de sortie. |
BufferFlagEndOfStream |
Obsolète.
Cela signale la fin du flux, i. |
BufferFlagKeyFrame |
Obsolète.
Cela indique que la mémoire tampon (encodée) marquée comme telle contient les données d’une trame clé. |
BufferFlagPartialFrame |
Obsolète.
Cela indique que la mémoire tampon contient uniquement une partie d’une trame et que le décodeur doit traiter les données jusqu’à ce qu’une mémoire tampon sans cet indicateur apparaisse avant de décoder le frame. |
BufferFlagSyncFrame |
Obsolète.
Cela indique que la mémoire tampon (encodée) marquée comme telle contient les données d’une trame clé. |
ConfigureFlagEncode |
Obsolète.
Si ce codec doit être utilisé en tant qu’encodeur, passez cet indicateur. |
ConfigureFlagUseBlockModel |
Obsolète.
Si ce codec doit être utilisé avec |
ConfigureFlagUseCryptoAsync |
Obsolète.
Cet indicateur doit être utilisé uniquement sur un décodeur sécurisé. |
CryptoModeAesCbc |
Obsolète.
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. |
CryptoModeAesCtr | |
CryptoModeUnencrypted | |
InfoOutputBuffersChanged |
Obsolète.
Les mémoires tampons de sortie ont changé, le client doit faire référence au nouvel ensemble de mémoires tampons de sortie retournées par |
InfoOutputFormatChanged |
Obsolète.
Le format de sortie a changé, les données suivantes suivent le nouveau format. |
InfoTryAgainLater |
Obsolète.
Si un délai d’expiration non négatif avait été spécifié dans l’appel, |
ParameterKeyHdr10PlusInfo |
Définissez les métadonnées HDR10+ sur le cadre d’entrée en file d’attente suivant. |
ParameterKeyLowLatency |
Activez/désactivez le mode de décodage à faible latence. |
ParameterKeyOffsetTime |
Spécifiez un décalage (en micro seconde) à ajouter au-dessus des horodatages. |
ParameterKeyRequestSyncFrame |
Demandez à l’encodeur de produire une trame de synchronisation « bientôt ». |
ParameterKeySuspend |
Suspendre/reprendre temporairement l’encodage des données d’entrée. |
ParameterKeySuspendTime |
Lorsqu’il |
ParameterKeyTunnelPeek |
Contrôlez l’aperçu vidéo du premier frame lorsqu’un codec est configuré pour le mode tunnel avec |
ParameterKeyVideoBitrate |
Modifiez la vitesse de transmission cible d’un encodeur vidéo à la volée. |
VideoScalingModeScaleToFit |
Obsolète.
Le contenu est mis à l’échelle vers les dimensions de la surface |
VideoScalingModeScaleToFitWithCropping |
Obsolète.
Le contenu est mis à l’échelle, conservant son rapport d’aspect, la surface entière est utilisée, le contenu peut être rogné. |
Propriétés
CanonicalName |
Récupérez le nom du codec sous-jacent. |
Class |
Retourne la classe runtime de ce |
CodecInfo |
Obtenez les informations de codec. |
Handle |
Handle de l’instance Android sous-jacente. (Hérité de Object) |
InputFormat |
Appelez-le une fois |
JniIdentityHashCode |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
JniPeerMembers |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. |
Metrics |
Retournez des données de métriques sur l’instance de codec actuelle. |
Name |
Récupérez le nom du codec. |
OutputFormat |
Appelez-le après dequeueOutputBuffer signale une modification de format en retournant |
PeerReference |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
SupportedVendorParameters |
Retourne une liste de noms de paramètres de fournisseur. |
ThresholdClass |
Cette API prend en charge l’infrastructure Mono pour Android et n’est pas destinée à être utilisée directement à partir de votre code. (Hérité de Object) |
ThresholdType |
Cette API prend en charge l’infrastructure Mono pour Android et n’est pas destinée à être utilisée directement à partir de votre code. (Hérité de Object) |
Méthodes
Clone() |
Crée et retourne une copie de cet objet. (Hérité de Object) |
Configure(MediaFormat, Surface, MediaCodecConfigFlags, MediaDescrambler) |
Configurez un composant à utiliser avec un déscrambler. |
Configure(MediaFormat, Surface, MediaCrypto, MediaCodecConfigFlags) |
Configure un composant. |
CreateByCodecName(String) |
Si vous connaissez le nom exact du composant que vous souhaitez instancier, utilisez cette méthode pour l’instancier. |
CreateDecoderByType(String) |
Instanciez le décodeur préféré prenant en charge les données d’entrée du type mime donné. |
CreateEncoderByType(String) |
Instanciez l’encodeur préféré prenant en charge les données de sortie du type mime donné. |
CreateInputSurface() |
Demande à une Surface d’utiliser comme entrée à un encodeur, à la place des mémoires tampons d’entrée. |
CreatePersistentInputSurface() |
Créez une surface d’entrée persistante qui peut être utilisée avec des codecs qui ont normalement une surface d’entrée, telle que des encodeurs vidéo. |
DequeueInputBuffer(Int64) |
Retourne l’index d’une mémoire tampon d’entrée à remplir avec des données valides ou -1 si aucune mémoire tampon n’est actuellement disponible. |
DequeueOutputBuffer(MediaCodec+BufferInfo, Int64) |
Mettre en file d’attente une mémoire tampon de sortie, bloquer au maximum les microsecondes « timeoutUs ». |
Dispose() |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
Dispose(Boolean) |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
Equals(Object) |
Indique si un autre objet est « égal à » celui-ci. (Hérité de Object) |
Flush() |
Videz les ports d’entrée et de sortie du composant. |
GetHashCode() |
Retourne une valeur de code de hachage pour l'objet. (Hérité de Object) |
GetInputBuffer(Int32) |
Renvoie un |
GetInputBuffers() |
Obsolète.
Récupérez l’ensemble de mémoires tampons d’entrée. |
GetInputImage(Int32) |
Renvoie un objet Image accessible en écriture pour un index de mémoire tampon d’entrée de file d’attente contenant l’image vidéo d’entrée brute. |
GetOutputBuffer(Int32) |
Renvoie un byteBuffer en lecture seule pour un index de mémoire tampon de sortie de file d’attente. |
GetOutputBuffers() |
Obsolète.
Récupérez l’ensemble de mémoires tampons de sortie. |
GetOutputFormat(Int32) |
Retourne le format de sortie d’une mémoire tampon de sortie spécifique. |
GetOutputFrame(Int32) |
Retourne un objet |
GetOutputImage(Int32) |
Renvoie un objet Image en lecture seule pour un index de mémoire tampon de sortie en file d’attente qui contient l’image vidéo brute. |
GetParameterDescriptor(String) |
Décrire un paramètre portant le nom. |
GetQueueRequest(Int32) |
Retourne un |
JavaFinalize() |
Appelé par le garbage collector sur un objet lorsque le garbage collection détermine qu’il n’y a plus de références à l’objet. (Hérité de Object) |
MapHardwareBuffer(HardwareBuffer) |
Mappez un |
Notify() |
Réveille un thread unique qui attend le moniteur de cet objet. (Hérité de Object) |
NotifyAll() |
Réveille tous les threads qui attendent le moniteur de cet objet. (Hérité de Object) |
QueueInputBuffer(Int32, Int32, Int32, Int64, MediaCodecBufferFlags) |
Après avoir rempli une plage de la mémoire tampon d’entrée à l’index spécifié, envoyez-la au composant. |
QueueSecureInputBuffer(Int32, Int32, MediaCodec+CryptoInfo, Int64, MediaCodecBufferFlags) |
Similaire à |
Release() |
Libérer des ressources utilisées par l’instance de codec. |
ReleaseOutputBuffer(Int32, Boolean) |
Si vous avez terminé avec une mémoire tampon, utilisez cet appel pour renvoyer la mémoire tampon au codec ou pour l’afficher sur l’aire de sortie. |
ReleaseOutputBuffer(Int32, Int64) |
Si vous avez terminé avec une mémoire tampon, utilisez cet appel pour mettre à jour son horodatage de surface et le renvoyer au codec pour l’afficher sur l’aire de sortie. |
Reset() |
Retourne le codec à son état initial (non initialisé). |
SetAudioPresentation(AudioPresentation) |
Définit la présentation audio. |
SetCallback(MediaCodec+Callback) |
Définit un rappel asynchrone pour les événements MediaCodec actionnables sur le looper par défaut. |
SetCallback(MediaCodec+Callback, Handler) |
Définit un rappel asynchrone pour les événements MediaCodec actionnables sur le looper par défaut. |
SetHandle(IntPtr, JniHandleOwnership) |
Définit la propriété Handle. (Hérité de Object) |
SetInputSurface(Surface) |
Configure le codec (e. |
SetOnFirstTunnelFrameReadyListener(Handler, MediaCodec+IOnFirstTunnelFrameReadyListener) |
Inscrit un rappel à appeler lorsque la première trame de sortie a été décodée et est prête à être rendue sur un codec configuré pour le mode tunnel avec |
SetOnFrameRenderedListener(MediaCodec+IOnFrameRenderedListener, Handler) |
Inscrit un rappel à appeler lorsqu’une trame de sortie est rendue sur l’aire de sortie. |
SetOutputSurface(Surface) |
Définit dynamiquement la surface de sortie d’un codec. |
SetParameters(Bundle) |
Communiquez des modifications de paramètre supplémentaires à l’instance du composant. |
SetVideoScalingMode(VideoScalingMode) |
Si une surface a été spécifiée dans un appel précédent pour |
SignalEndOfInputStream() |
Signale la fin du flux en entrée. |
Start() |
Après avoir correctement configuré le composant, appelez |
Stop() |
Terminez la session de décodage/encode, notez que l’instance de codec reste active et prête à être |
SubscribeToVendorParameters(IList<String>) |
Abonnez-vous aux paramètres du fournisseur afin que ces paramètres soient présents |
ToArray<T>() |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
ToString() |
Retourne une représentation de chaîne de l'objet. (Hérité de Object) |
UnregisterFromRuntime() |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
UnsubscribeFromVendorParameters(IList<String>) |
Désinscrivez-vous des paramètres du fournisseur afin que ces paramètres ne soient pas présents |
Wait() |
Provoque l’attente du thread actuel jusqu’à ce qu’il soit réveillé, généralement en étant <averti par em ou><em>interrompu</em>.<> (Hérité de Object) |
Wait(Int64) |
Provoque l’attente du thread actuel jusqu’à ce qu’il soit réveillé, généralement en étant <averti< par> em>ou <em>interrompu/em>,< ou jusqu’à ce qu’une certaine quantité de temps réel s’est écoulée. (Hérité de Object) |
Wait(Int64, Int32) |
Provoque l’attente du thread actuel jusqu’à ce qu’il soit réveillé, généralement en étant <averti< par> em>ou <em>interrompu/em>,< ou jusqu’à ce qu’une certaine quantité de temps réel s’est écoulée. (Hérité de Object) |
Implémentations d’interfaces explicites
IJavaPeerable.Disposed() |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
IJavaPeerable.DisposeUnlessReferenced() |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
IJavaPeerable.Finalized() |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
IJavaPeerable.JniManagedPeerState |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
IJavaPeerable.SetJniIdentityHashCode(Int32) |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
IJavaPeerable.SetPeerReference(JniObjectReference) |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. (Hérité de Object) |
Méthodes d’extension
JavaCast<TResult>(IJavaObject) |
Effectue une conversion de type vérifiée par le runtime Android. |
JavaCast<TResult>(IJavaObject) |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. |
GetJniTypeName(IJavaPeerable) |
La classe MediaCodec peut être utilisée pour accéder aux codecs multimédias de bas niveau, i. |