5

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

4

1 回答 1

9

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

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

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

kKeyAVCC对应于Codec Specific Dataorcsd本质上是底层流的SPSand 。PPSH.264

kKeyWidthkKeyHeight对应于视频帧width的和height。为了初始化解码器,您可以设置更多的附加参数。例如,如果您为colorFormat解码器的输出设置特定的,您可以通过kKeyColorFormat.

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

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

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

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

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

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

于 2013-02-16T02:52:09.033 回答