I'm using MediaCodec to read a video file and store the frames on SD card. However it is storing a green rectangle instead of the actual frame. Here is the code:
    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]; //The bytebuffer i want to convert to bitmap
        Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + buffer);
        buffer.position(info.offset);
        buffer.limit(info.offset + info.size);
        byte[] ba = new byte[buffer.remaining()]; //converting bytebuffer to byte array
        buffer.get(ba);
        Log.d("ba", ba.length + "");
        // I have to convert the byte array to a bitmap. So I'm doing this : 
        YuvImage yuvimage = new YuvImage(ba, ImageFormat.NV21, 1280, 720, null);        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        yuvimage.compressToJpeg(new Rect(0, 0, 1280, 720), 80, baos);
        byte[] jdata = baos.toByteArray();
        Bitmap bmp = BitmapFactory.decodeByteArray(jdata, 0, jdata.length);
        if (bmp != null) {
            //Store the bitmap as JPEG in SD card
            Log.d("Barcode",barcodeNumber+"");
            String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
            File videoFile = new File(baseDir + "/MyPhotos2/image" + barcodeNumber + ".jpg");
            barcodeNumber ++;
            FileOutputStream out = null;
            Log.d("success","yes");
            try {
                out = new FileOutputStream(videoFile);
                bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                        if (out != null) {
                        out.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                }
            }
            else if(bmp==null)
            {
                Log.d("null","null");
            }
    // 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();
}
I think the problem is with the format of the bitmap. I'm not sure if what I'm doing is right here. Please correct any mistakes in this or suggest a way in which I can extract the bitmap from the ByteBuffer. I decided to use mediacodec because MediaMetadataRetriever is too slow.
                        
My goal was to handle the ByteBuffer myself so that later I can save the image while displaying it in Surface. Here's how I did it. I also note that in MediaCodec I do not transfer Surface that I can could processed ByteBuffer . Maybe you will find something that will help you.
}