FFmpeg 无法解码 H264 流/帧数据

Posted

技术标签:

【中文标题】FFmpeg 无法解码 H264 流/帧数据【英文标题】:FFmpeg can't decode H264 stream/frame data 【发布时间】:2012-07-05 01:21:44 【问题描述】:

最近我有机会使用两台通过 RTSP 流式传输 H264 的设备。 我在尝试使用 FFmpeg 库解压缩此流时遇到了一些问题。

每次调用“avcodec_decode_video2” - FFmpeg 只会说:

[h264 @ 00339220] 没有框架!

我的原始 H264 流 I 帧数据如下所示:“65 88 84 21 3F F8 F8 0D...” (据我了解,这个 0x65 表示它是一个 IDR 帧?)

一个设备的其他帧开头如下:“41 9A 22 07 F3 4E 48 CC....”

对于其他设备 - 像这样:“61 9A 25 C1 1C 45 62 39....”

我在这里遗漏了一些帧数据吗? FFmpeg 是否需要设置一些额外的参数?

我期望帧数据的开头至少有“00 00 00 01”字节......但这就是我所得到的......

【问题讨论】:

【参考方案1】:

好的,成功了。

我需要包含序列 (SPS) 和图片参数集 (PPS) 在将帧发送到 FFmpeg 之前用于我的帧数据。 我需要在 SPS 和 PPS 数据之后添加 4 个额外字节“00 00 00 01”。

这是一张小图,说明了我的意思:

Bytes "65 88..." 是我的原始帧数据开始的地方。

此 SPS 和 PPS 信息未包含在 RTP 数据包中。我正在使用 Live555 库进行 RTSP 流式传输,因此我使用了子会话“fmtp_spropparametersets”函数来获得我需要的东西。此信息是 Base64 编码的。 (示例:类似 "Z0KAKNoC0EkQ,aM48gA==") 请注意,有两个“参数”SPS 和 PPS 由“,”分隔,并且这些参数没有“00 00 00 01 " 包括在内,因此您需要添加它们。

一些代码示例(我在这里使用 Qt 库):

QByteArray        ba          = pSubSession->fmtp_spropparametersets();
QList<QByteArray> recordsList = ba.split(',');

for (int i = 0; i < recordsList.size(); i++)

   mExtraData.append(char(0x00));
   mExtraData.append(char(0x00));
   mExtraData.append(char(0x00));
   mExtraData.append(char(0x01));

   mExtraData += QByteArray::fromBase64(recordsList.at(i));

现在对于每一帧我都做这样的事情:

QByteArray ba = QByteArray(4, 0); // Prepare the "00 00 00 01"
           ba[3] = 0x01;

mpTrackVideo->buffer.insert(0, mExtraData);
mpTrackVideo->buffer.insert(mExtraData.size(), ba);

一年前,我以为我的项目中集成了 H264 流支持,直到我有机会使用其他一些设备对其进行测试... 所以您需要记住,有些设备可能会为每个 I 帧发送 SPS 和 PPS 数据……而有些可能不会!

【讨论】:

以上是关于FFmpeg 无法解码 H264 流/帧数据的主要内容,如果未能解决你的问题,请参考以下文章

解码 RIMM 流文件格式

视频学习笔记:Android ffmpeg解码多路h264视频并显示

FFmpeg解码H264及swscale缩放详解

关于h264编解码的一些重要事项

使用 FFMpeg 将 FLV 流式传输到 RTMP,使用 H264 编解码器和 C++ API 到 flv.js

无法使用 ffmpeg 更改视频字幕编解码器