MediaCodec在API 17中异步解码视频和音频

时间:2019-01-29 16:22:08

标签: java android mediacodec mediaextractor android-mediacodec

我有一个使用Android 4.2的旧设备,试图在该设备上播放视频流。我正在使用MediaCodec和MediaExtractor,但是顺序解码视频和音频似乎很慢。进行音频会使它从30和音频卡顿速度降低到将近20fps,但是如果我取出音频解码器,它会非常流畅。有没有一种方法可以使其异步,从而使视频渲染不必等待音频?同样在我的代码中,“ extractor.getSampleTrackIndex()”似乎占用了大部分处理时间,因为它试图找出数据块是来自音频还是视频轨道,并且这似乎使所有内容变慢。 / p>

extractor.setDataSource(uri);

for (int i = 0; i < extractor.getTrackCount(); i++) {
    MediaFormat format = extractor.getTrackFormat(i);
    String mime = format.getString(MediaFormat.KEY_MIME);
    if (mime.startsWith("video/")) {
        Log.d(TAG, "Found video track with format " + mime);
        mVideoTrackIndex = i;
        extractor.selectTrack(mVideoTrackIndex);
        format_h264 = format;
        videoDecoder = MediaCodec.createDecoderByType(mime);
        videoDecoder.configure(format, surface, null, 0);
        Log.d(TAG, "Found a videoDecoder for " + mime);
    } else if (mime.startsWith("audio/") && audioDecoder == null) {
        Log.d(TAG, "Found audio track with format " + mime);
        audio_mime = mime;
        audio_format = extractor.getTrackFormat(i);
        try {
            audioDecoder = MediaCodec.createDecoderByType(audio_mime);
            if (audioDecoder != null) {
                audioDecoder.configure(audio_format, null, null, 0);
                mAudioTrackIndex = i;
                extractor.selectTrack(mAudioTrackIndex);
                MediaFormat extractorTrackFormat = extractor.getTrackFormat(mAudioTrackIndex);
                mAudioSampleRate = extractorTrackFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
                Log.d(TAG, "Found an audioDecoder for " + mime);
            }
        } catch (Exception e) {
            Log.w(TAG, "no audioDecoder found for" + mime);
            e.printStackTrace();
        }
    } else {
        Log.d(TAG, "Unknown mime type: " + mime + " on format: " + format.toString());
    }
}


videoDecoder.start();
VideoDecoderThread videoDecoderThread = new VideoDecoderThread();
videoDecoderThread.start();

ByteBuffer[] videoInputBuffers = videoDecoder.getInputBuffers();

AudioDecoderThread audioDecoderThread = null;

if (audioDecoder != null) {
    audioDecoder.start();
    audioInputBuffers = audioDecoder.getInputBuffers();
    audioDecoderThread = new AudioDecoderThread();
    audioDecoderThread.start();
}

while (!Thread.interrupted()) {    
    if (!isEOS) {
        render(extractor, videoInputBuffers, audioInputBuffers);
        extractor.advance();
    } else {Thread.sleep(1);}
}


void render(MediaExtractor extractor, ByteBuffer[] videoInputBuffers, ByteBuffer[] audioInputBuffers) {
    int videoInIndex;
    int audioinIndex;
    ByteBuffer buffer;

   int trackIndex = extractor.getSampleTrackIndex();

    if (trackIndex == mVideoTrackIndex) {
        videoInIndex = videoDecoder.dequeueInputBuffer(0);
        if (videoInIndex < 0) return;
        buffer = videoInputBuffers[videoInIndex];
        videoDecoder.queueInputBuffer(videoInIndex, 0, extractor.readSampleData(buffer, 0), extractor.getSampleTime(), 0);
    } else {
        if (audioDecoder != null) {
            audioinIndex = audioDecoder.dequeueInputBuffer(0);
            if (audioinIndex < 0) return;
            buffer = audioInputBuffers[audioinIndex];
            audioDecoder.queueInputBuffer(audioinIndex, 0, extractor.readSampleData(buffer, 0), extractor.getSampleTime(), 0);
        }
    }
}

0 个答案:

没有答案