我的 StreamPlayer 有一个奇怪的问题,我需要任何可以得到的帮助。
我需要实现的主要目标是 StreamPlayer,它能够以尽可能小的延迟播放 MPEG-2 传输流。为此,我遵循这种方法:
流由基于 Java 的 TS Parser 解析。我已经实现了一个 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);
阅读这篇文章后,我终于使用“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,容量=2],采样率=48000}
由 TSExtractor 创建:
mediaFormat: {is-adts=1, channel-count=2, mime=audio/mp4a-latm, csd-0=java.nio.ByteArrayBuffer[position=2,limit=2,capacity=2], 采样率= 48000}
即使我采用 TSExtractor 创建的 MediaFormat 与 MediaExtractor 创建的 MediaFormat 相似,解码器使用自己创建的解码器也会出现相同的错误,而使用另一个解码器则没有任何问题。
任何帮助都会非常有帮助。