ffmpeg 获取摄像头接收RTSP摄像头为什么Size=0kb

ffmpeg播放rtsp视频流花屏解决办法
最近做rtsp视频流播放,用到了ffmpeg,在处理花屏现象时花了不少时间。现在分享一下解决方案,希望对各位有所帮助。
我使用的版本为ffmpeg 2.6.3,使用平台为iOS
&可直接到官网下载http://ffmpeg.org/download.html
花屏有三个原因:
其一是发送数据包太大,超过了ffmpeg默认最大值。解决方法为下面的步骤 1。
其二是网络情况较差时,因网络状况出现的丢包而导致花屏。我这里是将有丢包的帧过滤掉,从而避免花屏现象。解决方法为下面的步骤2,3。
其三是因为解码出错。解决方法为下面的2,4,5,6,7,8,9。
要过滤掉丢包和解码出错的帧,首先需要找到丢包和解码出错的地方。通过ffmpeg打印的日志,再进行文本搜索,目前丢包的地方已明确找出,解码错误的地方找到以下几个地方,可能还有一些漏掉的,以后再慢慢补充。
1.修改udp.c&
&&UDP_MAX_PKT_SIZE&&大小x10
2设全局变量 & &在丢包或解码出错时将全局变量置为不同的值
& 最后在使用的地方根据全局变量的值来判断该帧是否完整 &
全局变量可在ffmpeg任意.h文件中设置 &我是在avcodec.h中设置的
3.修改rtpdec.c文件包含&missed %d
package的地方,这里出现丢包,需作标记
4.修改error_resilience.c文件&包含concealing
%d DC, %d AC, %d MV errors in %c
frame的地方。这里出现解包错误,需标记
5.修改h264_cavlc.c文件中包含&Invalid
level prefix处 这里出错 需标记
& 修改h264_cavlc.c文件中包含dquant out of
range处,出错,需标记
& 修改h264_cavlc.c文件中包含corrupted
macroblock处,出错,需标记
& 修改h264_cavlc.c文件中包含negative number of zero
coeffs at处,出错,需标记
修改h264_cavlc.c文件中包含mb_type %d in %c slice too large at %d
%d处,出错,徐标记
&&修改h264_cavlc.c文件中包含cbp too
large处,出错,需标记 &
6.修改error_resilience.c文件中包含Cannot use previous picture in error
concealment处,出错,需标记
& &修改error_resilience.c文件中包含Cannot use next
picture in error concealment处,出错,需标记
7.修改h264.c文件中包含out of range intra chroma pred mode
at处,出错,需标记
& &修改h264.c文件中包含top block unavailable for
requested intra mode at处,出错,需标记
&修改h264.c文件中包含left block unavailable for
requested intra mode at处,出错,需标记
8.修改h264_slice.c文件中包含error while decoding MB处,出错,需标记
9.修改svq3.c文件中包含error while decoding MB处,出错,需标记
修改完成后,需重新编译ffmpeg源码。
可以在使用的时候将全局变量打印出来,会发现一旦有丢包或解码错误现象,全局变量就会有对应的值。这样就可以通过该全局变量来判断该帧是否完整了,从而过滤掉。
需要注意的是,每一帧处理后,都需要将全局变量重置。
在iOS上测试,即使在网络条件较差的情况下,基本上已经没有花屏现象。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。现在位置:
恋香缘基于云计算随机推荐他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
我通过live555打开本地的SDP文件,然后通过这个文件为我的IP Camera建立个传输会话,已经成功,DummySink中的 afterGettingFrame这回调函数能不间断的调用,我直接把表示每帧fReceiveBuffer和frameSize传入了FFMPEG的解码器,但是 avcodec_decode_video2总是调用失败。我查看了一些帧的fReceiveBuffer,里面没有插入相关的SPS和PPS,没有0x的标记,因为解码器要解码IDR帧必须通过SPS和PPS正确初始化,才能够解码,我的SDP文件里面有PPS和SPS的Base64编码,我需要怎么处理这个SPS和PPS才能正确初始化解码器?不然解码器是无法解码H264的。FFMPEG中的AVCodecContext中的extradata也没有相关文档描述怎么用,听说是用来存放SPS和PPS的,如果是,该怎么用?我需要把SPS和PPS的Base64的编码解出来再传入吗?还是直接就传入(插入)SPS和PPS的Base64版本?
以下是我的代码片断:
void afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes,
struct timeval presentationTime, unsigned durationInMicroseconds)
if (fStreamId != NULL) envir() && "Stream \"" && fStreamId && "\"; ";
envir() && fSubsession.mediumName() && "/" && fSubsession.codecName() && ":\tReceived " && frameSize && " bytes";
if (numTruncatedBytes & 0) envir() && " (with " && numTruncatedBytes && " bytes truncated)";
char uSecsStr[6 + 1]; // used to output the 'microseconds' part of the presentation time
sprintf_s(uSecsStr, 7, "%06u", (unsigned)presentationTime.tv_usec);
envir() && ".\tPresentation time: " && (int)presentationTime.tv_sec && "." && uSecsS
gffmpeg-&decodeFrame(fReceiveBuffer, frameSize, presentationTime.tv_sec, presentationTime.tv_usec);
// Then continue, to request the next frame of data:
continuePlaying();
QFFmpeg::decodeFrame(uint8_t* frameBuffer, int frameLength, long second, long microSecond)
if (frameLength &= 0)
int frameFinished = 0;
AVPacket frameP
av_init_packet(&framePacket);
framePacket.size = frameL
framePacket.data = frameB
int ret = avcodec_decode_video2(m_pAVCodecContext, m_pAVFrame, &frameFinished, &framePacket);
if (ret & 0)
qDebug() && "Decode error";
if (frameFinished)
m_playMutex.lock();
m_videoWidth = m_pAVFrame-&
m_videoHeight = m_pAVFrame-&
m_pSwsContext = sws_getContext(m_videoWidth, m_videoHeight, AVPixelFormat::AV_PIX_FMT_YUV420P, m_videoWidth, m_videoHeight, AVPixelFormat::AV_PIX_FMT_RGB24, SWS_BICUBIC, 0, 0, 0);
sws_scale(m_pSwsContext, (const uint8_t* const *)m_pAVFrame-&data, m_pAVFrame-&linesize, 0, m_videoHeight, m_pAVPicture.data, m_pAVPicture.linesize);
char timestamp[100];
sprintf_s(timestamp, 100, "Time Stamp is: %ld.%ld", second, microSecond);
//发送获取一帧图像信号
QImage image(m_pAVPicture.data[0], m_videoWidth, m_videoHeight, QImage::Format_RGB888);
QPainter pen(&image);
pen.setPen(Qt::white);
pen.setFont(QFont("Times", 10, QFont::Bold));
pen.drawText(image.rect(), Qt::AlignBottom, QString(timestamp));
emit GetImage(image);
m_playMutex.unlock();
以下是解码器的初始化,都能正确返回
bool QFFmpeg::Init()
m_pAVCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!m_pAVCodec)
m_pAVCodecContext = avcodec_alloc_context3(m_pAVCodec);
if (avcodec_open2(m_pAVCodecContext, m_pAVCodec, NULL) & 0)
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
先理解关键知识点,不知道有没有误导,H264的帧是以
NAL单元的单位来传送的,一个NAL单元包含一帧(I帧 或 P帧 或 B帧),这三种类型的帧可以百度。所谓的NAL单元就是去掉SPS、PPS的视频帧, I帧是关键帧,所有的解析都需要靠它,两个I帧之间被称为视频序列,I帧头部需要加入SPS和PPS,这两个之间需要0x来分割, 0x00 0x00 0x00 0x01
+ SPS的Base64解码形式 + 0x00 0x00 0x00 0x01 + PPS的解码形式 + 0x00 0x00 0x00 0x01 视频帧(IDR帧)
这样组成的一个buffer,FFMPEG的H264解码器才能成功解码。
问题已经解决,忘记结贴了。解决方案参考
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。

我要回帖

更多关于 ffmpeg 打开摄像头 的文章

 

随机推荐