如何处理Android MediaCodec解码器的第一个输出ByteBuffers?

时间:2016-10-30 02:42:42

标签: android audio mediacodec mediaextractor

我正在尝试使用Android的MediaCodec套件编写音频重采样器。

我目前正在将MP3立体声音频文件输入MediaExtractor,然后由MediaCodec解码。源音频的采样率为48000。

我不明白的是我从解码器收到的前四个输出缓冲区:

  1. size 0,time 0
  2. 尺寸0,时间24000
  3. 尺寸4312,时间48000
  4. 尺寸4608,时间72000
  5. 尺寸4608,时间96000
  6. this answerthis answerthis article,我相信前两个缓冲区只是传播“编码器延迟”,可能只是被抛弃。但是,我列出的第三个缓冲区会抛出一个循环。

    对于缓冲区#4(及以后),数学计算出来了:

    ((4608 bytes) / (2 bytes/sample) / (2 channels)) 
        / ((48,000 samples/sec) / (1,000,000 us/sec))
    = 24,000 us (i.e. the change in time between buffers)
    

    虽然缓冲区#3发生了什么?对数据的简单描述表明,音频在48000 us时开始播放,然后在72000 us标记之前暂停,此时它开始连续播放而没有休息。

    似乎更有可能在缓冲区#3的数据之前有296个隐藏的0,但是这个偏移似乎没有被我的代码中的任何变量指示。任何人都可以为我阐明这一点吗?

1 个答案:

答案 0 :(得分:1)

据我所知,音频MediaCodec内容*并不关心时间戳与每个缓冲区的关联。相反,它只是通过假设字节流中没有漏洞,使用指定的比特率神奇地重新计算每个数据的时间戳应该是什么。

作为这个假设的支持证据,this answer中的一个解决方案只是建议递增时间戳值而不是实际计算正确的时间戳。

因此,在此问题的示例中,音频MediaCodec内容*将完全忽略所有时间戳值。缓冲区#3字节#1将由MediaCodec假定为时间0,缓冲区#4字节#1的时间将从迄今处理的字节数和取为24000或48000

*即MediaCodec对象或一些相关的自定义组件

注意:MediaCodec视频编码器似乎确实关心时间戳。