Kimi_Jin
Kimi_Jin

Reputation: 21

How to create Bitmap with byte array of the mime type video/raw

I use the MediaCodec API to decode the mp4 file. Now I have got the byte array with the mime type of video/raw, how could I byte array to create the Bitmap or any other object's that to show in the Activity? Here are all the code.

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();

}

And you can see the output format like this:

Format:{height=240, what=1869968451, color-format=19, slice-height=240, crop-left=0, width=320, crop-bottom=239, crop-top=0, mime=video/raw, stride=320, crop-right=319}

Upvotes: 1

Views: 1928

Answers (1)

user1379574
user1379574

Reputation: 709

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.

Upvotes: 1

Related Questions