设备上的音频编解码器 dequeueInputBuffer returns -1
audio codec dequeueInputBuffer returns -1 on device
我正在尝试播放从 MPEG2 传输 (.ts) 文件中提取的一些音频。我通过 MediaExtractor 获取音频流,使用 readSampleData 将样本复制到 MediaCodec 输入缓冲区,然后将 MediaCodec 输出缓冲区写入 AudioTrack。 MediaExtractor 将音频 MIME 类型指示为 "audio/mp4a-latm".
所有这些在 Nexus 7 2013 平板电脑上运行得非常好。
但它在便宜的 Neutab x7 平板电脑上根本不起作用。问题是在几个样本之后,dequeueInputBuffer 重复 returns -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 上有一个 "Videos" 应用程序播放此文件只是 fine.Logcat 显示它也在使用 MediaExtractor 和 AudioTrack 但显然不是 MediaCodec。我在 logcat 中看到了 Omx* 条目,所以它可能直接使用了 libstagefright。
据我阅读您的代码,每次您设法将一个输入缓冲区排队时,您只尝试使输出缓冲区出列一次。
请记住,解码器异步运行,并且输入和输出缓冲区的数量有限。即使解码器确实解码了您的输入缓冲区,输出缓冲区中的输出也可能无法立即使用。在这种情况下增加 TIMEOUT 值可能会有所帮助,但不能保证。
尝试拆分你的两个 if 语句,这样你每次都在循环中调用 dequeueOutputBuffer
,即使 dequeueInputBuffer
没有 return 任何缓冲区。
我正在尝试播放从 MPEG2 传输 (.ts) 文件中提取的一些音频。我通过 MediaExtractor 获取音频流,使用 readSampleData 将样本复制到 MediaCodec 输入缓冲区,然后将 MediaCodec 输出缓冲区写入 AudioTrack。 MediaExtractor 将音频 MIME 类型指示为 "audio/mp4a-latm".
所有这些在 Nexus 7 2013 平板电脑上运行得非常好。
但它在便宜的 Neutab x7 平板电脑上根本不起作用。问题是在几个样本之后,dequeueInputBuffer 重复 returns -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 上有一个 "Videos" 应用程序播放此文件只是 fine.Logcat 显示它也在使用 MediaExtractor 和 AudioTrack 但显然不是 MediaCodec。我在 logcat 中看到了 Omx* 条目,所以它可能直接使用了 libstagefright。
据我阅读您的代码,每次您设法将一个输入缓冲区排队时,您只尝试使输出缓冲区出列一次。
请记住,解码器异步运行,并且输入和输出缓冲区的数量有限。即使解码器确实解码了您的输入缓冲区,输出缓冲区中的输出也可能无法立即使用。在这种情况下增加 TIMEOUT 值可能会有所帮助,但不能保证。
尝试拆分你的两个 if 语句,这样你每次都在循环中调用 dequeueOutputBuffer
,即使 dequeueInputBuffer
没有 return 任何缓冲区。