gpt4 book ai didi

android - 如何初始化 MediaFormat 以配置 MediaCodec 来解码原始 AAC 数据?

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:56:46 25 4
gpt4 key购买 nike

我的 StreamPlayer 有一个奇怪的问题,我需要任何帮助。

我需要实现的主要目标是 StreamPlayer,它能够以尽可能小的延迟播放 MPEG-2 传输流。为此,我遵循这种方法:

流由基于 Java 的 TS 解析器解析。我已经实现了一个 TSExtractor,它类似于 MediaExtractor,并且工作正常。我可以接收选定轨道的所有媒体样本,就像使用 MediaExtractor 和

extractor.readSampleData(...);
extractor.advance();

要解码 AAC 数据,我想创建和配置 MediaCodec 的实例。使用 MediaExtractor 类,这通常由

MediaFormat mediaFormat = extractor.getTrackFormat(i);
decoder = MediaCodec.createDecoderByType(mediaFormat.getString(MediaFormat.KEY_MIME));
decoder.configure(mediaFormat, null, null, 0);

因为我必须在我使用的 TSExtractor.getTrackFormat(int track) 方法中初始化 MediaFormat

MediaFormat mf = MediaFormat.createAudioFormat ("audio/mp4a-latm", getSampleRate(), getChannelCount());

因为我所有的 AAC 样本都包含我做的 ADTS

mediaFormat.setInteger(MediaFormat.KEY_IS_ADTS, 1); 

看完this最后我使用“csd-0”键添加了一个 ESDS 框架

mediaFormat.setByteBuffer("csd-0", ByteBuffer.allocate(2).put(new byte[]{(byte) 0x11, (byte)0x90}));

其中值 0x11 和 0x90 是从 ADTS 中提取的。

当我现在想解码解码器发布的 AAC 样本时

AAC decoder returned error 4097, substituting silence

到日志。

为了验证我的 TSExtractor 是否正确提取样本,我使用 VLC 将相同的流记录为 mp4 文件,没有转码,因此原始流没有变化。现在我可以用录制的 mp4 文件初始化 MediaExtractor 并比较由我的 TSExtractor 和 MediaExtractor 创建的样本。使用跟踪和错误我发现了一个非常奇怪的行为:

当我使用 MediaExtractor 创建的 mediaFormat 配置 MediaCodec 时,MediaCodec 可以毫无问题地解码我的 TSExtractor 返回的 AAC 样本。比较由我的 TSExtractor 创建的基本上包装 HashMap 的 MediaFormat 和由 MediaExtractor 创建的 MediaFormat 给出了以下差异:

由 MediaExtractor 创建:

mediaFormat: {max-input-size=1212, durationUs=77428875, is-adts=1, channel-count=2, mime=audio/mp4a-latm, csd-0=java.nio.ByteArrayBuffer[position=0,limit=2,capacity=2], sample-rate=48000}

由 TSExtractor 创建:

mediaFormat: {is-adts=1, channel-count=2, mime=audio/mp4a-latm, csd-0=java.nio.ByteArrayBuffer[position=2,limit=2,capacity=2], sample-rate=48000}

即使我采用由 TSExtractor 创建的 MediaFormat 类似于由 MediaExtractor 创建的 MediaFormat,解码器也会使用自创建的 MediaFormat 给出相同的错误,而使用另一个解码器则没有任何问题。

任何帮助都会很有帮助。

最佳答案

我真的不知道为什么,但事实证明是这样初始化“csd-0”ByteBuffer

mediaFormat.setByteBuffer("csd-0", ByteBuffer.allocate(2).put(new byte[]{(byte) 0x11, (byte)0x90}));

不行,但要这样初始化

byte[] bytes = new byte[]{(byte) 0x11, (byte)0x90};
ByteBuffer bb = ByteBuffer.wrap(bytes);
mediaFormat.setByteBuffer("csd-0", bb);

会。

顺便说一句,比较这两个字节缓冲区使用

bb1.equals(bb2);

返回真。

很奇怪!

关于android - 如何初始化 MediaFormat 以配置 MediaCodec 来解码原始 AAC 数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18784781/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com