1

我使用 MediaCodec API 来解码 mp4 文件。现在我得到了具有 mime 类型的 video/raw 的字节数组,我怎样才能创建字节数组来创建Bitmap或任何其他对象,以显示在Activity? 这是所有的代码。

private Resources mResources;
private Button m_playBtn;
private ImageView imageView = null;
private MyAudioTrack audioTrack = null;

private File f = null;
private FileOutputStream fos = null;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getActionBar().setDisplayHomeAsUpEnabled(true);
    mResources = this.getResources();
    m_playBtn = (Button) findViewById(R.id.playBtn);
    m_playBtn.setOnClickListener(this);
    imageView = (ImageView) findViewById(R.id.imageView);
    imageView.setImageResource(R.drawable.eee);
    audioTrack = new MyAudioTrack(44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,AudioFormat.ENCODING_PCM_16BIT);
    audioTrack.init();
    f = new File("/sdcard/rawdata");
    try {
        fos = new FileOutputStream(f);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/*
 * the local file at res/raw R.raw.admiral R.raw.ttt R.raw.ww The h264 file
 * can't decode by MediaCodec . Mp3 or Mp4 can get decode byte[] from
 * MediaCodec
 */
@Override
public void onClick(View v) {
    try {
        decode(R.raw.testmp4, 0.0f);
        //decode("http://192.168.2.14/img/video.mjpeg");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

/**
 * @param testinput
 *            the file to decode
 * @param master
 *            the "golden master" to compared against
 * @param maxerror
 *            the maximum allowed root mean squared error
 * @throws IOException
 */
@SuppressLint("ParserError")
private void decode(int testinput, float maxerror) throws IOException {

    AssetFileDescriptor testFd = mResources.openRawResourceFd(testinput);

    MediaExtractor extractor;
    MediaCodec codec;
    ByteBuffer[] codecInputBuffers;
    ByteBuffer[] codecOutputBuffers;

    extractor = new MediaExtractor();
    //      extractor.setDataSource("http://zhangmenshiting2.baidu.com/data2/music/10547672/10547672.mp3?xcode=bcab1e9a9ffffae03c350b4e1ff22833&mid=0.09955182129452");
    extractor.setDataSource(testFd.getFileDescriptor(),
            testFd.getStartOffset(), testFd.getLength());
    System.out.println("wrong number of tracks:" + 1 + ":"
            + (extractor.getTrackCount()));
    MediaFormat format = extractor.getTrackFormat(0);
    String mime = format.getString(MediaFormat.KEY_MIME);
    System.out.println("mime type=====>" + mime);
    System.out.println("not an audio file:" + (mime.startsWith("audio/")));
    codec = MediaCodec.createDecoderByType(mime);
    codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
    codec.start();
    codecInputBuffers = codec.getInputBuffers();
    codecOutputBuffers = codec.getOutputBuffers();

    extractor.selectTrack(0);

    // start decoding
    int numBytesDecoded = 0;
    int maxdelta = 0;
    // long totalErrorSquared = 0;
    final long kTimeOutUs = 5000;
    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
    boolean sawInputEOS = false;
    boolean sawOutputEOS = false;
    while (!sawOutputEOS) {
        if (!sawInputEOS) {
            int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);

            if (inputBufIndex >= 0) {
                ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];

                int sampleSize = extractor
                        .readSampleData(dstBuf, 0 /* offset */);

                long presentationTimeUs = 0;

                if (sampleSize < 0) {
                    System.out.println("saw input EOS.");
                    sawInputEOS = true;
                    sampleSize = 0;
                } else {
                    presentationTimeUs = extractor.getSampleTime();
                }

                codec.queueInputBuffer(inputBufIndex, 0 /* offset */,
                        sampleSize, presentationTimeUs,
                        sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM
                                : 0);

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

        int res = codec.dequeueOutputBuffer(info, kTimeOutUs);
        /**
         * from here can get the decode data
         */
        if (res >= 0) {
            MediaFormat ff = codec.getOutputFormat();// decode format
            System.out.println("Format:" + ff);
            //System.out.println("format information detail" + ff.getInteger("channel-count"));
            int outputBufIndex = res;
            ByteBuffer buf = codecOutputBuffers[outputBufIndex];
            final byte[] chunk = new byte[info.size];// decode data
            System.out.println("chunk.size" + chunk.length);
            buf.get(chunk);
            buf.clear();


            if(chunk.length > 0){
                fos.write(chunk);

            numBytesDecoded += info.size;

            codec.releaseOutputBuffer(outputBufIndex, false /* render */);

            if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                System.out.println("saw output EOS.");
                sawOutputEOS = true;
            }
        } else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
            codecOutputBuffers = codec.getOutputBuffers();
            System.out.println("output buffers have changed.");
        } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            MediaFormat oformat = codec.getOutputFormat();
            System.out.println("output format has changed to :" + oformat);
        }
    }
    System.out.println("geshu:" + maxdelta);
    fos.flush();
    codec.stop();
    codec.release();
    testFd.close();

}

你可以看到这样的输出格式:

格式:{height=240, what=1869968451, color-format=19, slice-height=240,crop-left=0, width=320,crop-bottom=239,crop-top=0, mime=video/raw , 步幅=320, 裁剪右=319}

4

1 回答 1

1

You have to show it on surface. Add to layout VideoView. Then use surface holder to obtain surface object. After that pass the object to method of codec configuration and put true in method releaseInOutputBuffer. Thus you video will be rendered on activity.

于 2012-10-22T12:37:00.290 回答