您的位置:首页 > 其它

MediaCodec Demo

2015-12-04 09:28 302 查看
package io.vec.demo.mediacodec;

import java.nio.ByteBuffer;

import android.app.Activity;

import android.media.MediaCodec;

import android.media.MediaCodec.BufferInfo;

import android.media.MediaExtractor;

import android.media.MediaFormat;

import android.os.Bundle;

import android.os.Environment;

import android.util.Log;

import android.view.Surface;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

public class DecodeActivity extends Activity implements SurfaceHolder.Callback {

//获取手机sdcard卡中的video.mp4

private static final String SAMPLE = Environment.getExternalStorageDirectory() + "/video.mp4";

//声明播放线程

private PlayerThread mPlayer = null;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

SurfaceView sv = new SurfaceView(this);

sv.getHolder().addCallback(this);

setContentView(sv);

}

protected void onDestroy() {

super.onDestroy();

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

}

/**

*若线程为空,重新实例化并获取Surface

*/

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

if (mPlayer == null) {

mPlayer = new PlayerThread(holder.getSurface());

mPlayer.start();

}

}

/**

*线程存在则销毁

*/

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

if (mPlayer != null) {

mPlayer.interrupt();

}

}

private class PlayerThread extends Thread {

private MediaExtractor extractor;

private MediaCodec decoder;

private Surface surface;

public PlayerThread(Surface surface) {

this.surface = surface;

}

@Override

public void run() {

extractor = new MediaExtractor();

extractor.setDataSource(SAMPLE);

for (int i = 0; i < extractor.getTrackCount(); i++) {

MediaFormat format = extractor.getTrackFormat(i);

String mime = format.getString(MediaFormat.KEY_MIME);

if (mime.startsWith("video/")) {

extractor.selectTrack(i);

decoder = MediaCodec.createDecoderByType(mime);

decoder.configure(format, surface, null, 0);

break;

}

}

if (decoder == null) {

Log.e("DecodeActivity", "Can't find video info!");

return;

}

decoder.start();

ByteBuffer[] inputBuffers = decoder.getInputBuffers();

ByteBuffer[] outputBuffers = decoder.getOutputBuffers();

BufferInfo info = new BufferInfo();

boolean isEOS = false;

long startMs = System.currentTimeMillis();

while (!Thread.interrupted()) {

if (!isEOS) {

int inIndex = decoder.dequeueInputBuffer(10000);

if (inIndex >= 0) {

ByteBuffer buffer = inputBuffers[inIndex];

int sampleSize = extractor.readSampleData(buffer, 0);

if (sampleSize < 0) {

// We shouldn't stop the playback at this point, just pass the EOS

// flag to decoder, we will get it again from the

// dequeueOutputBuffer

Log.d("DecodeActivity", "InputBuffer BUFFER_FLAG_END_OF_STREAM");

decoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);

isEOS = true;

} else {

decoder.queueInputBuffer(inIndex, 0, sampleSize, extractor.getSampleTime(), 0);

extractor.advance();

}

}

}

int outIndex = decoder.dequeueOutputBuffer(info, 10000);

switch (outIndex) {

case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:

Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED");

outputBuffers = decoder.getOutputBuffers();

break;

case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:

Log.d("DecodeActivity", "New format " + decoder.getOutputFormat());

break;

case MediaCodec.INFO_TRY_AGAIN_LATER:

Log.d("DecodeActivity", "dequeueOutputBuffer timed out!");

break;

default:

ByteBuffer buffer = outputBuffers[outIndex];

Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + buffer);

// We use a very simple clock to keep the video FPS, or the video

// playback will be too fast

while (info.presentationTimeUs / 1000 > System.currentTimeMillis() - startMs) {

try {

sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

break;

}

}

decoder.releaseOutputBuffer(outIndex, true);

break;

}

// All decoded frames have been rendered, we can stop playing now

if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {

Log.d("DecodeActivity", "OutputBuffer BUFFER_FLAG_END_OF_STREAM");

break;

}

}

decoder.stop();

decoder.release();

extractor.release();

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: