【问题标题】:To use HW decoder in android through libstagefright, what to set for kKeyAVCC in meta data for frame base decoding instead of MP4 playback?要通过 libstagefright 在 android 中使用硬件解码器,在元数据中为 kKeyAVCC 设置什么以进行帧基解码而不是 MP4 播放?
【发布时间】:2013-01-31 03:48:42
【问题描述】:

我一直在尝试使用 libstagefright 来解码 h264 压缩帧。我没有 MP4 文件,而是想逐帧解码。我一直在探索来自a link 的样本。此示例使用 ffmpeg 解析 mp4 文件。并使用 ffmpeg 的 avcodeccontext 设置并找到所需的元数据。现在我想设置 kKeyAVCC、kKeyWidth、kKeyHeight、kKeyIsSyncFrame 和 kKeyTime。我不清楚这些参数中的每一个。那么,我只想知道是否需要设置所有这些参数?这些参数的目的是什么,以及为逐帧解码的元数据设置什么。当我没有设置 kKeyTime 时,omxcodec 在读取媒体缓冲区时崩溃。如果我在读取操作上获得成功,我不会得到我在 MediaBuffer 的派生读取方法中设置的元数据值。我得到帧的视频尺寸和 INFO_FORMAT_CHANGED 的错误代码。

【问题讨论】:

    标签: android android-ndk h.264 stagefright


    【解决方案1】:

    创建新编解码器时,元数据作为OMXCodec::Create 方法的一部分从解析器传递到解码器。我假设在您的实现中,您会注意以普通的 android 实现中指定的 MetaData 格式传递元数据。

    例如,请参考AwesomePlayer::initVideoDecoder,其中调用mVideoTrack->getFormat()获取视频轨道的元数据。请注意,这不是 MediaBuffer 的一部分,而是作为单独的对象传递的。

    一旦创建解码器,就会调用configureCodec。该方法中OMXCodec读取不同的配置参数来初始化解码器。

    kKeyAVCC 对应于 Codec Specific Datacsd,本质上是底层 H.264 流的 SPSPPS

    kKeyWidthkKeyHeight对应视频帧的widthheight。为了初始化解码器,您可以设置更多的附加参数。例如,如果你为解码器的输出设置一个特定的colorFormat,你可以通过kKeyColorFormat来设置。

    创建解码器后,您必须通过标准openmax 接口传递各个帧。解码器通过调用OMXCodec::read 方法启动,该方法将填充输入和输出缓冲区。

    输入缓冲区通过OMXCodec::drainInputBuffer 方法填充,该方法从解析器模块(在您的情况下是您的特定模块)读取MediaBufferMediaBuffer 的内容被复制到填充在OMX 组件的input port 上的缓冲区中。除了这个数据,这个缓冲区的timestamp 也被传递。时间戳信息通过与MediaBuffer 一起传递的kKeyTime 参数读取。

    因此,对于在MediaBuffer 中传递的每一帧,您需要确保将有效的timestamp 也传递给底层解码器,该解码器会反映在解码器的输出端口上。

    在您的问题中,您曾询问过kKeyIsSyncFrame。此标志由Encoder 设置,作为FillBufferDone 回调的一部分,即当编码器对IDR frame 之类的关键帧进行编码时,它会通过此特定标志传达此信息,作为输出端口上回调的一部分编码器。 对于解码,这无关紧要

    如果您可以在启用OMXCodec 日志的情况下发布更多日志,则可能更容易提供更准确的答案。

    附:在 android 框架中,有一个名为Stagefright 的命令行实用程序,它创建解析器和解码器并执行命令行解码,无需任何渲染。这可能是您插入自己的解析器的一个很好的参考。

    【讨论】:

    • 首先非常感谢您详细的回答。你提供了非常好的信息。我在我的项目中通过 android.mk 链接 libstagfright.so。我需要包含来自 Android 源的所有相应包含标头。我编写了两个名为 CustomMediaSource 和 CustomDecoder 的类。 CustomMediaSource 派生自 MediaSource 并实现 read 方法,而在 CustomDecoder 中,我调用 OMXCodec::Create 方法。现在,我怀疑 libstagefright 是否可以稳定地用于所有 android 设备。我的意思是,它可以非常符合 TI、Qualcom 等供应商的要求吗?
    • API 的角度来看,无论供应商如何,libstagefright 库都是相同的。但是,如果您正在查看一些性能数据,则可能存在特定于供应商 SoC 的潜在定制。我并不是说这将永远是这种情况,但很有可能。如果您无法访问来源,那么您可能无法区分。
    • 谢谢。我想开发一个独立于平台的 android 应用程序。因此,选择稳定的 api 变得很重要。所以,正如你所说,我会在所有安卓手机中找到 libstagefright.so,它具有相同的 api 结构,我可以派生媒体源并将派生类的实例用于 OMXCodec::Create 方法。 . .对吗?
    • 谢谢 Ganesh。我需要您的另一项帮助来实施。您在回答中提到我可以使用 kKeyColorFormat 标志设置编解码器的输出色彩空间。现在,当我将 kKeyColorFormat 设置为 OMX_COLOR_Format16bitRGB565 时,OMXCodec::Create 方法不会返回。根据我的要求,我希望解码和显示 h264 帧和表面可以在 rgb565 颜色空间中渲染。那么,你能告诉我如何在表面上实现 yuv 渲染吗?当我将 kKeyColorFormat 参数设置为 rgb565 时会出现什么问题?
    • Video Decoder 很少支持OMX_Color_Format16BitRGB565 作为输出格式。要确切知道发生了什么,您可能需要OMXCodec 日志或启用来自OMX 组件的日志。如果要渲染表面,则必须在surfaceflinger 和/或hwcomposer 接口内进行修改,以执行colorConversionYUVRGB
    猜你喜欢
    • 1970-01-01
    • 2014-11-07
    • 2015-10-12
    • 2014-10-01
    • 1970-01-01
    • 2015-01-18
    • 2016-06-29
    • 2019-06-17
    • 2013-07-13
    相关资源
    最近更新 更多