FFmpeg无法解码H264流/帧数据 [英] FFmpeg can't decode H264 stream/frame data

查看:781
本文介绍了FFmpeg无法解码H264流/帧数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



每次 avcodec_decode_video2 是所谓的 - FFmpeg只是说:


[h264 @ 00339220]没有框架!


我原始的H264流帧数据开始如下: 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 字节开始为帧数据...但这是我有... ..

解决方案

好的,设法使事情工作。




  • 我需要包括序列(SPS)和图片在发送帧到FFmpeg之前,我的帧数据的参数集
    (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(','); (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); //准备00 00 00 01
ba [3] = 0x01;

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

年前我以为我已将H264流支持整合到我的项目中,直到我有机会测试它与一些其他设备...
所以你需要记住,一些设备可能会发送SPS和PPS数据每一帧...有些可能不!


Recently I had chance to work with two devices that are streaming the H264 through RTSP. And I've ran into some problem trying to decompress this stream using FFmpeg library.

Every time the "avcodec_decode_video2" is called - FFmpeg just says something like:

[h264 @ 00339220] no frame!

My raw H264 stream I frame data starts like this: "65 88 84 21 3F F8 F8 0D..." (as far as I understand this 0x65 indicates that it's a IDR frame?)

Other frames for one device starts like: "41 9A 22 07 F3 4E 48 CC...."

and for other device - like this: "61 9A 25 C1 1C 45 62 39...."

  • Am I missing some frame data here?
  • Does FFmpeg needs to have some extra parameters set up?

I was expecting at least "00 00 00 01" bytes at the start for the frame data... but this is what I've got..

解决方案

Ok, managed to make things working.

  • I needed to include the sequence (SPS) and picture parameter sets (PPS) for my frame data before sending frame to the FFmpeg.
  • I needed to add 4 extra bytes "00 00 00 01" after SPS and PPS data.

Here is a little picture showing what I mean:

Bytes "65 88..." is where my original frame data begins.

This SPS and PPS information was not included in RTP packet. I'm using Live555 library for RTSP streaming, so I've used subsessions "fmtp_spropparametersets" function to get what I need. This information was Base64 encoded. (Sample: Something like this "Z0KAKNoC0EkQ,aM48gA==") Note that there are two "parameters" SPS and PPS seperated by "," and those parameters doesn't have a "00 00 00 01" included, so you need to add them.

Some code sample (I'm using Qt library here):

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));
}

Now for every frame I do something like this:

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);

Year ago I thought I had H264 stream support integrated in my project till I've had chance to test it with some other devices... So you need to keep in mind that some devices might send SPS and PPS data for every I frame... and some might not!

这篇关于FFmpeg无法解码H264流/帧数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆