

表題通り、`MediaExtractor`を使用しない場合の`MediaCodec`のデコード方法がわかりません。

自分が探した限りでは`MediaCodec`によるデコードのサンプルはほとんどが`MediaExtractor`を使用したものばかりでした。`MediaExtractor`を使用したくない理由として再生をしながら
メタデータ(icy-meta, Shoutcast)、MP3 Rawバイナリを操作したいと考えているからです。

`MediaExtractor`をもちいたデコードの[サンプル](https://github.com/ytRino/MediaCodecSample/blob/a65e7b73ea299fda6d3f4ff66edc1c362986b70d/src/net/nessness/android/sample/showmycodec/MainActivity.java)を元に`FileInputStream`を使用したコードを書いてみました。エラーが起きてまともにデコードできません。

[code]

    package com.test;
    
    import android.app.Activity;
    import android.media.AudioFormat;
    import android.media.AudioManager;
    import android.media.AudioTrack;
    import android.media.MediaCodec;
    import android.media.MediaCodec.BufferInfo;
    
    import android.media.MediaFormat;
    import android.os.Bundle;
    import android.os.Environment;
    import android.util.Log;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.nio.ByteBuffer;
    
    import com.test.R;
    
    public class AndroidTestActivity extends Activity {
    
        private static final String TAG = "TAG";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            new Thread() {
                @Override
                public void run() {
                    try {
                        process();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    
        private synchronized void process() throws IOException {
            File inputFile = new File(Environment.getExternalStorageDirectory().getPath() + "/download/music/test.mp3");
            FileInputStream fis = new FileInputStream(inputFile);        
    
            MediaFormat format = MediaFormat.createAudioFormat("audio/mpeg", 44100,2);
            String mime = format.getString(MediaFormat.KEY_MIME);
            //int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
    
            MediaCodec codec = MediaCodec.createDecoderByType(mime);
            codec.configure(format, null , null , 0);
            codec.start();
    
            ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
            ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
    
            AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,
                    format.getInteger(MediaFormat.KEY_SAMPLE_RATE),
                    AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT,
                    8000, AudioTrack.MODE_STREAM);
            track.play();
    
            BufferInfo info = new BufferInfo();
            boolean inputEos = false;
            boolean outputEos = false;
            long timeoutUs = 1000;
    
            byte[] tempBuffer = new byte[8192];
    
            while (!outputEos) {
                if (!inputEos) {
                    int inputBufIndex = codec.dequeueInputBuffer(timeoutUs);
                    if (inputBufIndex >= 0) {
                        ByteBuffer buf = codecInputBuffers[inputBufIndex];
    
                        int bytesRead = fis.read(tempBuffer, 0, buf.limit());
    
                        long presentationTimeUs = 0;
                        if (bytesRead < 0) {
                            inputEos = true;
                            bytesRead = 0;
                        } else {
                            presentationTimeUs = System.nanoTime();
                        }
    
                        codec.queueInputBuffer(inputBufIndex, 0, bytesRead, presentationTimeUs,
                                inputEos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
                    }
                }
    
                int res = codec.dequeueOutputBuffer(info, timeoutUs);
    
                if (res >= 0) {
                    int outputBufIndex = res;
    
                    ByteBuffer buf = codecOutputBuffers[outputBufIndex];
                    byte[] dst = new byte[info.size];
                    int oldPosition = buf.position();
    
                    buf.get(dst);
                    buf.position(oldPosition);
    
                    //Play music
                    track.write(dst, 0, dst.length);
    
                    codec.releaseOutputBuffer(outputBufIndex, false);
    
                    if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                        Log.d(TAG, "output eos.");
                        outputEos = true;
                    }
                } else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                    Log.d(TAG, "output buffer changed.");
                    codecOutputBuffers = codec.getOutputBuffers();
                } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                    MediaFormat f = codec.getOutputFormat();
                    Log.d(TAG, "output format changed. " + f);
                    //track.setPlaybackRate(f.getInteger(MediaFormat.KEY_SAMPLE_RATE));
                }
            }
    
            Log.d(TAG, "complete stop!");
            fis.close();
            codec.stop();
            codec.release();
        }
    }
    
[/code]

以下実行時のエラー

[code]

    01-20 00:57:22.271: I/OMXClient(2626): Using client-side OMX mux.
    01-20 00:57:22.276: E/SEC_COMP_REGS(2626): .
    01-20 00:57:22.276: E/SEC_COMP_REGS(2626): ..
    01-20 00:57:22.276: E/SEC_COMP_REGS(2626): libOMX.SEC.AVC.Decoder.so
    01-20 00:57:22.276: E/SEC_COMP_REGS(2626): Path & libName : /system/lib/omx/libOMX.SEC.AVC.Decoder.so
    01-20 00:57:22.276: E/SEC_COMP_REGS(2626): libOMX.SEC.AVC.Encoder.so
    01-20 00:57:22.276: E/SEC_COMP_REGS(2626): Path & libName : /system/lib/omx/libOMX.SEC.AVC.Encoder.so
    01-20 00:57:22.281: E/SEC_COMP_REGS(2626): libOMX.SEC.M4V.Decoder.so
    01-20 00:57:22.281: E/SEC_COMP_REGS(2626): Path & libName : /system/lib/omx/libOMX.SEC.M4V.Decoder.so
    01-20 00:57:22.281: E/SEC_COMP_REGS(2626): libOMX.SEC.M4V.Encoder.so
    01-20 00:57:22.291: E/SEC_COMP_REGS(2626): Path & libName : /system/lib/omx/libOMX.SEC.M4V.Encoder.so
    01-20 00:57:22.291: E/SEC_COMP_REGS(2626): libOMX.SEC.WMV.Decoder.so
    01-20 00:57:22.291: E/SEC_COMP_REGS(2626): Path & libName : /system/lib/omx/libOMX.SEC.WMV.Decoder.so
    01-20 00:57:22.311: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.321: D/TAG(2626): output format changed. {sample-rate=44100, channel-count=2, what=1869968451, mime=audio/raw}
    01-20 00:57:22.331: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.341: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.351: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.396: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.436: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.481: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.486: D/libEGL(2626): loaded /system/lib/egl/libEGL_mali.so
    01-20 00:57:22.491: D/libEGL(2626): loaded /system/lib/egl/libGLESv1_CM_mali.so
    01-20 00:57:22.496: D/libEGL(2626): loaded /system/lib/egl/libGLESv2_mali.so
    01-20 00:57:22.506: E/(2626): Device driver API match
    01-20 00:57:22.506: E/(2626): Device driver API version: 23
    01-20 00:57:22.506: E/(2626): User space API version: 23 
    01-20 00:57:22.506: E/(2626): mali: REVISION=Linux-r3p2-01rel3 BUILD_DATE=Wed Oct  9 21:05:57 KST 2013 
    01-20 00:57:22.526: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.536: D/OpenGLRenderer(2626): Enabling debug mode 0
    01-20 00:57:22.576: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.621: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.626: I/ActivityManager(2626): Timeline: Activity_idle id: android.os.BinderProxy@424d6780 time:611732103
    01-20 00:57:22.666: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.716: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:22.811: E/SoftMP3(2626): mp3 decoder returned error 12
    ...以下略...
    01-20 00:57:29.171: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:29.221: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:29.266: E/SoftMP3(2626): mp3 decoder returned error 12
    01-20 00:57:29.401: D/TAG(2626): output eos.
    01-20 00:57:29.401: D/TAG(2626): complete stop!
    01-20 00:57:29.411: I/OMXNodeInstance(2626): OMX_FreeBuffer for buffer header 0x524cc9d8 successful
    01-20 00:57:29.411: I/OMXNodeInstance(2626): OMX_FreeBuffer for buffer header 0x524cc8d8 successful
    01-20 00:57:29.411: I/OMXNodeInstance(2626): OMX_FreeBuffer for buffer header 0x524cc7c0 successful
    01-20 00:57:29.416: I/OMXNodeInstance(2626): OMX_FreeBuffer for buffer header 0x524cad28 successful
    01-20 00:57:29.416: I/OMXNodeInstance(2626): OMX_FreeBuffer for buffer header 0x524cd018 successful
    01-20 00:57:29.421: I/OMXNodeInstance(2626): OMX_FreeBuffer for buffer header 0x524ccf48 successful
    01-20 00:57:29.421: I/OMXNodeInstance(2626): OMX_FreeBuffer for buffer header 0x524cce30 successful
    01-20 00:57:29.426: I/OMXNodeInstance(2626): OMX_FreeBuffer for buffer header 0x524cccb8 successful
    
[/code]


CC BY-SA 3.0
2015-01-19T16:22:47.023
4861
2015-02-26T12:46:07.740
2015-02-26T12:46:07.740
7926
7494
question
android java mp3
MediaExtractorを使用しないMediaCodecデコード方法がわかりません