花屏和丢帧问题解决思路

IP摄像头播放
Uestc Computer
编者的话作文对外贸易增长的原因
当前版本
V1.0
密级
文档编号
总页数
正文页数
附录页数
编制人
张占忠
评审人
鲁晓军
批准人
编制日期
2015.06.27
评审日期
批准日期
修改履历
海布圣地城外语与外语教学
序号
状态
版本
修改内容
修改位置
修改人
日期
评审人
日期
批准人
日期
1
M
1.0
全文完成
张占忠
2015/06/27
2
3
4
5
6
7
评阅意见
结题报告
状态:C—创建文档,A—增加内容,M—修改内容,D—删除内容
cusa                        摄像头问题总结
本次做摄像头监控主要遇到的问题有2个。
1:丢帧问题。协议采用的是基于rtp的Udp协议。
2:花屏问题。
丢帧问题解决思路:
1:采取双线程机制。
    如果接收和解码在一个线程中,那么会遇到一个问题就是如果解码一个较大的帧,这时发送端发送2个较小的帧。这时就只能保存一个帧,从而出现丢帧的问题。
:2:发送端采取双线程增加缓冲区机制。
    缓冲区采用循环队列的方式。
    一个进程往缓冲区里面放数据,一个进程从缓冲区里面取数据并解码。
    具体实现参考接收端缓冲区。
3:接收端采取双线程增加缓冲区机制。
    缓冲区采用循环队列的方式。
    一个进程往缓冲区里面放数据,一个进程从缓冲区里面取数据并解码。
    每次接收到的rtp数据包为一帧H264数据。(注意,由于一些帧太大,可能会将帧分成若干包,我们需要将包重组为帧。)
设我们得到的一帧数据长度为vsize,得到的数据保存在vdata中。开辟一个全局数组作为缓冲区。假设缓冲区数组为BufQue。我们需要在数组中保存的内容为数据长度vsize和vdata。由于H264数据以字节为单位而vsize为int型,占据4个字节,需要采取一定措施将int型转化为4个字节。方法如下:
        BufQue[head] = numcount & 0xff;//FirstBit;
            head = (head+1)%BUF_SZIE;
            BufQue[head] = (numcount>>8) & 0xff;//SecondBit;
            head = (head+1)%BUF_SZIE;
            BufQue[head] =(numcount>>16) & 0xff;
            head = (head+1)%BUF_SZIE;
            BufQue[head] = (numcount>>24) & 0xff;
            head = (head+1)%BUF_SZIE;
BUF_SZIE为缓冲区的大小。切记:由于缓冲区为循环队列,因此必须有求余操作。
检查缓冲区代码是否正确与是否丢帧的思路:
    缓冲区代码写好以后并不能立即确定缓冲区代码是否正确,并且由于是一帧帧的得到数据,用单步调试太过复杂繁琐并且一不错就得重新调试,并且由于码流在不停发送并不能
确定是否丢帧。解决办法就是将调试信息写到文件中去。
解决思路:
First :发送端发送数据是发送一个时间戳,也就是帧发送的顺序。接受端接受到的数据也有一个时间戳,如果接收端接收到的时间戳不连续,即是丢帧。
Second:接收端接受到数据以后在将数据写入缓冲区以前将H264码流保存到文件中设该文件为RecH264.h264.
Third :将从缓冲区里面读出来的数据也保存到文件中。设该文件为DecBuf.h264
Forth:用VLC播放器播放RecH264.h264.,如果没有花屏则证明接收到的数据无误。如果播放RecH264.h264.不花屏而播放DecBuf.h264花屏说明缓冲区代码错误。
Fifth:如果用VLC播放器播放RecH264.h264花屏,检查数据是否发送和发送的每一帧数据是都正确。
注意:如果写文件的时候以a+,ab+,w+等方式打开文件,在写文件的时候会自动将0A转
化为0D0A,这时就算发送端发送数据无误,写文件的时候也会出错。解决方式很简单。以wb+方式打开文件,这样0A就不会转化为0D0A了。
花屏问题解决思路:
1:检查解码方式是否正确。
    遇到花屏问题首先考虑的是是否丢帧。而丢帧问题的解决办法为增加缓冲区。增加缓冲区以后,如果还是出现花屏,这时候解决问题主要从以下方面着手。
第一:检查缓冲区,方法如上。
第二:解码是否正确。无论是采用FFmpeg解码还是用海思解码还是别的方式解码,必须确定解码是都正确。验证解码是否正确的方式如下:
将解码以后的YUV数据保存,可以自己编写YUV文件播放器也可以用现有软件播放。当然也可以将现有的YUV数据转码成RGB数据进行播放。如果此时不能正常播放则说明是解码出错。
2:针对缓冲区的访问机制。(事件遇到问题,信号量可以完美解决缓冲区互斥访问的问题)
    对于缓冲区我们必须保持互斥访问,然而互斥访问就有一个问题那就是读和写会占据一定的时间,不能同时访问。不用mutex那么采用event会怎么样呢?会缓冲区爆掉,原因也很简单,因为如果解码一个很大的帧,解码需要花相当多的时间,这是同时到来2个event,然而传给解码进程的只有后面一个event,也就是说缓冲区里面有一帧数据没有进行解码,这样越积累愈多,缓冲区就会爆掉。
信号量semaphor可以完美解决以上问题。每往缓冲区里面存一个数据,semaphor就加1.每取一个数据semaphor就减一,只要有数据取进程就可以一直取,没有数据,那么取数据进程就阻塞等待,这样可以解决有的数据没有取走的问题。
3:SDL显示的控制。(每一帧应该怎么播放)
  SDL显示的时候如果用SDL_delay()函数,不是说不行,而是相对不好,因为每帧的解码时间不确定,delay时间不好确定,并且如果帧率改变的话delay的时间就需要重新修改。
怎么控制SDL显示呢?可以采取事件或信号量机制。每解码一帧就发送一个事件或信号量,然后SDL就显示一帧图像。如果没有事件或信号量到来,SDL就显示上一幅图像直到下幅解码图像的到来!

本文发布于:2024-09-23 11:23:14,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/256515.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:缓冲区   数据   解码   文件   问题   发送   是否
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议