我有一个使用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);
}
}
}