private void doExtract(MediaExtractor extractor,int trackIndex,MediaCodec decoder,FrameCallback frameCallback){
  final int TIMEOUT_USEC=10000;
  ByteBuffer[] decoderInputBuffers=decoder.getInputBuffers();
  int inputChunk=0;
  long firstInputTimeNsec=-1;
  boolean outputDone=false;
  boolean inputDone=false;
  while (!outputDone) {
    if (VERBOSE)     Log.d(TAG,"loop");
    if (mIsStopRequested) {
      Log.d(TAG,"Stop requested");
      return;
    }
    if (!inputDone) {
      int inputBufIndex=decoder.dequeueInputBuffer(TIMEOUT_USEC);
      if (inputBufIndex >= 0) {
        if (firstInputTimeNsec == -1) {
          firstInputTimeNsec=System.nanoTime();
        }
        ByteBuffer inputBuf=decoderInputBuffers[inputBufIndex];
        int chunkSize=extractor.readSampleData(inputBuf,0);
        if (chunkSize < 0) {
          decoder.queueInputBuffer(inputBufIndex,0,0,0L,MediaCodec.BUFFER_FLAG_END_OF_STREAM);
          inputDone=true;
          if (VERBOSE)           Log.d(TAG,"sent input EOS");
        }
 else {
          if (extractor.getSampleTrackIndex() != trackIndex) {
            Log.w(TAG,"WEIRD: got sample from track " + extractor.getSampleTrackIndex() + ", expected "+ trackIndex);
          }
          long presentationTimeUs=extractor.getSampleTime();
          decoder.queueInputBuffer(inputBufIndex,0,chunkSize,presentationTimeUs,0);
          if (VERBOSE) {
            Log.d(TAG,"submitted frame " + inputChunk + " to dec, size="+ chunkSize);
          }
          inputChunk++;
          extractor.advance();
        }
      }
 else {
        if (VERBOSE)         Log.d(TAG,"input buffer not available");
      }
    }
    if (!outputDone) {
      int decoderStatus=decoder.dequeueOutputBuffer(mBufferInfo,TIMEOUT_USEC);
      if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
        if (VERBOSE)         Log.d(TAG,"no output from decoder available");
      }
 else       if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
        if (VERBOSE)         Log.d(TAG,"decoder output buffers changed");
      }
 else       if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
        MediaFormat newFormat=decoder.getOutputFormat();
        if (VERBOSE)         Log.d(TAG,"decoder output format changed: " + newFormat);
      }
 else       if (decoderStatus < 0) {
        throw new RuntimeException("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus);
      }
 else {
        if (firstInputTimeNsec != 0) {
          long nowNsec=System.nanoTime();
          Log.d(TAG,"startup lag " + ((nowNsec - firstInputTimeNsec) / 1000000.0) + " ms");
          firstInputTimeNsec=0;
        }
        boolean doLoop=false;
        if (VERBOSE)         Log.d(TAG,"surface decoder given buffer " + decoderStatus + " (size="+ mBufferInfo.size+ ")");
        if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
          if (VERBOSE)           Log.d(TAG,"output EOS");
          if (mLoop) {
            doLoop=true;
          }
 else {
            outputDone=true;
          }
        }
        boolean doRender=(mBufferInfo.size != 0);
        if (doRender && frameCallback != null) {
          frameCallback.preRender(mBufferInfo.presentationTimeUs);
        }
        decoder.releaseOutputBuffer(decoderStatus,doRender);
        if (doRender && frameCallback != null) {
          frameCallback.postRender();
        }
        if (doLoop) {
          Log.d(TAG,"Reached EOS, looping");
          extractor.seekTo(0,MediaExtractor.SEEK_TO_CLOSEST_SYNC);
          inputDone=false;
          decoder.flush();
          if (frameCallback != null) {
            frameCallback.loopReset();
          }
        }
      }
    }
  }
}

private void doExtract ( MediaExtractor extractor , int trackIndex , MediaCodec decoder , FrameCallback frameCallback ) { final int TIMEOUT_USEC = 10000 ; ByteBuffer [ ] decoderInputBuffers = decoder . getInputBuffers ( ) ; int inputChunk = 0 ; long firstInputTimeNsec = - 1 ; boolean outputDone = false ; boolean inputDone = false ; while ( ! outputDone ) { if ( VERBOSE ) Log . d ( TAG , "loop" ) ; if ( mIsStopRequested ) { Log . d ( TAG , "Stop requested" ) ; return ; } if ( ! inputDone ) { int inputBufIndex = decoder . dequeueInputBuffer ( TIMEOUT_USEC ) ; if ( inputBufIndex >= 0 ) { if ( firstInputTimeNsec == - 1 ) { firstInputTimeNsec = System . nanoTime ( ) ; } ByteBuffer inputBuf = decoderInputBuffers [ inputBufIndex ] ; int chunkSize = extractor . readSampleData ( inputBuf , 0 ) ; if ( chunkSize < 0 ) { decoder . queueInputBuffer ( inputBufIndex , 0 , 0 , 0L , MediaCodec . BUFFER_FLAG_END_OF_STREAM ) ; inputDone = true ; if ( VERBOSE ) Log . d ( TAG , "sent input EOS" ) ; } else { if ( extractor . getSampleTrackIndex ( ) != trackIndex ) { Log . w ( TAG , "WEIRD: got sample from track " + extractor . getSampleTrackIndex ( ) + ", expected " + trackIndex ) ; } long presentationTimeUs = extractor . getSampleTime ( ) ; decoder . queueInputBuffer ( inputBufIndex , 0 , chunkSize , presentationTimeUs , 0 ) ; if ( VERBOSE ) { Log . d ( TAG , "submitted frame " + inputChunk + " to dec, size=" + chunkSize ) ; } inputChunk ++ ; extractor . advance ( ) ; } } else { if ( VERBOSE ) Log . d ( TAG , "input buffer not available" ) ; } } if ( ! outputDone ) { int decoderStatus = decoder . dequeueOutputBuffer ( mBufferInfo , TIMEOUT_USEC ) ; if ( decoderStatus == MediaCodec . INFO_TRY_AGAIN_LATER ) { if ( VERBOSE ) Log . d ( TAG , "no output from decoder available" ) ; } else if ( decoderStatus == MediaCodec . INFO_OUTPUT_BUFFERS_CHANGED ) { if ( VERBOSE ) Log . d ( TAG , "decoder output buffers changed" ) ; } else if ( decoderStatus == MediaCodec . INFO_OUTPUT_FORMAT_CHANGED ) { MediaFormat newFormat = decoder . getOutputFormat ( ) ; if ( VERBOSE ) Log . d ( TAG , "decoder output format changed: " + newFormat ) ; } else if ( decoderStatus < 0 ) { throw new RuntimeException ( "unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus ) ; } else { if ( firstInputTimeNsec != 0 ) { long nowNsec = System . nanoTime ( ) ; Log . d ( TAG , "startup lag " + ( ( nowNsec - firstInputTimeNsec ) / 1000000.0 ) + " ms" ) ; firstInputTimeNsec = 0 ; } boolean doLoop = false ; if ( VERBOSE ) Log . d ( TAG , "surface decoder given buffer " + decoderStatus + " (size=" + mBufferInfo . size + ")" ) ; if ( ( mBufferInfo . flags & MediaCodec . BUFFER_FLAG_END_OF_STREAM ) != 0 ) { if ( VERBOSE ) Log . d ( TAG , "output EOS" ) ; if ( mLoop ) { doLoop = true ; } else { outputDone = true ; } } boolean doRender = ( mBufferInfo . size != 0 ) ; if ( doRender && frameCallback != null ) { frameCallback . preRender ( mBufferInfo . presentationTimeUs ) ; } decoder . releaseOutputBuffer ( decoderStatus , doRender ) ; if ( doRender && frameCallback != null ) { frameCallback . postRender ( ) ; } if ( doLoop ) { Log . d ( TAG , "Reached EOS, looping" ) ; extractor . seekTo ( 0 , MediaExtractor . SEEK_TO_CLOSEST_SYNC ) ; inputDone = false ; decoder . flush ( ) ; if ( frameCallback != null ) { frameCallback . loopReset ( ) ; } } } } } }
work loop . we execute here until we run out of video or are told to stop .
