android.media.MediaCodec# flush ( ) 源码实例Demo

下面列出了android.media.MediaCodec# flush ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。


/**
 * This method implements the actual seeking and can be overwritten by subclasses to implement
 * custom seeking methods.
 *
 * @see #seekTo(MediaPlayer.SeekMode, long)
 */
protected FrameInfo seekTo(MediaPlayer.SeekMode seekMode, long seekTargetTimeUs,
                           MediaExtractor extractor, MediaCodec codec) throws IOException {
    if(mPassive) {
        // Even when not actively seeking, the codec must be flushed to get rid of left over
        // audio frames from the previous playback position and the EOS flags need to be reset too.
        mInputEos = false;
        mOutputEos = false;
        codec.flush();
        return null;
    }

    Log.d(TAG, "seeking to:                 " + seekTargetTimeUs);
    Log.d(TAG, "extractor current position: " + extractor.getSampleTime());

    extractor.seekTo(seekTargetTimeUs, seekMode.getBaseSeekMode());

    Log.d(TAG, "extractor new position:     " + extractor.getSampleTime());

    // TODO add seek cancellation possibility
    // e.g. by returning an object with a cancel method and checking the flag at fitting places within this method

    mInputEos = false;
    mOutputEos = false;
    codec.flush();

    if(extractor.hasTrackFormatChanged()) {
        reinitCodec();
        mRepresentationChanged = true;
    }

    return decodeFrame(true, true);
}
 
源代码2 项目: heifreader   文件: HeifReader.java

private static void renderHevcImage(ByteBuffer bitstream, ImageInfo info, Surface surface) {
    long beginTime = SystemClock.elapsedRealtimeNanos();

    // configure HEVC decoder
    MediaCodec decoder = configureDecoder(info, bitstream.limit(), surface);
    MediaFormat outputFormat = decoder.getOutputFormat();
    Log.d(TAG, "HEVC output-format=" + outputFormat);

    decoder.start();
    try {
        // set bitstream to decoder
        int inputBufferId = decoder.dequeueInputBuffer(-1);
        if (inputBufferId < 0) {
            throw new IllegalStateException("dequeueInputBuffer return " + inputBufferId);
        }
        ByteBuffer inBuffer = decoder.getInputBuffer(inputBufferId);
        inBuffer.put(bitstream);
        decoder.queueInputBuffer(inputBufferId, 0, bitstream.limit(), 0, 0);

        // notify end of stream
        inputBufferId = decoder.dequeueInputBuffer(-1);
        if (inputBufferId < 0) {
            throw new IllegalStateException("dequeueInputBuffer return " + inputBufferId);
        }
        decoder.queueInputBuffer(inputBufferId, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);

        // get decoded image
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        while (true) {
            int outputBufferId = decoder.dequeueOutputBuffer(bufferInfo, -1);
            if (outputBufferId >= 0) {
                decoder.releaseOutputBuffer(outputBufferId, true);
                break;
            } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                outputFormat = decoder.getOutputFormat();
                Log.d(TAG, "HEVC output-format=" + outputFormat);
            } else {
                Log.d(TAG, "HEVC dequeueOutputBuffer return " + outputBufferId);
            }
        }
        decoder.flush();
    } finally {
        decoder.stop();
        decoder.release();
    }
    long endTime = SystemClock.elapsedRealtimeNanos();
    Log.i(TAG, "HEVC decoding elapsed=" + (endTime - beginTime) / 1000000.f + "[msec]");
}
 

private long fastSeek(long targetTime, MediaExtractor extractor, MediaCodec codec) throws IOException {
    codec.flush();
    extractor.seekTo(targetTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);

    if(extractor.getSampleTime() == targetTime) {
        Log.d(TAG, "skip fastseek, already there");
        return targetTime;
    }

    // 1. Queue first sample which should be the sync/I frame
    skipToNextSample();
    queueSampleToCodec(false);

    // 2. Then, fast forward to target frame
    /* 2.1 Search for the best candidate frame, which is the one whose
     *     right/positive/future distance is minimized
     */
    extractor.seekTo(targetTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);

    /* Specifies how many frames we continue to check after the first candidate,
     * to account for DTS picture reordering (this value is arbitrarily chosen) */
    int maxFrameLookahead = 20;

    long candidatePTS = 0;
    long candidateDistance = Long.MAX_VALUE;
    int lookaheadCount = 0;

    while (extractor.advance() && lookaheadCount < maxFrameLookahead) {
        long distance = targetTime - extractor.getSampleTime();
        if (distance >= 0 && distance < candidateDistance) {
            candidateDistance = distance;
            candidatePTS = extractor.getSampleTime();
            //Log.d(TAG, "candidate " + candidatePTS + " d=" + candidateDistance);
        }
        if (distance < 0) {
            lookaheadCount++;
        }
    }
    targetTime = candidatePTS; // set best candidate frame as exact seek target

    // 2.2 Fast forward to chosen candidate frame
    extractor.seekTo(targetTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
    while (extractor.getSampleTime() != targetTime) {
        extractor.advance();
    }
    Log.d(TAG, "exact fastseek match:       " + extractor.getSampleTime());

    return targetTime;
}