Android硬件解码

来源:互联网 发布:在淘宝买散片cpu可靠吗 编辑:程序博客网 时间:2024/04/27 23:38

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 {private static final String SAMPLE = Environment.getExternalStorageDirectory() + "/video.mp4";private PlayerThread mPlayer = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SurfaceView sv = new SurfaceView(this);sv.getHolder().addCallback(this);setContentView(sv);}protected void onDestroy() {super.onDestroy();}@Overridepublic void surfaceCreated(SurfaceHolder holder) {}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {if (mPlayer == null) {mPlayer = new PlayerThread(holder.getSurface());mPlayer.start();}}@Overridepublic 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;}@Overridepublic 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// dequeueOutputBufferLog.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 fastwhile (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 nowif ((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();}}}



0 0