1

MIC からのオーディオ ストリームを 3gpp (AMR-NB) としてエンコードしようとしています。問題は、出力バッファーに奇妙なデータが含まれていることです。コードと出力は次のとおりです。

メディア エンコーダーの作成:

MediaFormat format = MediaFormat.createAudioFormat("audio/3gpp", 8*1024, 1);
format.setInteger(MediaFormat.KEY_BIT_RATE, 8*1024);
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, minBufSize);
MediaCodec encoder = MediaCodec.createEncoderByType("audio/3gpp");
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start();

MIC からの PCM データは正しいようです (ファイルに保存され、Audacity でリッスンされます)

エンコードされたバイトの読み取り (バッファ、スレッドで実行):

ByteBuffer[] outputBuffers = encoder.getOutputBuffers();
int outputBufferIndex = 0;
while( outputBufferIndex >= 0 )
{
    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
    outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, -1);
    if (outputBufferIndex >= 0)
    {
        ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
        byte[] outData = new byte[bufferInfo.size];
        outputBuffer.get(outData);
        outputBuffer.clear();
        encoder.releaseOutputBuffer(outputBufferIndex, false);
        Log.d(LOG_TAG_ENCODING, util.bytesToString(outData));
    }
    else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
    {
        outputBuffers = encoder.getOutputBuffers();
    }
}

出力は次のとおりです。

07-11 13:13:58.622: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
07-11 13:13:58.632: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
07-11 13:13:58.667: 34 ff d9 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
07-11 13:13:58.672: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
07-11 13:13:58.677: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

私はグーグルで検索しましたが、助けが見つかりませんでした。MediaCodec の使用に関する Android ドキュメントも優れていません。出力バッファ コンテキストでの ByteBuffer.clear() の使用に関する多くの試行錯誤です。

よろしく、Ahti。

4

1 に答える 1

1

そこにいるすべての仲間の患者に、私自身の質問に答えてください。

実際の問題は、生の PCM データをエンコーダー入力に供給することでした。Android のドキュメントでは、データを入力バッファーに正確にフィードする方法が曖昧です (正直に言うと、実際には ByteBuffer の動作にもっと関係があります)。

int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
if (inputBufferIndex >= 0) {
   // fill inputBuffers[inputBufferIndex] with valid data
   ...
   codec.queueInputBuffer(inputBufferIndex, ...);
}

私の解釈は、次のようにデータを追加することでした:

inputBuffers[inputBufferIndex].clear();
inputBuffers[inputBufferIndex].put(audioPCMbuffer);
codec.queueInputBuffer(inputBufferIndex, ...);

上記のコードには 1 ビット欠けています: ByteBuffer の位置を反転します!

inputBuffers[inputBufferIndex].flip();

実装を確認するための単純なコードを見つけるのは非常に困難だったので、将来の参考のためにここに残しておきます。

于 2013-07-11T20:23:03.297 に答える