問題タブ [android-mediacodec]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
android - lib_k3_generic_audio_extractor.so、lib_k3_mov_extractor.so などとは何ですか?
ここから取得したコードを使用して、Android MediaCodec を試しています: https://code.google.com/p/android-source-browsing.platform--cts
コード「android-source-browsing.platform--cts/tests/tests/media/src/android/media/cts/DecoderTest.java」を実行しようとすると、次のエラーが発生しました。
lib_k3_avi_extractor.so、lib_k3_mov_extractor.so などのライブラリが私のデバイスにないようです。ここに私の質問があります: これらのライブラリは何ですか? それらは何のため?それらがデバイスにないのはなぜですか? 私はこれらのライブラリをグーグルで検索しましたが、奇妙なことに、検索ではまったく何も見つかりませんでした。
エラーを生成した Java コードを以下に示します。ログ情報を追加するための小さな変更が加えられています。
android - MediaCodec ビデオデコーダーで使用するために Android Surface から直接 EGL イメージにアクセスする方法は?
私は現在、ビデオフレームをキャッシュする必要があるAndroidアプリを作成しているため、ほとんどまたはまったく遅延なく簡単に行き来できます。
MediaCodec
現在、オブジェクトの Configure 呼び出しに Surface を提供releaseOutputBuffer
し、render フラグを に設定して呼び出して、Android にビデオ フレームをデコードさせていますtrue
。
デコードされたサーフェス データにアクセスするために見つけた唯一の方法 (形式がデバイスに依存しているように見える、返されたバイトバッファーをデコードする以外に) は、サーフェスにリンクされた を呼び出し、これをターゲットにアタッチし、updateTeximage
作成したターゲット テクスチャにレンダリングすることです。それをキャッシュするために自分自身。SurfaceTexture
GL_TEXTURE_EXTERNAL_OES
GL_TEXTURE2D
このキャッシュ プロセスを最適化し、別のスレッドでフレームをデコードできるようにしたいと考えています。現在の方法を使用すると、これは、ビデオ デコーダー用に別の EGL コンテキストを作成し、コンテキストを共有する必要があることを意味します...
私の質問は:を呼び出さずに、Surface に関連付けられた EGL イメージまたはネイティブ バッファ データにアクセスすることは可能 updateTexImage
ですか?
そうすれば、egl イメージをキャッシュすることができます (これは、 に従って EGL コンテキストを必要としませんEGL_ANDROID_image_native_buffer
)。これは、現在キャッシュしている未加工の RGB テクスチャよりもはるかにストレージ効率の高い YUV 形式でもキャッシュされます。
android - Android で MediaCodec を使用して、フレームが画面にレンダリングされているにもかかわらず、outputBuffers が null ポインターを返す
このリンクで指定されたコードを使用して、MediaCodec
クラスを使用して .mp4 ビデオをデコードしています。
画面にレンダリングされた出力を取得できますが、にアクセスしようとするとoutputBuffers[outIndex]
、null ポインター エラーが発生します。フレーム バッファにアクセスして処理を行う方法がわかりません。
android - 生の AAC データをデコードするように MediaCodec を構成するために MediaFormat を初期化する方法は?
StreamPlayer に不可解な問題があり、何か助けが必要です。
私が達成する必要がある主な目標は、MPEG-2 トランスポート ストリームを可能な限り最小のレイテンシで再生できる StreamPlayer です。このために、私はこのアプローチに従っています:
ストリームは、Java ベースの TS パーサーによって解析されます。MediaExtractor に似た、正常に動作する TSExtractor を実装しました。MediaExtractor を使用して可能なのと同じ方法で、選択したトラックのすべてのメディア サンプルを受信できます。
AAC データをデコードするには、MediaCodec のインスタンスを作成して構成します。MediaExtractor クラスを使用して、これは通常
TSExtractor.getTrackFormat(int track) メソッドで MediaFormat を初期化する必要があるため、使用します
すべての AAC サンプルには ADTS が含まれているため、
この投稿を読んだ後、「csd-0」キーを使用して ESDS フレームを最終的に追加します
ここで、値 0x11 と 0x90 は ADTS から抽出されます。
AAC サンプルをデコードしたいときは、デコーダーがポストします。
ログに。
TSExtractor がサンプルを正しく抽出することを確認するために、VLC を使用して同じストリームを記録し、トランスコーディングせずに mp4 ファイルに再多重化し、生のストリームを変更しませんでした。これで、記録した mp4 ファイルで MediaExtractor を初期化し、TSExtractor と MediaExtractor によって作成されたサンプルを比較できます。トレイルアンドエラーを使用すると、非常に奇妙な動作が見つかりました。
MediaExtractor によって作成された mediaFormat を使用して MediaCodec を構成すると、MediaCodec は TSExtractor によって返された AAC サンプルを問題なくデコードします。私の TSExtractor によって作成された HashMap を基本的にラップする MediaFormat と MediaExtractor によって作成されたものを比較すると、次のような違いがあります。
MediaExtractor によって作成されました:
mediaFormat: {max-input-size=1212, durationUs=77428875, is-adts=1, channel-count=2, mime=audio/mp4a-latm, csd-0=java.nio.ByteArrayBuffer[position=0,limit =2,容量=2]、サンプルレート=48000}
TSExtractor によって作成:
mediaFormat: {is-adts=1, channel-count=2, mime=audio/mp4a-latm, csd-0=java.nio.ByteArrayBuffer[position=2,limit=2,capacity=2], sample-rate= 48000}
TSExtractor によって作成された MediaFormat を MediaExtractor によって作成されたものと同様に採用しても、デコーダーは、作成された自己を使用して同じエラーを出し、他のものを使用して問題なくデコードします。
どんな助けでも本当に役に立ちます。
android - MediaCodec を使用して一連の画像をビデオとして保存する
MediaCodec
ファイルにバイト配列として保存された一連の画像をビデオファイルに保存するために使用しようとしています。SurfaceView
これらの画像を(連続して再生して)テストしましたが、問題なく表示されます。を使用して多くの例を見てきましたMediaCodec
が、これが私が理解していることです(間違っている場合は修正してください):
MediaCodec オブジェクトから InputBuffers を取得 -> フレームの画像データで埋める -> 入力バッファをキューに入れる -> コード化された出力バッファを取得 -> ファイルに書き込む -> プレゼンテーション時間を増やして繰り返す
ただし、これを何度もテストした結果、次の 2 つのケースのいずれかになります。
- 私が真似ようとしたすべてのサンプル プロジェクト
queueInputBuffer
では、2 回目の呼び出し時にメディア サーバーが停止しました。 - 最後に呼び出し
codec.flush()
てみました (出力バッファーをファイルに保存した後、私が見た例はどれもこれを行いませんでした)、メディアサーバーは停止しませんでしたが、どのメディアプレーヤーでも出力ビデオファイルを開くことができませんでした。何かが間違っている。
これが私のコードです:
私の質問は、MediaCodec を使用して画像のストリームから作業ビデオを取得するにはどうすればよいかということです。私は何を間違っていますか?
もう 1 つの質問 (欲張りではない場合)、このビデオにオーディオ トラックを追加したいのですが、MediaCodec でも実行できますか、それとも FFmpeg を使用する必要がありますか?
注:Android 4.3については知ってMediaMux
いますが、アプリはAndroid 4.1以降で動作する必要があるため、これはオプションではありません。
更新 fadden answer のおかげで、メディアサーバーが停止することなく EOS に到達できました (上記のコードは変更後です)。ただし、取得しているファイルは意味不明です。これは、私が取得したビデオのスナップショットです (.h264 ファイルとしてのみ機能します)。
入力画像形式は YUV 画像 (カメラ プレビューの NV21) です。再生可能なフォーマットにすることはできません。すべての COLOR_FormatYUV420 形式と同じ意味不明な出力を試しました。そして、オーディオを追加する方法を (MediaCodec を使用して) まだ見つけることができません。
android - MediaCodec は、デコードのために着信パケットを切り捨てますか?
MediaCodec
ffmpeg でエンコードされた h264 パケットをデコードするために使用しています。ffmpeg でデコードすると、フレームは正常に表示されます。ただし、MediaCodec
ハードウェア デコーダーでデコードすると、フレームの中央に黒いバーが表示されることがあります。これは、エンコーディング ビットレートが十分に高く設定されている場合 (たとえば 4000000 以上) にのみ発生し、特定AVPacket
のサイズが 95000 程度を超えるようになります。MediaCodec
(または基礎となるデコーダー)がフレームを切り捨てているようです。残念ながら、ビットレートを下げられないほどの品質が必要です。フレームが他の場所で切り捨てられていないことを確認し、MediaFormat.KEY_MAX_INPUT_SIZE
より高い値に設定しようとしました.
誰かがこの問題に遭遇したか、それを回避する方法を知っていますか?
OpenGL でレンダリングし、Galaxy S4 でデコードしたランダム ピクセルの画像を添付しました。
android-4.3-jelly-bean - 入力が Surface のメディア コーデック API が H264 エンコーダーで動作しない (bigflake サンプル コード)
bigflakeの次のリンクで説明されている4.3でH264エンコーダーを使用してMedia Codec APIのサンプルコードを実行しようとしています
http://bigflake.com/mediacodec/CameraToMpegTest.java.txt
次の問題に直面しました。-> H264 エンコーダ コードでは、getpatameter の実装に問題があるため、カラー フォーマット、高さ、および幅が更新されません。そこで、このパッチを適用しました ( https://code.google.com/p/android/issues/detail?id=58834 )。-> パッチを適用した後、エンコーダーもエンコードしません -> D/CameraToMpegTest( 3421): エンコーダーの出力形式が変更されました: {csd-1=java.nio.ByteArrayBuffer[position=0,limit=8 、容量=8]、高さ=144、mime=ビデオ/avc、csd-0=java.nio.ByteArrayBuffer[位置=0、制限=12、容量=12]、何=1869968451、幅=176}
なぜこの値が変更されるのか、わかりません...その後、エンコーダーが queueOutputBuffer のステータスを INFO_TRY_AGAIN_LATER として与えるのを常に確認します。したがって、ファイルを作成しますが、何もエンコードせず、次のように停止します
I/MPEG4Writer( 3421): 合計/長さ 0 (0/0) のバッファーを受信し、0 フレームをエンコードしました。- ビデオ
D/MPEG4Writer( 3421): ビデオ トラックを停止しています
D/MPEG4Writer( 3421): ビデオトラックソースを停止しています
D/MPEG4Writer( 3421): ビデオ トラックが停止しました
D/MPEG4Writer( 3421): ライター スレッドを停止しています
D/MPEG4Writer( 3421): 最後のバッチで 0 チャンクが書き込まれました
D/MPEG4Writer( 3421): ライター スレッドが停止しました
したがって、私の理解では動作するはずですが、エンコーダがまだ正しく構成されていないようです...
これについてガイドしてください...ありがとう
ネハル
android - Android の MediaCodec と MediaMuxer を使用した AAC オーディオの多重化
Android フレームワークの例を変更して、MediaCodec によって生成された基本的な AAC ストリームをスタンドアロンの .mp4 ファイルにパッケージ化しています。MediaMuxer
インスタンスによって生成された 1 つの AAC トラックを含む単一のインスタンスを使用していMediaCodec
ます。
ただし、次の呼び出しで常にエラーメッセージが表示されますmMediaMuxer.writeSampleData(trackIndex, encodedData, bufferInfo)
。
E/MPEG4Writer﹕timestampUs 0 < lastTimestampUs XXXXX for Audio track
生の入力データをキューに入れるときmCodec.queueInputBuffer(...)
、フレームワークの例に従ってタイムスタンプ値として 0 を指定します (単調に増加するタイムスタンプ値を使用しても同じ結果が得られました。これで生のカメラ フレームを h264/mp4 ファイルにエンコードすることに成功しました)同じ方法)。
最も関連性の高いスニペット:
更新:内にあると思われる根本的な症状を見つけましたMediaCodec
。:
に送信presentationTimeUs=1000
しますが、電話してからqueueInputBuffer(...)
受信します。fadden は、この動作に関連する有益なコメントを残しました。info.presentationTimeUs= 33219
MediaCodec.dequeueOutputBuffer(info, timeoutUs)