title: How to get bitmap (frames) from video using MediaCodec
body: <p>I'm trying to get all frames from video file using MediaCodec. If I try display video on SurfaceView, everything is ok. But if surface is null, and when I try get Bitmap from byte array, alwaus get null or runtime exception.</p>
  
  <p>This is my code:</p>
  
  <pre><code>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(videoPath);
  
          for (int i = 0; i &lt; 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, 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;
  
          while (!Thread.interrupted()) {
              ++numFrames;
              if (!isEOS) {
                  int inIndex = decoder.dequeueInputBuffer(10000);
                  if (inIndex &gt;= 0) {
                      ByteBuffer buffer = inputBuffers[inIndex];
                      int sampleSize = extractor.readSampleData(buffer, 0);
                      if (sampleSize &lt; 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:
                  // I tried get Bitmap on few ways
                  //1.
                  //ByteBuffer buffer = outputBuffers[outIndex];
                  //byte[] ba = new byte[buffer.remaining()];
                  //buffer.get(ba);
                  //final Bitmap bmp = BitmapFactory.decodeByteArray(ba, 0, ba.length);// this return null
                  //2. 
                  //ByteBuffer buffer = outputBuffers[outIndex];
                  //final Bitmap bmp = Bitmap.createBitmap(1920, 1080, Config.ARGB_8888);//using MediaFormat object I know width and height
                  //int a = bmp.getByteCount(); //8294400
                  //buffer.rewind();
                  //int b = buffer.capacity();//3137536
                  //int c = buffer.remaining();//3137536
                  //bmp.copyPixelsFromBuffer(buffer); // java.lang.RuntimeException: Buffer not large enough for pixels
                  //I know what exception mean, but i don't know why xception occurs
  
                  //In this place I need bitmap
  
                  // We use a very simple clock to keep the video FPS, or the
                  // video
                  // playback will be too fast
                  while (info.presentationTimeUs / 1000 &gt; 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 &amp; MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                  Log.d("DecodeActivity",
                          "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
                  break;
              }
          }
  
          decoder.stop();
          decoder.release();
          extractor.release();
      }
  }
  </code></pre>
  
  <p>I have no idea how to solve it.</p>
  
  <p>Samos</p>