I am trying to use MediaCodec to extract all frames from a video for image processing, I am trying to display a video and grab a frame from outBuffers but I cannot initiate a bitmap instance from the received bytes.
I tried to display it on the surface or into nothing (zero) because I noticed that when rendering null, outBuffers get bytes of render frames.
This is the code:
private static final String SAMPLE = Environment.getExternalStorageDirectory() + "/test_videos/sample2.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) { } @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 void writeFrameToSDCard(byte[] bytes, int i, int sampleSize) { try { Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, sampleSize); File file = new File(Environment.getExternalStorageDirectory() + "/test_videos/sample" + i + ".png"); if (file.exists()) file.delete(); file.createNewFile(); FileOutputStream out = new FileOutputStream(file.getAbsoluteFile()); bmp.compress(Bitmap.CompressFormat.PNG, 90, out); out.close(); } catch (Exception e) { e.printStackTrace(); } } 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); int index = extractor.getTrackCount(); Log.d("MediaCodecTag", "Track count: " + index); 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(); int i = 0; 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) { 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);
Any help will be ambiguous
Nativ source share