MediaCodec API を使用して mp4 ファイルをデコードします。これで、video/raw の MIME タイプのバイト配列を取得でき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();
}
出力形式は次のようになります。
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 、ストライド=320、クロップ右=319}