3

低レベルのメディア API を使用して mp3 やその他の形式のファイルをデコードし、処理できるようにしようとしています。ここのチュートリアルに従って、エンコードされたファイルを取得し、AudioTrack で再生します。コードはほとんど同じですが、エラーが発生します。

これが私のコードです:

public void playSongMono(View view)
{   
    //create extractor and point it to file
    AssetFileDescriptor fd = getResources().openRawResourceFd(R.raw.song);

    MediaExtractor extractor = new MediaExtractor();
    extractor.setDataSource(fd.getFileDescriptor(),fd.getStartOffset(),fd.getLength());

    //get MIME type of file
    MediaFormat inputFormat = extractor.getTrackFormat(0);
    Log.d("MonoPlayer","TRACKS #: "+extractor.getTrackCount());
    String mime = inputFormat.getString(MediaFormat.KEY_MIME);
    Log.d("MonoPlayer","FORMAT: "+mime);

    extractor.selectTrack(0);

    //create codec
    MediaCodec codec = MediaCodec.createDecoderByType(mime);
    Log.d("MonoPlayer","1");
    codec.configure(inputFormat, null, null, 0);
    Log.d("MonoPlayer","2");
    codec.start();
    Log.d("MonoPlayer","3");

    ByteBuffer[] inputBuffers = codec.getInputBuffers();
    ByteBuffer[] outputBuffers  = codec.getOutputBuffers();

    //get a buffer and fill it
    int inputBufferIndex = codec.dequeueInputBuffer(1000000);

    if(inputBufferIndex >= 0)
    {
        Log.d("MonoPlayer","4");
        //fill the buffer
        int sampleSize = extractor.readSampleData(inputBuffers[inputBufferIndex], 0);
        long presentationTimeUs = 0;
        boolean sawInputEOS= false;

        if (sampleSize < 0) {
            sawInputEOS = true;
            sampleSize = 0;
        } else {
            presentationTimeUs = extractor.getSampleTime();
        }

        codec.queueInputBuffer(inputBufferIndex,
                                0,
                                sampleSize,
                                presentationTimeUs,
                                sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);

        if (!sawInputEOS) {
            extractor.advance();
        }
    }

    BufferInfo info = new BufferInfo(); //this will be populated with data by dequeueOutputBuffer

    //get the index of a finished buffer. since we only enqueued one we should only wait for one
    int resultBufferIndex = codec.dequeueOutputBuffer(info, 1000000);

    if (resultBufferIndex >= 0 )
    {
        Log.d("MonoPlayer","5");
        //we now have a buffer of pcm data
        byte[] chunk = new byte[info.size];
        outputBuffers[resultBufferIndex].get(chunk); 
        outputBuffers[resultBufferIndex].clear();
        codec.releaseOutputBuffer(resultBufferIndex, false);

        //create audiotrack to play sound
        audiotrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                44100,
                AudioFormat.CHANNEL_OUT_STEREO,
                AudioFormat.ENCODING_PCM_16BIT,
                chunk.length,
                AudioTrack.MODE_STATIC);

        audiotrack.play();
        audiotrack.write(chunk, 0, chunk.length);

    }

    extractor.release();
    extractor = null;

    codec.stop();
    codec.release();
    codec = null;
}

そして、このコードを実行すると、次のlogcat出力が得られます

D MonoPlayer       TRACKS #: 1
D MonoPlayer       FORMAT: audio/mpeg
I OMXClient        Using client-side OMX mux.
D MonoPlayer       1
E OMXNodeInstance  OMX_GetExtensionIndex failed
D MonoPlayer       2
D MonoPlayer       3
D MonoPlayer       4

上記は私が言及したエラーです。このエラーが発生する理由や意味が正確にはわかりません。しかし、私はいくつかの情報を収集しようとしました。ログ出力を使用すると、行でエラーが発生することが示唆されますcodec.configure(inputFormat, null, null, 0);。行を削除しようとしましたが、これにより、不正な状態エラーが発生することが予想されますが、問題のエラーは削除されます。さらに、私が投稿したコードではLog.d("MonoPlayer","5");、デキュー呼び出しのタイムアウトが無期限に設定されていても、到達することはないため、デコーダーが適切に構成されていないと思います。

このエラーが発生する理由と、それを修正するために何ができるかについて誰かが情報を持っていれば、それは素晴らしいことです. 前もって感謝します。

4

1 に答える 1

2

そのメッセージはおそらく無害です。私は成功するテストでそれを見ます。

OMXNodeInstance.cppの 288 行目から来ているようです。OMX.google.android.index.enableAndroidNativeBuffers拡張機能の検索は失敗します。これは、拡張機能がそのデバイスで定義されていなかったことを意味します。

于 2013-04-03T21:09:32.227 に答える