18

最近我有机会使用两台通过 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 ”字节......但这就是我所拥有的......

4

1 回答 1

19

好的,设法使事情正常进行。

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

这是一张小图片,显示了我的意思: 在此处输入图像描述

字节“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 数据。 ..有些可能不会!

于 2012-07-05T09:20:51.847 回答