0

我正在尝试播放一些从 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从 获取的 MediaFormat 进行配置audioExtractor。我尝试将 TIMEOUT 增加到较大的值,但没有任何乐趣。

为什么这段代码在这两种设备上的行为会有所不同?有什么旋钮可以转动吗?

Neutab 上有一个“视频”应用程序可以很好地播放这个文件。Logcat 显示它也在使用 MediaExtractor 和 AudioTrack,但显然不是 MediaCodec。我在 logcat 中看到 Omx* 条目,所以它可能直接使用 libstagefright。

4

1 回答 1

4

据我阅读您的代码,每次您设法将一个输入缓冲区排队时,您只尝试将输出缓冲区出列一次。

请记住,解码器异步运行,并且输入和输出缓冲区数量有限。即使解码器确实解码了您的输入缓冲区,输出也可能不会立即在输出缓冲区中可用。在这种情况下增加 TIMEOUT 值可能会有所帮助,但不能保证。

尝试拆分您的两个 if 语句,以便您dequeueOutputBuffer每次都在循环中调用,即使dequeueInputBuffer没有返回任何缓冲区。

于 2015-03-06T07:28:18.123 回答