我一直在尝试使用 libstagefright 来解码 h264 压缩帧。我没有 MP4 文件,而是想逐帧解码。我一直在从链接中探索样本. 此示例使用 ffmpeg 解析 mp4 文件。并使用 ffmpeg 的 avcodeccontext 设置并找到所需的元数据。现在我想设置 kKeyAVCC、kKeyWidth、kKeyHeight、kKeyIsSyncFrame 和 kKeyTime。我不清楚这些参数中的每一个。那么,我只想知道是否需要设置所有这些参数?这些参数的目的是什么,以及为逐帧解码的元数据设置什么。当我没有设置 kKeyTime 时,omxcodec 在读取媒体缓冲区时崩溃。如果我在读取操作上获得成功,我不会得到我在 MediaBuffer 的派生读取方法中设置的元数据值。我得到帧的视频尺寸和 INFO_FORMAT_CHANGED 的错误代码。
1 回答
创建新编解码器时,元数据作为OMXCodec::Create
方法的一部分从解析器传递到解码器。我假设在您的实现中,您会注意以普通香草实现MetaData
中指定的格式传递元数据。android
例如,请参考AwesomePlayer::initVideoDecoder
在哪个mVideoTrack->getFormat()
中调用来获取视频轨道的元数据。请注意,这不是 a 的一部分MediaBuffer
,而是作为单独的对象传递。
一旦创建了解码器,configureCodec
就会调用 。在这个方法中,OMXCodec
读取不同的配置参数来初始化解码器。
kKeyAVCC
对应于Codec Specific Data
orcsd
本质上是底层流的SPS
and 。PPS
H.264
kKeyWidth
kKeyHeight
对应于视频帧width
的和height
。为了初始化解码器,您可以设置更多的附加参数。例如,如果您为colorFormat
解码器的输出设置特定的,您可以通过kKeyColorFormat
.
创建解码器后,您必须通过标准openmax
接口传递各个帧。解码器从调用OMXCodec::read
方法开始,该方法将填充输入和输出缓冲区。
输入缓冲区通过从解析器模块(在您的情况下是您的特定模块)OMXCodec::drainInputBuffer
读取 a 的方法填充。MediaBuffer
的内容MediaBuffer
被复制到组件上填充的缓冲区input port
中OMX
。与此数据一起,timestamp
此缓冲区的 也被传递。时间戳信息是kKeyTime
通过随MediaBuffer
.
因此,对于在 a 中传递的每一帧MediaBuffer
,您需要确保一个有效timestamp
的也传递给底层解码器,该解码器反映在解码器的输出端口上。
在您的问题中,您曾询问过kKeyIsSyncFrame
. 该标志由Encoder
作为FillBufferDone
回调的一部分设置,即当编码器对关键帧进行编码时IDR frame
,然后它通过此特定标志传达此信息,作为编码器输出端口上的回调的一部分。 对于解码,这无关紧要。
如果您可以在启用日志的情况下发布更多日志OMXCodec
,则提供更准确的答案可能会更容易。
PS 在 android 框架中,有一个名为的命令行实用程序Stagefright
,它创建解析器和解码器并执行命令行解码而无需任何渲染。这可能是您插入自己的解析器的一个很好的参考。