MediaCodec クラス
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
MediaCodec クラスを使用して、低レベルのメディア コーデック (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
- 継承
- 属性
注釈
MediaCodec クラスを使用して、低レベルのメディア コーデック (エンコーダー/デコーダー コンポーネント) にアクセスできます。 これは、Android の低レベルのマルチメディア サポート インフラストラクチャの一部です (通常は 、MediaSync
、MediaMuxer
、、MediaCrypto
、Image
Surface
MediaDrm
とAudioTrack
一緒MediaExtractor
に使用されます)。
<center><img src="../../../images/media/mediacodec_buffers.svg" style="width: 540px;height: 205px" alt="MediaCodec buffer flow diagram"></center>
大まかに言えば、コーデックは入力データを処理して出力データを生成します。 データは非同期的に処理され、一連の入力バッファーと出力バッファーが使用されます。 単純なレベルでは、空の入力バッファーを要求 (または受信) し、データでいっぱいにして、処理のためにコーデックに送信します。 コーデックはデータを使用し、空の出力バッファーのいずれかに変換します。 最後に、入力された出力バッファーを要求 (または受信) し、その内容を使用してコーデックに解放します。
<h3 id=quality Floor>"quality Floor">Minimum Quality Floor for Video Encoding</h3>
以降、 android.os.Build.VERSION_CODES#S
Android の Video MediaCodecs では最小品質のフロアが適用されます。 その目的は、低品質のビデオ エンコードを排除することです。 この品質フロアは、コーデックが Variable Bitrate (VBR) モードの場合に適用されます。コーデックが Constant Bitrate (CBR) モードの場合は適用されません。 品質の床の適用はまた、特定のサイズ範囲に制限されています。このサイズ範囲は、現在、320 x 240 以上から 1920 x 1080 までのビデオ解像度用です。
この品質フロアが有効な場合、コーデックとサポートフレームワークコードは、生成されたビデオが少なくとも「公平」または「良い」品質であることを保証するために機能します。 これらのターゲットの選択に使用されるメトリックは、選択したテスト シーケンスのターゲット スコアが 70 の VMAF (ビデオマルチメソッド評価関数) です。
一般的な効果は、一部のビデオでは、最初に構成されたよりも高いビットレートが生成されるということです。 これは、非常に低いビットレートで構成されたビデオで最も注目に値します。コーデックでは、"fair" または "good" 品質のビデオを生成する可能性が高いと判断されたビットレートが使用されます。 もう一つの状況は、ビデオに非常に複雑なコンテンツ(たくさんの動きと詳細)が含まれている場合です。このような構成では、コーデックは必要に応じて追加ビットレートを使用して、コンテンツの詳細をすべて失わないようにします。
この品質レベルは、高ビットレートでキャプチャされたコンテンツには影響しません (高ビットレートでは、すべての詳細をエンコードするのに十分な容量をコーデックに提供する必要があります)。 品質フロアは CBR エンコードでは動作しません。 現在、品質レベルは 320 x 240 以下の解像度でも、解像度が 1920 x 1080 を超えるビデオでも動作しません。
<h3>データ型</h3>
コーデックは、圧縮データ、生オーディオ データ、生ビデオ データの 3 種類のデータで動作します。 3 種類のデータはすべて使用して ByteBuffer ByteBuffers
処理できますが、コーデックのパフォーマンスを向上させるには、生のビデオ データ用に a を使用 Surface
する必要があります。 Surface では、マッピングや ByteBuffers へのコピーを行わずにネイティブ ビデオ バッファーを使用します。したがって、はるかに効率的です。 Surface を使用する場合、通常は生のビデオ データにアクセスできませんが、クラスを ImageReader
使用して、セキュリティで保護されていないデコード (未加工) ビデオ フレームにアクセスできます。 一部のネイティブ バッファーは ByteBuffer#isDirect ダイレクト ByteBuffers にマップされる可能性があるため、これは ByteBuffers を使用するよりも効率的な場合があります。 ByteBuffer モードを使用する場合Image
は、クラスと/#getInputImage getInput
#getOutputImage OutputImage(int)
.
<h4>圧縮バッファー</h4>
入力バッファー (デコーダーの場合) と出力バッファー (エンコーダーの場合) には、MediaFormat#KEY_MIME 形式の種類に従って圧縮されたデータが含まれます。 ビデオの種類の場合、これは通常、1 つの圧縮されたビデオ フレームです。 オーディオ データの場合、これは通常、1 つのアクセス ユニット (通常、フォーマットの種類によって指示される数ミリ秒のオーディオを含むエンコードされたオーディオ セグメント) ですが、バッファーに複数のエンコードされたオーディオ アクセス ユニットが含まれている可能性があるため、この要件は若干緩和されます。 どちらの場合も、バッファーは任意のバイト境界で開始または終了するのではなく、フレーム/アクセス ユニットの境界でフラグが設定されている場合を除き、フレーム/アクセス ユニットの境界で #BUFFER_FLAG_PARTIAL_FRAME
開始または終了しません。
<h4>Raw Audio Buffers</h4>
生オーディオ バッファーには PCM オーディオ データのフレーム全体が含まれています。これはチャネル順のチャネルごとに 1 つのサンプルです。 各 PCM オーディオ サンプルは、ネイティブバイト順の 16 ビット符号付き整数または float です。 浮動小数点 PCM エンコードの生オーディオ バッファーは、MediaFormat の MediaFormat#KEY_PCM_ENCODING が MediaCodec #configure configure(…)
中に AudioFormat#ENCODING_PCM_FLOAT に設定され、デコーダーまたは#getInputFormat
エンコーダーで#getOutputFormat
確認された場合にのみ使用できます。 MediaFormat で float PCM を確認するサンプル メソッドは次のとおりです。
static boolean isPcmFloat(MediaFormat format) {
return format.getInteger(MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_16BIT)
== AudioFormat.ENCODING_PCM_FLOAT;
}
短い配列で、16 ビット符号付き整数オーディオ データを含むバッファーの 1 つのチャネルを抽出するために、次のコードを使用できます。
// Assumes the buffer PCM encoding is 16 bit.
short[] getSamplesForChannel(MediaCodec codec, int bufferId, int channelIx) {
ByteBuffer outputBuffer = codec.getOutputBuffer(bufferId);
MediaFormat format = codec.getOutputFormat(bufferId);
ShortBuffer samples = outputBuffer.order(ByteOrder.nativeOrder()).asShortBuffer();
int numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
if (channelIx < 0 || channelIx >= numChannels) {
return null;
}
short[] res = new short[samples.remaining() / numChannels];
for (int i = 0; i < res.length; ++i) {
res[i] = samples.get(i * numChannels + channelIx);
}
return res;
}
<h4>Raw Video Buffers</h4>
ByteBuffer モードでは、ビデオ バッファーは MediaFormat#KEY_COLOR_FORMAT カラー形式に従ってレイアウトされます。 サポートされている色形式を配列#getCodecInfo
.
.
MediaCodecInfo#getCapabilitiesForType getCapabilitiesForType(…)
CodecCapabilities#colorFormats colorFormats
として取得できます。 ビデオ コーデックは、3 種類のカラー形式<をサポートする場合があります。ul><li><strong>native raw video format:</strong> これはマークCodecCapabilities#COLOR_FormatSurface
され、入力または出力 Surface で使用できます。</li li>><<強力>な柔軟な YUV バッファー</強い> (などCodecCapabilities#COLOR_FormatYUV420Flexible
): これらは、入力/出力 Surface および ByteBuffer モードで使用#getOutputImage OutputImage(int)
#getInputImage getInput
/できます。</li li>><<strong>other, specific formats:</strong> 通常は ByteBuffer モードでのみサポートされます。 一部の色形式はベンダー固有です。 その他の定義は次のとおりです CodecCapabilities
。 柔軟な形式に相当する色書式の場合でも #getInputImage getInput
/#getOutputImage OutputImage(int)
、使用できます。</li></ul>
すべてのビデオ コーデックは、柔軟な YUV 4:2:0 バッファーをサポートしています android.os.Build.VERSION_CODES#LOLLIPOP_MR1
。
<h4>古いデバイス<での生ビデオ ByteBuffers へのアクセス/h4>
サポートする前にandroid.os.Build.VERSION_CODES#LOLLIPOP
Image
、未加工の出力バッファーのレイアウトをMediaFormat#KEY_STRIDE
理解するために、出力形式の値とMediaFormat#KEY_SLICE_HEIGHT
出力形式の値を使用する必要があります。 <p class=note 一部のデバイスでは、スライスの高さが 0 としてアドバタイズされることに注意してください> 。 これは、スライスの高さがフレームの高さと同じか、スライスの高さがある値 (通常は 2 の累乗) に合わせたフレームの高さであることを意味する可能性があります。 残念ながら、この場合、実際のスライスの高さを伝える標準的で簡単な方法はありません。 さらに、平面の U
垂直ストライドも指定も定義もされませんが、通常はスライスの高さの半分です。
キーとキーMediaFormat#KEY_HEIGHT
はMediaFormat#KEY_WIDTH
ビデオ フレームのサイズを指定しますが、ほとんどの場合、ビデオ (画像) はビデオ フレームの一部のみを占めます。 これは、"トリミング四角形" で表されます。
#getOutputFormat 出力形式から生出力イメージのトリミング四角形を取得するには、次のキーを使用する必要があります。 これらのキーが存在しない場合、ビデオはビデオ フレーム全体を占有します。トリミング四角形は、MediaFormat#KEY_ROTATION 回転を適用する前/em> の<出力フレーム <em>のコンテキストで認識されます。 <table style="width: 0%"><thead><tr><th>Format Key</th><Type<>/th<>th>Description</th<>/tr></thead<>tbody><tr><tdMediaFormat#KEY_CROP_LEFT
></td td><>Integer</td td td<>Td>トリミング四角形</td/tr tr>><<td<>><MediaFormat#KEY_CROP_TOP
/td td<>>整数<の左座標 (x)td><td>トリミング四角形</td/tr tr><td>><<<MediaFormat#KEY_CROP_RIGHT
>/td td<>td>の上座標 (y) 整数</td<>td>右座標 (x) <トリミング四角形<の厳密>な負の 1</強>さ/td<>/tr><tr<>td>MediaFormat#KEY_CROP_BOTTOM
</td<>td>整数</td<>td td>下座標 (y) <強い>MINUS 1</strong>のトリミング四角形</td></tr tr><td><colspan=3> 右と下の座標は、トリミングされた出力画像の最も有効な列または最下位の有効な行の座標として認識できます。 </td></tr></tbody></table>
ビデオ フレームのサイズ (回転前) は、次のように計算できます。
MediaFormat format = decoder.getOutputFormat(…);
int width = format.getInteger(MediaFormat.KEY_WIDTH);
if (format.containsKey(MediaFormat.KEY_CROP_LEFT)
&& format.containsKey(MediaFormat.KEY_CROP_RIGHT)) {
width = format.getInteger(MediaFormat.KEY_CROP_RIGHT) + 1
- format.getInteger(MediaFormat.KEY_CROP_LEFT);
}
int height = format.getInteger(MediaFormat.KEY_HEIGHT);
if (format.containsKey(MediaFormat.KEY_CROP_TOP)
&& format.containsKey(MediaFormat.KEY_CROP_BOTTOM)) {
height = format.getInteger(MediaFormat.KEY_CROP_BOTTOM) + 1
- format.getInteger(MediaFormat.KEY_CROP_TOP);
}
<p class=note> デバイス間で意味 BufferInfo#offset BufferInfo.offset
が一致しないことにも注意してください。 一部のデバイスでは、オフセットはトリミング四角形の左上のピクセルを指し、ほとんどのデバイスではフレーム全体の左上のピクセルを指しています。
<h3>States</h3>
その有効期間中、コーデックは概念的には、停止、実行中、またはリリースの 3 つの状態のいずれかで存在します。 停止された集合状態は、実際には 3 つの状態 (初期化されていない、構成済み、エラー) のコンコンフェデレーションですが、実行中の状態は概念的に 3 つのサブ状態 (Flushed、Running、End-of-Stream) を介して進行します。
<center><img src="../../../images/media/mediacodec_states.svg" style="width: 519px;height: 356px" alt="MediaCodec state diagram"></center>
いずれかのファクトリ メソッドを使用してコーデックを作成すると、コーデックは初期化されていない状態になります。 まず、それを構成 #configure configure(…)
する必要があります。これにより構成済みの状態になります。次に、呼び出 #start
して実行中の状態に移動します。 この状態では、前述のバッファー キュー操作を使用してデータを処理できます。
実行中の状態には、Flushed、Running、End-of-Stream の 3 つのサブ状態があります。 コーデックが Flushed サブ状態の直後 #start
に、すべてのバッファーを保持します。 最初の入力バッファーがデキューされるとすぐに、コーデックは実行中のサブ状態に移動し、そこでほとんどの時間が費やされます。 #BUFFER_FLAG_END_OF_STREAM ストリームの終了マーカーを使用して入力バッファーをキューに入れると、コーデックはストリームの終了サブ状態に遷移します。 この状態では、コーデックはそれ以上の入力バッファーを受け入れなくなりますが、出力でストリームの終わりに達するまで出力バッファーを生成します。 デコーダーの場合、フラッシュされたサブ状態にいつでも戻り、実行中の状態 #flush
に戻すことができます。 <p class=note><strong Note strong>Note:</strong> Flushed 状態に戻る操作はデコーダーでのみサポートされており、エンコーダーでは機能しない可能性があります (動作は未定義です)。
コーデックを初期化されていない状態に戻す呼び出し #stop
。ここで、再び構成できます。 コーデックの使用が完了したら、コーデックを呼び出 #release
して解放する必要があります。
まれに、コーデックでエラーが発生し、エラー状態に移行することがあります。 これは、キュー操作からの無効な戻り値を使用して、または例外を介して通信されます。 コーデックを再び使用できるようにするための呼び出 #reset
し。 これを任意の状態から呼び出して、コーデックを初期化されていない状態に戻すことができます。 それ以外の場合は、ターミナル Released 状態に移動する呼び出し #release
。
<h3>Creation</h3>
特定MediaFormat
の MediaCodec を作成するために使用MediaCodecList
します。 ファイルまたはストリームをデコードするときに、目的の形式 MediaExtractor#getTrackFormat MediaExtractor.getTrackFormat
を取得できます。 使用して MediaFormat#setFeatureEnabled MediaFormat.setFeatureEnabled
追加する特定の機能を挿入し、その特定のメディア形式を処理できるコーデックの名前を取得するために呼び出 MediaCodecList#findDecoderForFormat MediaCodecList.findDecoderForFormat
します。 最後に、次を使用して #createByCodecName
コーデックを作成します。 <p class=note><strong Note strong>Note:</strong> Onandroid.os.Build.VERSION_CODES#LOLLIPOP
, the formatEncoderForFormat
MediaCodecList.findDecoder
/must not contain a MediaFormat#KEY_FRAME_RATE frame rate. 既存のフレーム レート設定をフォーマットでクリアするために使用 format.setString(MediaFormat.KEY_FRAME_RATE, null)
します。
を使用して #createDecoderByType createDecoder
/#createEncoderByType EncoderByType(String)
、特定の MIME タイプの優先コーデックを作成することもできます。 ただし、これは機能の挿入には使用できず、特定の目的のメディア形式を処理できないコーデックを作成する場合があります。
<h4>セキュア デコーダーの<作成/h4>
バージョン以前のバージョン android.os.Build.VERSION_CODES#KITKAT_WATCH
では、セキュリティで保護されたコーデックが一覧に MediaCodecList
表示されない場合がありますが、システムで引き続き使用できる場合があります。 存在するセキュリティで保護されたコーデックは、通常のコーデックの名前 (セキュリティで保護されたすべてのコーデックの名前は .で".secure"
終わる必要があります) #createByCodecName
に追加".secure"
することによって、名前のみでインスタンス化できます。コーデックがシステムに存在しない場合は、IOException
スローされます。
以降 android.os.Build.VERSION_CODES#LOLLIPOP
は、メディア形式の機能を CodecCapabilities#FEATURE_SecurePlayback
使用して、セキュリティで保護されたデコーダーを作成する必要があります。
<h3>初期化</h3>
コーデックを作成した後、データを非同期的に処理する場合に使用して #setCallback setCallback
コールバックを設定できます。 次 #configure 特定のメディア形式を使用してコーデックを構成します。 これは、生のビデオ データ (ビデオ デコーダーなど) を生成するビデオ プロデューサーおよび ndash コーデックの出力 Surface
を指定できる場合です。 これは、セキュリティで保護されたコーデックの復号化パラメーターを設定できる場合にも当たります (参照 MediaCrypto
)。 最後に、一部のコーデックは複数のモードで動作できるため、デコーダーとエンコーダーのどちらを使用するかを指定する必要があります。
そのため android.os.Build.VERSION_CODES#LOLLIPOP
、結果の入力形式と出力形式を構成済み状態で照会できます。 これを使用して、コーデックを開始する前に、結果の構成 (カラー形式など) を確認できます。
生の入力ビデオ バッファーをビデオ コンシューマー & ndash を使用してネイティブに処理する場合。ビデオ エンコーダーや ndash などの生のビデオ入力を処理するコーデック。構成後に使用して #createInputSurface
、入力データの変換先 Surface を作成します。 または、以前に作成した #createPersistentInputSurface 永続的な入力サーフェス #setInputSurface
を使用するようにコーデックを設定します。
<h4 id=CSD>"CSD">コーデック固有のデータ</h4>
一部の形式 (特に AAC オーディオおよび MPEG4、H.264、H.265 ビデオ形式) には、実際のデータに、セットアップ データまたはコーデック固有のデータを含む多数のバッファーがプレフィックスとして付いている必要があります。 このような圧縮形式を処理する場合、このデータはフレーム データの前後 #start
にコーデックに送信する必要があります。 このようなデータは、呼び出しでフラグ #BUFFER_FLAG_CODEC_CONFIG
を使用してマークする #queueInputBuffer queueInputBuffer
必要があります。
コーデック固有のデータは、キー "csd-0"、"csd-1" などの ByteBuffer エントリに渡される #configure configure
形式に含めることもできます。これらのキーは、常にから取得したトラック MediaFormat
に MediaExtractor#getTrackFormat MediaExtractor
含まれています. 形式のコーデック固有のデータは、コーデックに自動的に送信されます#start
。このデータを><明示的に送信することはできません。>厳密に送信しないでください<。 形式にコーデック固有のデータが含まれていない場合は、形式の要件に従って、指定された数のバッファーを使用して適切な順序で送信することを選択できます。 H.264 AVC の場合は、すべてのコーデック固有のデータを連結し、1 つのコーデック構成バッファーとして送信することもできます。
Android では、次のコーデック固有のデータ バッファーが使用されます。 これらは、適切な MediaMuxer
トラック構成のためにトラック形式で設定する必要もあります。 各パラメーター セットと (<sup>*</sup>) でマークされたコーデック固有のデータ セクションは、開始コード "\x00\x00\x00\x01"
で始まる必要があります。
<style>td.NA { background: #ccc; } .mid > tr > td { vertical-align: middle; }</style><table><thead><th>Format</th><th>CSD buffer #0</th<>>CSD buffer #1</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 class=NA>Not Used</td></tr tr><td<>>OPUS</td<>td>Identification header</td td<>td>pre-skip in nanosecs<br> (unsigned 64 ビット ByteOrder#nativeOrder nativeOrder native-order integer.)<br> 識別ヘッダーのスキップ前の値をオーバーライドします。</td td>><Seek Pre-roll in nanosecs<br> (unsigned 64 ビット ByteOrder#nativeOrder native-order integer.)</td></tr tr tdLAC<<><>>/td td<>td>"fLaC"、ASCII のFLAC ストリーム マーカー、br> の<後に STREAMINFO ブロック (必須メタデータ ブロック)<、br> (必要に応じて、任意の数の他のメタデータ ブロック</td<>td class=NA>Not Used</td td><td class=NA>Not Used</td<>/tr tr<>><td>MPEG-4</td)><td>ESDS sup*/sup></td td><td class=NA>Not Used</td><td class=NA>Not Used</td<>/tr tr<>td>><H.264 AVC</td td td><SPS (Sequence Parameter Sets<sup>*</sup>)</td td>><PPS (Picture Parameter Sets<sup>*</sup>)</td 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></tr tr>><<td>VP9</td td><>VP9 CodecPrivate Data (省略可能)</td><td class=NA>Not Used</td><td td class=NA>Not Used</td<>/tr td>>><<AV1</td td<>>AV1 AV1 AV1CodecConfigurationRecord Data (省略可能) </td<>td class=NA>Not Used/<td><td class=NA>Not Used</td></tr></tbody></table>
<p class=note><strong Note strong>Note:</strong> care must be flushed immediately or shortly after start, before any output buffer or output format change has been returned, as the codec specific data may lost during the flush. 適切なコーデック操作を確保するには、このようなフラッシュ後に #BUFFER_FLAG_CODEC_CONFIG
マークされたバッファーを使用してデータを再送信する必要があります。
エンコーダー (または圧縮データを生成するコーデック) は、#BUFFER_FLAG_CODEC_CONFIG codec-config フラグでマークされた出力バッファー内の有効な出力バッファーの前にコーデック固有のデータを作成して返します。 コーデック固有のデータを含むバッファーには、意味のあるタイムスタンプがありません。
<h3>データ処理</h3>
各コーデックは、API 呼び出しのバッファー ID によって参照される入力バッファーと出力バッファーのセットを保持します。 クライアントへの呼び出し #start
が成功した後、入力バッファーも出力バッファーも "所有" しません。 同期モードでは、コーデックから入力バッファーまたは出力バッファーを取得 (所有権を取得) するために呼び出 #dequeueInputBuffer dequeueInput
/#dequeueOutputBuffer OutputBuffer(…)
します。 非同期モードでは、コールバックを介して使用可能なバッファーを自動的に Callback#onInputBufferAvailable MediaCodec.Callback.onInput
/Callback#onOutputBufferAvailable OutputBufferAvailable(…)
受信します。
入力バッファーを取得したら、データを入力し、&ndash を使用して #queueInputBuffer queueInputBuffer
コーデックに送信するか、復号化 #queueSecureInputBuffer queueSecureInputBuffer
を使用する場合に送信します。 同じタイムスタンプを持つ複数の入力バッファーを送信しないでください (コーデック固有のデータがそのようにマークされている場合を除く)。
次に、コーデックは、非同期モードのコールバックを介して、または同期モードでの呼び出しに応答して Callback#onOutputBufferAvailable onOutputBufferAvailable
、読み取り専用の出力バッファーを #dequeueOutputBuffer dequeueOutputBuffer
返します。 出力バッファーが処理されたら、いずれかのメソッドを #releaseOutputBuffer releaseOutputBuffer
呼び出して、バッファーをコーデックに返します。
バッファーをコーデックにすぐに再送信または解放する必要はありませんが、入力バッファーまたは出力バッファーを保持するとコーデックがストールする可能性があり、この動作はデバイスに依存します。 <厳密>な具体的には、すべての/em> 未処理のバッファーが解放/再送信されるまで<<>、コーデックが出力バッファーの生成を保留する可能性があります。</strong> そのため、できるだけ使用可能なバッファーを保持するようにしてください。
API のバージョンに応じて、3 つの方法<でデータを処理できます。table<>thead<>tr<>th>Processing Mode</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<>td>Supported</tdtd>Deprecated</td></tr tr td><>><synchronous API using buffers</td><td class=NA>Not Available</td td>><Supported</td></tr tr><td><>Asynchronous API using buffers</td><td class=NA>Not Available</td td<>td>Supported</td<>/tr></tbody></table ><>
<h4>バッファー</h4 を使用した非同期処理>
ので android.os.Build.VERSION_CODES#LOLLIPOP
、推奨される方法は、呼び出す #configure configure
前にコールバックを設定してデータを非同期的に処理することです。 非同期モードでは、コーデックを実行中のサブ状態に移行し、入力バッファーの受信を開始するために後で呼び出す#start
#flush
必要があるため、状態遷移が若干変更されます。 同様に、コーデックへの start
最初の呼び出し時に、実行中のサブ状態に直接移動し、コールバックを介して使用可能な入力バッファーの渡しを開始します。
<center><img src="../../../images/media/mediacodec_async_states.svg" style="width: 516px;height: 353px" alt="MediaCodec state diagram for asynchronous operation"></center>
MediaCodec は通常、非同期モードで次のように使用されます。
MediaCodec codec = MediaCodec.createByCodecName(name);
MediaFormat mOutputFormat; // member variable
codec.setCallback(new MediaCodec.Callback() {
{@literal @Override}
void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
// fill inputBuffer with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
{@literal @Override}
void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
// bufferFormat is equivalent to mOutputFormat
// outputBuffer is ready to be processed or rendered.
…
codec.releaseOutputBuffer(outputBufferId, …);
}
{@literal @Override}
void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
mOutputFormat = format; // option B
}
{@literal @Override}
void onError(…) {
…
}
{@literal @Override}
void onCryptoError(…) {
…
}
});
codec.configure(format, …);
mOutputFormat = codec.getOutputFormat(); // option B
codec.start();
// wait for processing to complete
codec.stop();
codec.release();
<h4>バッファー</h4 を使用した同期処理>
そのためandroid.os.Build.VERSION_CODES#LOLLIPOP
、同期モードでコーデックを使用/#getOutputBuffer OutputBuffer(int)
#getInputBuffer getInput
する場合でも、入力バッファーと#getInputImage getInput
/#getOutputImage OutputImage(int)
出力バッファーを取得する必要があります。 これにより、動的コンテンツを処理する場合など、フレームワークによる特定の最適化が可能になります。 この最適化は、呼び出 #getInputBuffers getInput
/#getOutputBuffers OutputBuffers()
すと無効になります。
<p class=note><strong Note strong>Note:</strong> では、バッファーとバッファー配列を同時に使用するメソッドは混在しません。 具体的には、出力バッファー ID の値#INFO_OUTPUT_FORMAT_CHANGED
をデキューした直後#start
または後にのみ呼び出getInput
/OutputBuffers
します。
MediaCodec は通常、同期モードで次のように使用されます。
MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
MediaFormat outputFormat = codec.getOutputFormat(); // option B
codec.start();
for (;;) {
int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
if (inputBufferId >= 0) {
ByteBuffer inputBuffer = codec.getInputBuffer(…);
// fill inputBuffer with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
int outputBufferId = codec.dequeueOutputBuffer(…);
if (outputBufferId >= 0) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
// bufferFormat is identical to outputFormat
// outputBuffer is ready to be processed or rendered.
…
codec.releaseOutputBuffer(outputBufferId, …);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
outputFormat = codec.getOutputFormat(); // option B
}
}
codec.stop();
codec.release();
<h4>バッファー配列を使用した同期処理 (非推奨)</h4>
バージョン android.os.Build.VERSION_CODES#KITKAT_WATCH
以前では、入力バッファーと出力バッファーのセットは配列によって ByteBuffer[]
表されます。 呼び出し #start
が成功したら、次を使用して #getInputBuffers getInput
/#getOutputBuffers OutputBuffers()
バッファー配列を取得します。 次のサンプルに示すように、バッファー ID をこれらの配列のインデックスとして使用します (負でない場合)。 配列サイズは上限を提供しますが、配列のサイズとシステムで使用される入力バッファーと出力バッファーの数の間には固有の相関関係がないことに注意してください。
MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();
for (;;) {
int inputBufferId = codec.dequeueInputBuffer(…);
if (inputBufferId >= 0) {
// fill inputBuffers[inputBufferId] with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
int outputBufferId = codec.dequeueOutputBuffer(…);
if (outputBufferId >= 0) {
// outputBuffers[outputBufferId] is ready to be processed or rendered.
…
codec.releaseOutputBuffer(outputBufferId, …);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = codec.getOutputBuffers();
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
MediaFormat format = codec.getOutputFormat();
}
}
codec.stop();
codec.release();
<h4>ストリーム終了処理</h4>
入力データの末尾に達したら、呼び出しでフラグを指定 #BUFFER_FLAG_END_OF_STREAM
してコーデックに信号を送信する #queueInputBuffer queueInputBuffer
必要があります。 これは、最後の有効な入力バッファーで行うか、ストリームの終わりフラグが設定された空の入力バッファーを追加で送信することによって行うことができます。 空のバッファーを使用している場合、タイムスタンプは無視されます。
コーデックは、セット内で同じストリーム終了フラグを指定するか、または経由してCallback#onOutputBufferAvailable onOutputBufferAvailable
返すことで、最終的に出力ストリームの終わりを通知するまで、出力バッファーを#dequeueOutputBuffer dequeueOutputBuffer
BufferInfo
返し続けます。 これは、最後の有効な出力バッファーで、または最後の有効な出力バッファーの後の空のバッファーに設定できます。 このような空のバッファーのタイムスタンプは無視する必要があります。
コーデックがフラッシュされているか、停止して再起動されていない限り、入力ストリームの末尾に通知した後は、追加の入力バッファーを送信しないでください。
<h4>出力サーフェス<の使用/h4>
データ処理は、出力を使用する場合の ByteBuffer モードとほぼ同じですが、出力 Surface
バッファーにはアクセスできません。値として null
表されます。 たとえば#getOutputBuffer getOutputBuffer
/#getOutputImage Image(int)
、-s のみをnull
含む配列が返null
され#getOutputBuffers
、返されます。
出力サーフェスを使用する場合は、各出力バッファーをサーフェスにレンダリングするかどうかを選択できます。 次の 3 つの選択肢があります。ul>li strong バッファーをレンダリングしないでください:</strong> 呼び出し#releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, false)
。<>><<</li li>><<strong>既定の timestamp:</strong> Call #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, true)
を使用してバッファーをレンダリングします。</li li>><<strong>特定のタイムスタンプ:</strong> 呼び出し#releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp)
でバッファーをレンダリングします。</li></ul>
そのため android.os.Build.VERSION_CODES#M
、既定のタイムスタンプはバッファーの BufferInfo#presentationTimeUs プレゼンテーション タイムスタンプです (nanoseconds に変換されます)。 それ以前に定義されていませんでした。
また、 android.os.Build.VERSION_CODES#M
を使用して #setOutputSurface setOutputSurface
出力 Surface を動的に変更することもできます。
Surface に出力をレンダリングする場合、過剰なフレームをドロップするように Surface を構成できます (Surface ではタイムリーに使用されません)。 または、過剰なフレームをドロップしないように構成してもよい。 後者のモードでは、Surface が出力フレームを十分に高速に消費していない場合、最終的にデコーダーがブロックされます。 正確な動作が android.os.Build.VERSION_CODES#Q
定義されていない前は、ビュー サーフェス (SurfaceView または TextureView) が常に過剰なフレームを削除するという例外があります。 既定の動作では過剰なフレームがドロップされるため android.os.Build.VERSION_CODES#Q
です。 アプリケーションは、SDK android.os.Build.VERSION_CODES#Q
をターゲットにしてキー MediaFormat#KEY_ALLOW_FRAME_DROP
を構成形式に設定することで、ビュー以外のサーフェス (ImageReader や SurfaceTexture など) に対して 0
この動作をオプトアウトできます。
<サーフェス</h4>にレンダリングするときの h4 変換>
コーデックが Surface モードに構成されている場合、トリミング四角形、MediaFormat#KEY_ROTATION 回転、#setVideoScalingMode ビデオ スケーリング モードは 1 つの例外 <で自動的に適用されます。p class=note> リリース前 android.os.Build.VERSION_CODES#M
は、ソフトウェア デコーダーが Surface にレンダリングされるときに回転が適用されていない可能性があります。 残念ながら、ソフトウェア デコーダーを識別する標準的で簡単な方法はありません。または、試してみる以外にローテーションを適用する場合もあります。
いくつかの注意事項もあります。 <p クラス=注: Surface に出力を表示する場合、ピクセル縦横比は考慮されないことに注意> してください。 つまり、モードを使用 #VIDEO_SCALING_MODE_SCALE_TO_FIT
している場合は、最終的な表示縦横比が適切になるように出力 Surface を配置する必要があります。 逆に、正方形のピクセル (ピクセル縦横比または 1:1) のコンテンツにのみモードを使用 #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
できます。 <p class=note> リリース時点 android.os.Build.VERSION_CODES#N
では、 #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
90 度または 270 度回転したビデオではモードが正しく機能しない場合があることに注意してください。 <p class=note> ビデオスケーリングモードを設定するときは、出力バッファーが変更されるたびにリセットする必要があることに注意してください。 #INFO_OUTPUT_BUFFERS_CHANGED
イベントは非推奨であるため、出力形式が変更されるたびにこれを行うことができます。
<h4>入力サーフェス<の使用/h4>
入力 Surface を使用する場合、バッファーは入力サーフェイスからコーデックに自動的に渡されるため、アクセス可能な入力バッファーはありません。 呼び出し#dequeueInputBuffer dequeueInputBuffer
は 、をIllegalStateException
スローし、#getInputBuffers
strong>MUST NOT</strong> を<書き込む偽ByteBuffer[]
の配列を返します。
ストリームの終わりを通知する呼び出し #signalEndOfInputStream
。 入力サーフェスは、この呼び出しの直後にコーデックへのデータの送信を停止します。
<h3>シーク中・シーク中アダプティブ再生のサポート</h3>
ビデオ デコーダー (および圧縮されたビデオ データを使用する一般的なコーデック) は、シークとフォーマットの変更に関して動作が異なります。サポートされているかどうかに関係なく、アダプティブ再生用に構成されています。 デコーダーが CodecCapabilities#FEATURE_AdaptivePlayback アダプティブ再生 CodecCapabilities#isFeatureSupported CodecCapabilities.isFeatureSupported(String)
をサポートしているかどうかを確認できます。 ビデオ デコーダーのアダプティブ再生のサポートは、デコード Surface
するようにコーデックを構成した場合にのみアクティブになります。
<h4 id=KeyFrames>"KeyFrames">Stream Boundary and Key Frames</h4>
入力データは、適切なストリーム境界の後 #start
、または #flush
開始する必要があります。最初のフレームはキー フレームである必要があります。 <em>キー フレーム</em> は単独で完全にデコードできます (ほとんどのコーデックでは I フレームを意味します)。キー フレームがキー フレームの前のフレームを参照した後に表示されるフレームはありません。
次の表は、さまざまなビデオ形式に適したキー フレームをまとめたものです。 <table>thead><tr><th>Format</th><suitable>key frame</th></tr<>/thead<>tbody class=mid<>tr<>td>VP9/VP8</td td td><>a suitable intraframe where no subsequent frames refer to frames prior to this frame.<<br>(このようなキー フレームには特定の名前がありません。)</td></tr tr><<>td>H.265 HEVC</td td td>><IDR または CRA</td></tr tr<>td>><H.264 AVC</td td td>><IDR</td></tr tr<>td><>MPEG-4<br>H.263<br>MPEG-2</td td td>><は、後続のフレームがこのフレームより前のフレームを参照しない適切な I フレームです。<br>(このようなキー フレームには特定の名前がありません。)</td></tr></tbody></table>
<h4>アダプティブ再生をサポートしていないデコーダーの場合 (Surface にデコードしない場合を含む)</h4>
以前に送信されたデータ (シーク後) <に隣接していないデータのデコードを開始するには、デコーダーを強く>する必要があります</厳密> にフラッシュします。 すべての出力バッファーはフラッシュの時点ですぐに取り消されるため、最初にストリームの終わりを待ってから呼び出す flush
必要があります。 フラッシュ後の入力データは、適切なストリーム境界/キー フレームから開始することが重要です。 <p class=note strong Note strong Note:/strong the format of the data submitted after a flush must not change; does not support format discontinuities; for a full cycle is necessary. (p class=note><strong Note strong>Note:</strong> the format of the data submitted after a flush must not change; not support format discontinuities; for a full - #start
#stop
#configure configure(…)
- cycle is necessary. #flush
<p class=note><strong>また注意:</strong> コーデックをフラッシュする場合は、一般的 #start
に、最初の出力バッファーまたは出力形式の変更を受信する前に 、コーデック固有のデータをコーデックに再送信する必要があります。 詳細については、コーデック固有のデータに関するセクションを参照してください。
<h4>アダプティブ再生</h4 をサポートし、構成されているデコーダーの場合>
以前に送信されたデータに隣接していないデータ (シーク後) のデコードを開始するには、デコーダーをフラッシュする必要<はありません。>ただし、不連続の後の入力データは<>、適切なストリーム境界/キー フレームから開始する必要があります。
一部のビデオ形式 (H.264、H.265、VP8、VP9) では、画像のサイズまたは構成のミッドストリームを変更することもできます。 これを行うには、新しいコーデック固有の構成データ全体をキー フレームと共に 1 つのバッファー (開始コードを含む) にパッケージ化し、強力>な<標準</強力>な入力バッファーとして送信する必要があります。
画像サイズの#INFO_OUTPUT_FORMAT_CHANGED
変更が行われた直後とCallback#onOutputBufferAvailable onOutputFormatChanged
、新しいサイズのフレームが返される前に、戻り値または#dequeueOutputBuffer dequeueOutputBuffer
コールバックを受け取ります。 <p class=note><strong Note strong>Note:</strong> コーデック固有のデータの場合と同様に、画像のサイズを変更した直後に呼び出 #flush
すときは注意してください。 画像サイズの変更の確認を受け取っていない場合は、新しい画像サイズの要求を繰り返す必要があります。
<h3>エラー処理</h3>
ファクトリメソッド#createByCodecName createByCodecName
は失敗した場合にスローIOException
します#createDecoderByType createDecoder
/#createEncoderByType EncoderByType
。失敗した場合は、渡すためにキャッチまたは宣言する必要があります。 MediaCodec メソッドは、許可しないコーデック状態からメソッドが呼び出されたときにスロー IllegalStateException
します。これは通常、アプリケーション API の使用が正しくないためです。 セキュリティで保護されたバッファーを含むメソッドがスロー CryptoException
される可能性があります。このメソッドでは、さらにエラー情報を CryptoException#getErrorCode
取得できます。
内部コーデック エラーにより、アプリケーションが CodecException
API を正しく使用している場合でも、メディア コンテンツの破損、ハードウェアの障害、リソースの枯渇などが原因である可能性があります。 a をCodecException
受け取るときに推奨されるアクションは、呼び出しCodecException#isRecoverable
によって<CodecException#isTransient
決定できます。ul<>li><strong>recoverable errors:</strong> If isRecoverable()
returns true, then call #stop
, #configure configure(…)
and to #start
recover.</li li><<>厳密な>一時的なエラー:</strong> true を返す場合isTransient()
、リソースは一時的に使用できず、メソッドは後で再試行される可能性があります。</li li><<>強い>致命的なエラー:</strong> 両方とも isTransient()
isRecoverable()
false を返す場合CodecException
は、致命的であり、コーデックはリセット #reset または #release リリースする必要があります。</li></ul>
両方 isRecoverable()
とも、 isTransient()
同時に true を返しません。
<h2 id=History>"History">Valid API Calls and API History</h2>
このセクションでは、各状態での有効な API 呼び出しと、MediaCodec クラスの API 履歴を要約します。 API のバージョン番号については、以下を参照してください 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: 30px; height: 83px;} .deg45 > div { transform: skew(-45deg, 0deg) translate(1px, -67px); transform-origin: 左下 0; width: 30px; height: 20px; } .deg45 > 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); }</スタイル>
<table align="right" style="width: 0%"><thead<>tr><th>Symbol</th><Meaning<>/th></tr<>/thead><tbody class=sml<>tr><td>>#9679;</td><td>Supported</td></tr tr><><td>>#8277;</td td>><Semantics changed</td></tr tr><<>td>>#9675;</td td td Experimental support</td></tr tr><><td>[ ]</td td><td>Deprecated</td></tr tr><><td>>#9099;<>></td><td>サーフェス入力モード<に制限/td></tr tr><><td>>#9094;</td><td>サーフェス出力モード<に制限/td></tr tr><><td>>#9639;</td><td>ByteBuffer 入力モード<に制限/td></tr tr><><td>>#8617;</td><td>同期モード<に制限/td></tr tr><><td>>#8644;</td><td>非同期モード<に制限/td></tr tr><td>><( )</td><td td>呼び出すことができますが、呼び出すことはできませんが、t</td></tr></tbody></table>
<table style="width: 100%;"><thead class=api><tr><th class=deg45><div><div style="background:#4285f4"><div>Uninitialized</div></div></th>< th><class=deg45><div><div style="background:#f4b400"><div>Configured</div></div></div></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><></th th><class=deg45><div><div style="background:#f7cb4d"><div>End of Stream</div></div></th>< th><class=deg45><div><div style="background:#db4437"><div>Error</div></div></div></th class<>=deg45><div div><style="background:#666"div>><Released</div></div></div></th><><th>< colspan="8">SDK Version</th<>/tr tr><<>th colspan="7">State</th th><>Method</th<>>16</th 17</th>><18</th<>>>><19</th<>>20</th>><21/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 class=fn><#createByCodecName createByCodecName
/td<>td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr tr<>td><></td td><td></td><td></td><td></td><td>< td></<>td td<>td></td><td td class=fn><#createDecoderByType createDecoderByType
/td<>td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr tr<>td><></td td><td></td><td></td><td></td><td>< td></<>td td<>td></td><td td class=fn><#createEncoderByType createEncoderByType
/td<>td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</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></td><td></td><td/td><><td>>#9679;</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>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#8277;</td><td>>#9679;</td><td>>#9679;</td></tr td><>><-</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>>#9099;</td><td>>#9099;</td><td>>#9099;</td><td>>#9099;</td><td>>#9099;</td><td>>#9099;</td></tr tr><<>td>-</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><td>>#9679;</td><td>>#9639;</td><td>>#9639;</td><td>>#9639;</td><td>>#8277;>#9639;>#8617;</td><td>>#9639;>#8617;</td><td>>#9639;>#8617;</td></tr td<>>><-</td td<>td>-</td<>td td>16+</td><td>16+</td<>td>16+</td><td>-</td><td>-</td><td class=fn>#dequeueOutputBuffer dequeueOutputBuffer
</td><td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#8277;>#8617;</td><td>>#8617;</td><td>>#8617;</td></tr td<>>><-</td td<>td>-</td<>td td>16+</td><td>16+</td<>td>16+</td><td>-</td><td>-</td><td class=fn>#flush flush
</td><td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr tr>><<td>18+</td><td>18+</td td>><18+</td><td>18+<</td>><<td>td>18+</td><td>-</td><td class=fn#getCodecInfo getCodecInfo
<>/td td>><</td><td td></td td>d<>td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr td>><><-</td 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/td td><><td></td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr tr><<>td>-</td td>><-</td><td td>16+</td><td>(16+)</td><td>(16+)</td><td>-</td td><>-</td><td class=fn><#getInputBuffers getInputBuffers
/td<>td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>[>#8277;>#8617;]</td><td>[>#8617;]</td><td>[>#8617;]</td></tr tr><<>td>-</td td><>21+</td<>td>(21+)</td<>td>(21+)</td<>td>(21+)</td<>td>-<</td><<>td td> class=fn<>#getInputFormat getInputFormat
/td td><></td><td></td><td></td<>td></td> td<td></td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr tr>><<td>-</td td<>td>-</td<>td>(21+)</td><td>21+</td><td>(21+)</td><td>-</td<>td>-</td><td class=fn><#getInputImage getInputImage
/td><td td></td<>><>< td/td td/td><><td></td><td></td td>><>#9675;</td><td>>#9679;</td><td>>#9679;</td></tr tr>><<td>18+</td td>><18+</td<>td>18+</td<>td>18+</td><><td>18+</td td td>18+</td td>><-</td td><class=fn#getName getName
></td td><<>/td<>td td><>< td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr tr>><<td>-</td td><>-</td td><>(21+)</td><td>21+</td><td>21+</td><td>-</td td>><-</td td<>class=fn>#getOutputBuffer getOutputBuffer
</td<>td td></td><td><>< td></td><td></td><td></td td>><>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr td<>>><-</td td<>td>-</td<>td td>16+</td><td>16+</td<>td>16+</td><td>-</td><td>-</td><td class=fn>#getOutputBuffers getOutputBuffers
</td><td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>[>#8277;>#8617;]</td><td>[>#8617;]</td><td>[>#8617;]</td></tr tr><><td>-</td td><>21+</td><td>16+</td td><td>16+</td><td>16+</td><td>-</td td>><-</td><td class=fn><#getOutputFormat()
/td<>td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr tr>><<td>-</td td><>-</td td><>(21+)</td><td>21+</td><td>21+</td><td>-</td td>><-</td td<>class=fn>#getOutputFormat(int)
</td<>td td></td><td><>< td></td><td></td><td></td td>><>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr tr>><<td>-</td td><>-</td td><>(21+)</td><td>21+</td><td>21+</td><td>-</td td>><-</td td<>class=fn>#getOutputImage getOutputImage
</td<>td td></td><td><>< td></td><td></td><td></td td>><>#9675;</td><td>>#9679;</td><td>>#9679;</td></tr tr>><<td>-</td td>><-</td><td>-</td><td td>16+</td><td>(16+)</td><td>-</td td><>-</td><td class=fn>#queueInputBuffer queueInputBuffer
</td><td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#8277;</td><td>>#9679;</td><td>>#9679;</td></tr tr>><<td>-</td 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><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#8277;</td><td>>#9679;</td><td>>#9679;</td></tr tr><<>td>16+</td<>td>16+</td><td>16+</td<>td>16+</td>><<td>16+<</td><td td>>16+</td><td class=fn><#release release
/td<>td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr td<>>><-</td td<>td>-</td<>td>-</td<>td td>16+</td<>td td>16+</td<>td>-<</td><><td> class=fn><#releaseOutputBuffer(int, boolean)
/td<>td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#8277;</td><td>>#9679;</td><td>>#8277;</td></tr tr>><<td>-</td td><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>><>#9094;</td><td>>#9094;</td><td>>#9094;</td></tr tr>><<td>21+</td<>td>21+</td><td>21+</td><td>21+</td><><td>21+</td td td>21+</td<>td>-</td td><class=fn#reset reset
></td td><<>/td><td></td td><td></td><td></td><td></td td>><>#9679;</td><td>>#9679;</td><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>><>#9679;</td><td>>#9679;</td><td/td>#setCallback(Callback, Handler) ⁕
<></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><>>><#9099;</td></tr tr><<>td>23+</td td>><23+</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><td td></td td>><>#9675; >#9094;</td></tr tr>><<td>-</td td>><23+</td<>td>23+</td td><td>23+<</td><td>-/td><td>>-<</td><><td class=fn><#setOutputSurface setOutputSurface
/td td<>td></td><td>< td><td></td><td></td td><<>/td><td></td td><<>/td><td>>#9094;</td></tr tr>><<td>19+</td><td>19+</td td>><19+</td><td>19+</td<<>>td>>(19+<)</td td>><-</td><td class=fn><#setParameters setParameters
/td td<>td></td><td>< td><td></td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td></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>>#9094;</td><td>>#9094;</td><td>>#9094;</td><td>>#9094;</td><td>>#9094;</td><td>>#9094;</td><td>>#9094;</td><td>>#9094;</td></tr tr>><<td>(29+)</td><td>29+</td td><>29+</td><td>29+</td<>td>(29+)</td<>td>(29+)</td<>td>-</td<>td td class=fn<>#setAudioPresentation setAudioPresentation
/td td>><</td<>td/td>< td><td></td><td></td><td></td><td></td><td></td><td></tr<>td>>><<-</td<>td>-</td><td td>18+</td><td td>18+</td><td>-</td><td>-</td><td>-</td td><class=fn>#signalEndOfInputStream signalEndOfInputStream
</td td><></td td><></td><td>>#9099;</td><td>>#9099;</td><td>>#9099;</td><td>>#9099;</td><td>>#9099;</td><td>>#9099;</td></tr tr><<>td>-</td td>><16+</td<>td>21+(>#8644;)</td td>-</td td><>-</td td><>-</td><td td>-</td<>td class=fn<>#start start
/td td><td>>#9679;<></td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#8277;</td><td>>#9679;</td><td>>#9679;</td></tr td<>>><-</td td<>td>-</td<>td td>16+</td><td>16+</td<>td>16+</td><td>-</td><td>-</td><td class=fn>#stop stop
</td><td td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td><td>>#9679;</td></tr></tbody></table>
の Java ドキュメントandroid.media.MediaCodec
このページの一部は、Android オープンソース プロジェクトによって作成および共有され、クリエイティブ コモンズ 2.5 属性ライセンスに記載されている条件に従って使用される作業に基づく変更です。
フィールド
BufferFlagCodecConfig |
古い.
これは、そのようにマークされたバッファーに、メディア データの代わりにコーデック初期化/コーデック固有のデータが含まれていることを示しました。 |
BufferFlagDecodeOnly |
古い.
これは、バッファーがデコードされ、デコーダーの内部状態が更新されますが、出力バッファーは生成されないことを示します。 |
BufferFlagEndOfStream |
古い.
これはストリームの終わりを示します, i. |
BufferFlagKeyFrame |
古い.
これは、そのようにマークされた (エンコードされた) バッファーにキー フレームのデータが含まれていることを示します。 |
BufferFlagPartialFrame |
古い.
これは、バッファーにフレームの一部のみが含まれていることを示し、デコーダーは、フレームをデコードする前に、このフラグのないバッファーが表示されるまでデータをバッチ処理する必要があることを示します。 |
BufferFlagSyncFrame |
古い.
これは、そのようにマークされた (エンコードされた) バッファーにキー フレームのデータが含まれていることを示します。 |
ConfigureFlagEncode |
古い.
このコーデックをエンコーダーとして使用する場合は、このフラグを渡します。 |
ConfigureFlagUseBlockModel |
古い.
このコーデックを使用する |
ConfigureFlagUseCryptoAsync |
古い.
このフラグは、セキュリティで保護されたデコーダーでのみ使用する必要があります。 |
CryptoModeAesCbc |
古い.
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 |
CryptoModeAesCtr | |
CryptoModeUnencrypted | |
InfoOutputBuffersChanged |
古い.
出力バッファーが変更されました。クライアントは、この時点から返される |
InfoOutputFormatChanged |
古い.
出力形式が変更され、後続のデータは新しい形式に従います。 |
InfoTryAgainLater |
古い.
非負のタイムアウトが呼び出しで指定されている場合は、呼び出 |
ParameterKeyHdr10PlusInfo |
次のキューに入った入力フレームに HDR10+ メタデータを設定します。 |
ParameterKeyLowLatency |
待機時間の短いデコード モードを有効または無効にします。 |
ParameterKeyOffsetTime |
タイムスタンプの上に追加するオフセット (マイクロ秒単位) を指定します。 |
ParameterKeyRequestSyncFrame |
エンコーダーが "間もなく" 同期フレームを生成することを要求します。 |
ParameterKeySuspend |
入力データのエンコードを一時的に中断または再開します。 |
ParameterKeySuspendTime |
存在する場合 |
ParameterKeyTunnelPeek |
コーデックがトンネル モード |
ParameterKeyVideoBitrate |
ビデオ エンコーダーのターゲット ビットレートをオンザフライで変更します。 |
VideoScalingModeScaleToFit |
古い.
コンテンツはサーフェスの寸法に合わせて拡大縮小されます。 |
VideoScalingModeScaleToFitWithCropping |
古い.
コンテンツは拡大縮小され、その縦横比を維持し、表面積全体が使用され、コンテンツはトリミングされ得る。 |
プロパティ
CanonicalName |
基になるコーデック名を取得します。 |
Class |
この |
CodecInfo |
コーデック情報を取得します。 |
Handle |
基になる Android インスタンスへのハンドル。 (継承元 Object) |
InputFormat |
コーデックで受け入れられた入力形式を取得するために、正常に戻った後 |
JniIdentityHashCode |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
JniPeerMembers |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 |
Metrics |
現在のコーデック インスタンスに関するメトリック データを返します。 |
Name |
コーデック名を取得します。 |
OutputFormat |
dequeueOutputBuffer が返すことによって形式の変更を通知した後にこれを呼び出します |
PeerReference |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
SupportedVendorParameters |
ベンダー パラメーター名の一覧を返します。 |
ThresholdClass |
この API は Android 用 Mono インフラストラクチャをサポートしており、コードから直接使用するためのものではありません。 (継承元 Object) |
ThresholdType |
この API は Android 用 Mono インフラストラクチャをサポートしており、コードから直接使用するためのものではありません。 (継承元 Object) |
メソッド
Clone() |
このオブジェクトのコピーを作成して返します。 (継承元 Object) |
Configure(MediaFormat, Surface, MediaCodecConfigFlags, MediaDescrambler) |
descrambler で使用するコンポーネントを構成します。 |
Configure(MediaFormat, Surface, MediaCrypto, MediaCodecConfigFlags) |
コンポーネントを構成します。 |
CreateByCodecName(String) |
インスタンス化するコンポーネントの正確な名前がわかっている場合は、このメソッドを使用してインスタンス化します。 |
CreateDecoderByType(String) |
特定の MIME の種類の入力データをサポートする優先デコーダーをインスタンス化します。 |
CreateEncoderByType(String) |
指定された MIME の種類の出力データをサポートする優先エンコーダーをインスタンス化します。 |
CreateInputSurface() |
入力バッファーの代わりに、エンコーダーへの入力として使用するように Surface に要求します。 |
CreatePersistentInputSurface() |
ビデオ エンコーダーなど、通常は入力サーフェスを持つコーデックで使用できる永続的な入力サーフェスを作成します。 |
DequeueInputBuffer(Int64) |
有効なデータが格納される入力バッファーのインデックスを返します。現在使用できるバッファーがない場合は -1 を返します。 |
DequeueOutputBuffer(MediaCodec+BufferInfo, Int64) |
出力バッファーをデキューし、最大で "timeoutUs" マイクロ秒をブロックします。 |
Dispose() |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
Dispose(Boolean) |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
Equals(Object) |
他のオブジェクトがこのオブジェクトと "等しい" かどうかを示します。 (継承元 Object) |
Flush() |
コンポーネントの入力ポートと出力ポートの両方をフラッシュします。 |
GetHashCode() |
オブジェクトのハッシュ コード値を返します。 (継承元 Object) |
GetInputBuffer(Int32) |
入力データを |
GetInputBuffers() |
古い.
入力バッファーのセットを取得します。 |
GetInputImage(Int32) |
未加工の入力ビデオ フレームを格納するデキューされた入力バッファー インデックスの書き込み可能な Image オブジェクトを返します。 |
GetOutputBuffer(Int32) |
デキューされた出力バッファー インデックスの読み取り専用 ByteBuffer を返します。 |
GetOutputBuffers() |
古い.
出力バッファーのセットを取得します。 |
GetOutputFormat(Int32) |
特定の出力バッファーの出力形式を返します。 |
GetOutputFrame(Int32) |
オブジェクトを |
GetOutputImage(Int32) |
未加工のビデオ フレームを含むデキューされた出力バッファー インデックスの読み取り専用 Image オブジェクトを返します。 |
GetParameterDescriptor(String) |
名前を使用してパラメーターを記述します。 |
GetQueueRequest(Int32) |
入力スロット インデックスの |
JavaFinalize() |
オブジェクトへの参照がなくなったとガベージ コレクションによって判断されたときに、オブジェクトのガベージ コレクターによって呼び出されます。 (継承元 Object) |
MapHardwareBuffer(HardwareBuffer) |
バッファーの |
Notify() |
このオブジェクトのモニターで待機している 1 つのスレッドを起動します。 (継承元 Object) |
NotifyAll() |
このオブジェクトのモニターで待機しているすべてのスレッドを起動します。 (継承元 Object) |
QueueInputBuffer(Int32, Int32, Int32, Int64, MediaCodecBufferFlags) |
指定したインデックス位置にある入力バッファーの範囲を入力した後、それをコンポーネントに送信します。 |
QueueSecureInputBuffer(Int32, Int32, MediaCodec+CryptoInfo, Int64, MediaCodecBufferFlags) |
暗号化される可能性があるバッファーを送信する |
Release() |
コーデック インスタンスによって使用されるリソースを解放します。 |
ReleaseOutputBuffer(Int32, Boolean) |
バッファーが完了した場合は、この呼び出しを使用して、バッファーをコーデックに返すか、出力サーフェイスにレンダリングします。 |
ReleaseOutputBuffer(Int32, Int64) |
バッファーが完了したら、この呼び出しを使用してサーフェスタイムスタンプを更新し、コーデックに返して出力サーフェイスにレンダリングします。 |
Reset() |
コーデックを初期 (初期化されていない) 状態に戻します。 |
SetAudioPresentation(AudioPresentation) |
オーディオ プレゼンテーションを設定します。 |
SetCallback(MediaCodec+Callback) |
既定のルーパーでアクション可能な MediaCodec イベントの非同期コールバックを設定します。 |
SetCallback(MediaCodec+Callback, Handler) |
既定のルーパーでアクション可能な MediaCodec イベントの非同期コールバックを設定します。 |
SetHandle(IntPtr, JniHandleOwnership) |
Handle プロパティを設定します。 (継承元 Object) |
SetInputSurface(Surface) |
コーデックを構成します (例: |
SetOnFirstTunnelFrameReadyListener(Handler, MediaCodec+IOnFirstTunnelFrameReadyListener) |
最初の出力フレームがデコードされ、トンネル モード用に構成されたコーデックでレンダリングする準備ができたときに呼び出されるコールバックを |
SetOnFrameRenderedListener(MediaCodec+IOnFrameRenderedListener, Handler) |
出力フレームが出力サーフェイスにレンダリングされるときに呼び出されるコールバックを登録します。 |
SetOutputSurface(Surface) |
コーデックの出力サーフェスを動的に設定します。 |
SetParameters(Bundle) |
追加のパラメーター変更をコンポーネント インスタンスに伝えます。 |
SetVideoScalingMode(VideoScalingMode) |
前の呼び出しでサーフェスが指定されている場合は、使用する |
SignalEndOfInputStream() |
入力時にストリームの終わりを通知します。 |
Start() |
コンポーネントの構成が正常に完了したら、次を呼び出します |
Stop() |
デコード/エンコード セッションを終了します。コーデック インスタンスはアクティブなままであり、再び有効になる準備ができていることに |
SubscribeToVendorParameters(IList<String>) |
これらのパラメーターが存在 |
ToArray<T>() |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
ToString() |
オブジェクトの文字列表現を返します。 (継承元 Object) |
UnregisterFromRuntime() |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
UnsubscribeFromVendorParameters(IList<String>) |
これらのパラメーターが存在 |
Wait() |
現在のスレッドが目覚めるまで待機させます。通常<は、通知<>/em> または <em>割り込み/em> を受け<取ります。 (継承元 Object) |
Wait(Int64) |
現在のスレッドが目覚めるまで待機します。通常<><は、通知/em> または <em>中断</em> によって、または一定のリアルタイムが経過するまで待機します。 (継承元 Object) |
Wait(Int64, Int32) |
現在のスレッドが目覚めるまで待機します。通常<><は、通知/em> または <em>中断</em> によって、または一定のリアルタイムが経過するまで待機します。 (継承元 Object) |
明示的なインターフェイスの実装
IJavaPeerable.Disposed() |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
IJavaPeerable.DisposeUnlessReferenced() |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
IJavaPeerable.Finalized() |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
IJavaPeerable.JniManagedPeerState |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
IJavaPeerable.SetJniIdentityHashCode(Int32) |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
IJavaPeerable.SetPeerReference(JniObjectReference) |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 (継承元 Object) |
拡張メソッド
JavaCast<TResult>(IJavaObject) |
Android ランタイムチェック型変換を実行します。 |
JavaCast<TResult>(IJavaObject) |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 |
GetJniTypeName(IJavaPeerable) |
MediaCodec クラスを使用して、低レベルのメディア コーデック (i) にアクセスできます。 |