设备上的音频编解码器 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 任何缓冲区。