2016-10-05 28 views
0

Bitmapsを作成していて、それらを(ハードウェアで)エンコードし、.mp4ファイルに多重化します。AndroidのMediaCodecクラスを使用してエンコードされた緑色のビデオ

私はMediaCodecクラスをエンコードし、MediaMuxerをmuxに使用しています。

エンコーダ(MediaCodec)の入力バッファが小さすぎるという問題があります。私が選択したカラーフォーマット(MediaFormatオブジェクトがエンコーダに渡されても)は、12ビットカラーコーディングを使用したいと思うような外観のresWidth * resHeight * 1.5に等しいバッファを常に返します。

たとえば、フレームを960x540ピクセルに設定すると、エンコーダは777600バイトの長さのバッファを渡します。他の解像度を選択すると、それに応じてバッファが常にスケールされます。

ビットマップはプログラムの実行中に作成され、Androidビューをそれらにレンダリングします(Canvasを使用)。ビットマップクラスの仕様では色の書式設定に多くの選択肢がありません。私が知る限り、12ビットコーディングを選択するオプションはありません。

しかし私は、8ビットを選択することができ、これは私が私の8ビットピクセルあたりのビットマップのコンテンツで入力バッファを埋めるためにしようとすると、私が得るものです:あなたはすべてが緑がかっている見ることができるようにhttps://www.youtube.com/watch?v=5c-fjYp9KMQ

とそれはあってはならない。 https://github.com/eeprojects/MediaCodecExample

このアプリケーションを実行して数秒待つだけで、ビデオを生成することができます。ランタイム中のすべてのアプリケーションがLogCatに記録されています。

I手動( MediaFormat.KEY_MAX_INPUT_SIZEフィールドを設定することにより可能である)バッファサイズを設定した後、16ビットで符号化されたビットマップを resWidth * resHeight * 2に設定し、試み

が、このようにして、出力バッファをデキューしようとしたとき、コーデックは、致命的な内部エラーとアプリケーションを返しますクラッシュ:

E/ACodec: [OMX.Exynos.AVC.Encoder] ERROR(0x80001001) 
E/ACodec: signalError(omxError 0x80001001, internalError -2147483648) 
E/MediaCodec: Codec reported err 0x80001001, actionCode 0, while in state 6 

答えて

1

エンコーダが望む形式を盲目的に推測する必要はありません。実際にはアプリケーションコードで自分で選択します。あなたのMainActivity.javaから:

MediaCodecInfo codecInfo = selectCodec(OUTPUT_VIDEO_MIME_TYPE); 
    int colorFormat = selectColorFormat(codecInfo, OUTPUT_VIDEO_MIME_TYPE); 

    MediaFormat outputVideoFormat = 
      MediaFormat.createVideoFormat(OUTPUT_VIDEO_MIME_TYPE, TEX_WIDTH, TEX_HEIGHT); 
    outputVideoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat); 

selectColorFormat方法は、おそらくいくつかのYUV 420カラーフォーマットを返しました。すべての一般的なYUV 420カラーフォーマット(例:MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar)は12ビットです。より正確に言えば、フル解像度で8ビットの輝度平面を持ち、その後に8ビットコンポーネントを持つ2つのクロミナンスプレーンがありますが、水平方向と垂直方向の2倍にサブサンプリングされています。

Bitmap.Config.ALPHA_8を使用してこれを描画すると、輝度プレーンのみが設定され、クロミナンスプレーンは初期化されずに残っています。おそらくゼロに設定され、緑色になります。入力バッファの残りのバイトを0ではなく128に設定すると、グレースケール画像が得られます。

BitmapはYUVピクセル形式をサポートしていないため、ピクセルデータを手動で変換するか、Android 4.3以降の新しいSurface入力方法を使用する必要があります。次に、Surfaceに描画するものを使って入力を生成することができます。少なくともOpenGL ESを使うことはできますが、確かにCanvasについてはわかりません。

+0

ありがとうございます。デバイスのコーデックが6種類のカラーフォーマットコードをサポートしているように見えますが、いずれも12ビットです。 MediaCodecを使用して32ビットカラーコード化ビットマップをエンコードすることは可能ですか?また、仕様によるとSurfaceを使用することはできません: "OpenGL ESのようなハードウェアアクセラレーションAPIでSurfaceをレンダリングする必要があります。lockCanvas(android.graphics.Rect)が失敗したり、予期しない結果が生じる可能性があります。 - https://developer.android.com/reference/android/media/MediaCodec.html#createInputSurface() –

+1

いいえ、32ビットカラーは使用できません。いくつかの個々のデバイスが潜在的にそれをサポートする可能性がありますが、それほど一般的ではありません。 – mstorsjo

関連する問題