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 回答