【问题标题】:MediaFormat.getByteBuffer("csd-0") returning null on some devicesMediaFormat.getByteBuffer("csd-0") 在某些设备上返回 null
【发布时间】:2017-04-22 05:38:51
【问题描述】:

我正在尝试在我的应用程序中解码 AAC 编码文件并初始化用于初始化我的 MediaCodec 对象的 MediaFormatobject,这是为 MediaFormat 对象设置变量的代码

MediaExtractor mediaExtractor = new MediaExtractor();
        try {
            mediaExtractor.setDataSource(audioFilePath);
        } catch (IOException e) {
            return false;
        }
        Log.d(TAG, "Number of tracks in the file are:" + mediaExtractor.getTrackCount());

        MediaFormat mediaFormat = mediaExtractor.getTrackFormat(0);

        Log.d(TAG, "mediaFormat:" + mediaFormat.toString());

        mSampleRate = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
        Log.d(TAG, "mSampleRate: " + mSampleRate);


        mChannels = mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);

        Log.d(TAG, "mChannels number of channels: " + mChannels);

        // Reading the duration from the file and converting from micro seconds to milliseconds.
        mDuration = (int) (mediaFormat.getLong(MediaFormat.KEY_DURATION) / 1000);

        Log.d(TAG, "duration: " + mDuration);

        // Getting the csd-0 info from the file ..
        mCSDBuffer = mediaFormat.getByteBuffer("csd-0");

我面临的问题是声明 mCSDBuffer = mediaFormat.getByteBuffer("csd-0") 在某些设备上为同一文件获取了 null。该应用程序正在生产中,我在 android API 级别为 17、18 和 19 的armabi-v7a/armabiprocessors 设备上看到此错误,并且这些错误中的大多数都在三星设备上。这有什么方向吗?

【问题讨论】:

    标签: android decoding android-mediacodec aac


    【解决方案1】:

    如果csd-0 缓冲区为空,那么我希望它在传递到 MediaCodec 时仍能正确解码。如果您只是选择不将 csd-0 数据设置为 MediaCodec 的输入(如果它为空),会不会?一般来说,如果您直接将 MediaExtractor 输出通过管道传输到 MediaCodec,您应该能够解码它。

    虽然从 MediaExtractor 输出的数据的实际格式并没有非常严格地指定,所以在实践中众所周知,一些制造商(主要是三星)以只有他们自己的解码器处理的方式改变了这一点。参见例如https://code.google.com/p/android/issues/detail?id=74356 另一个相同的情况。

    理想情况下,Android CTS 测试会变得更严格,以确保 MediaExtractor 的行为一致,允许在更通用的上下文中使用它,或者使用除 MediaCodec 之外的其他解码器。 (例如,对于当前的三星问题,您不能在一台设备上使用 MediaExtractor,将提取的数据通过网络发送到另一台设备并在那里解码。)

    【讨论】:

    • 我还有一个自定义函数,借助它可以生成 stackoverflow.com/a/32154154/2606411 中提到的“csd-0”缓冲区。我可以用它来手动设置信息吗?
    • 你也许可以使用它。但如果这样做,您可能还应该从实际的音频数据包中去除 ADTS 标头。 IMO,如果 MediaExtractor 选择以 ADTS 格式返回数据(即数据包中没有 csd-0 和 ADTS 标头),那么 MediaCodec 应该能够处理它,所以我认为您根本不需要进行任何编辑。
    • 我们自己对我们使用的文件进行了编码,并为所有文件设置了 ADTS 标头,所以我认为手动设置该标头是有意义的。
    • 但即使是正常情况下(当 MediaExtractor 返回 csd-0 信息时),我们也会自己读取 ADTS 标头并从中获取所有信息。有没有办法,我们可以通过MediaCodec api 避免这种情况?
    • 所以您要手动读取 ADTS 标头,以便将采样率和通道号提供给 MediaCodec 以初始化解码器? MediaExtractor 不会在它返回的 MediaFormat 中为您提供这些值吗?
    猜你喜欢
    • 1970-01-01
    • 2016-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 2013-01-10
    • 1970-01-01
    相关资源
    最近更新 更多