我的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}));

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

现在,当我想解码AAC样本时,解码器发布
AAC decoder returned error 4097, substituting silence

到日志。

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

当我使用由MediaExtractor创建的mediaFormat配置MediaCodec时,MediaCodec可以解码TSExtractor返回的AAC样本,而不会出现任何问题。比较由我的TSExtractor创建的MediaFormat和基本上由HashMap封装的MediaFormat,由MediaExtractor创建的HashMap可以得出以下区别:

由MediaExtractor创建:



由TSExtractor创建:



即使当我采用由TSExtractor创建的MediaFormat类似于由MediaExtractor创建的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);

做。

顺便说一句,比较这两个byteBuffer使用
bb1.equals(bb2);

返回true。

很奇怪!

10-05 17:43