我正在尝试播放从MPEG2传输(.ts)文件中获取的某些音频。我通过MediaExtractor获取音频流,使用readSampleData将样本复制到MediaCodec输入缓冲区,然后将MediaCodec输出缓冲区写入AudioTrack。 MediaExtractor将音频MIME类型指示为“audio / mp4a-latm”。
所有这一切都在Nexus 7 2013平板电脑上运行得非常好。
但它在廉价的Neutab x7平板电脑上根本不起作用。问题是在几个样本之后,dequeueInputBuffer重复返回-1。 注释掉对AudioTrack.write()的调用不会改变这一事实,因此问题在于MediaCodec的操作。
代码看起来像(记录,省略了一些错误处理):
audioInputBufferIndex = audioCodec.dequeueInputBuffer(TIMEOUT);
if (audioInputBufferIndex >= 0) {
audioInputBuffers[audioInputBufferIndex].clear();
sampleSize = audioExtractor.readSampleData(audioInputBuffers[audioInputBufferIndex], 0);
audioPresentationTimeUs = audioExtractor.getSampleTime();
audioCodec.queueInputBuffer(audioInputBufferIndex,0,sampleSize,audioPresentationTimeUs,0);
audioOutputBufferIndex = audioCodec.dequeueOutputBuffer(audioBufferInfo, TIMEOUT);
if (audioOutputBufferIndex >= 0) {
ByteBuffer buffer = audioOutputBuffers[audioOutputBufferIndex];
byte[] chunk = new byte[audioBufferInfo.size];
buffer.get(chunk);
buffer.clear();
if (audioTrack != null & chunk.length > 0) {
audioTrack.write(chunk, 0, chunk.length);
audioExtractor.advance();
}
audioCodec.releaseOutputBuffer(audioOutputBufferIndex,false);
audioCodec
配置了从audioExtractor
获取的MediaFormat。我已经尝试将TIMEOUT增加到大值,没有快乐。
为什么这些代码在这两个设备上的行为会有所不同?有转动的旋钮吗?
Neutab上有一个“视频”应用可以正常播放这个文件.Logcat显示它也使用了MediaExtractor和AudioTrack,但显然不是MediaCodec。我在logcat中看到了Omx *条目,所以也许它直接使用libstagefright。
答案 0 :(得分:3)
就我读代码而言,每次设法排队一个输入缓冲区时,只尝试将输出缓冲区出列一次。
请记住,解码器是异步运行的,并且输入和输出缓冲区数量有限。即使解码器对输入缓冲区进行解码,输出也可能无法立即在输出缓冲区中使用。在这种情况下增加TIMEOUT值可能有所帮助,但不能保证。
尝试拆分两个if语句,以便在循环中每次调用dequeueOutputBuffer
,即使dequeueInputBuffer
没有返回任何缓冲区。