移动端

流媒体服务器之视频缓冲区设计

2011年10月27日 11:49杭州锐虎科技有限公司点击量:257

流媒体服务器之视频缓冲区设计

一、为什么要设计这样的缓冲区
a)         为什么要设计缓冲区
流媒体服务器从前端获取视频流,为了达到分发的效果,则必须对每个要分发的视频通道建立一个缓冲区。这样每个分发的线程都可以从缓冲区里读取数据,分发到各个客户端。
客户端在播放时,为了避免数据流上来时的快慢或者过大等情况而引起跳帧等现象,则也需要对每个播放通道建立一个缓冲区。
可以看出,设计一个合理的缓冲区是有必要的。
b)        一般缓冲区的不足
传统的缓冲区是对每个通道建立一个有N个BUF的数组,每个BUF的大小都是固定的,一个BUF用于存储一帧的数据。假设N为100,BUF大小为20K。这样,每个通道的都需要占用2000K的内存。然而,不可能每帧数据都是20K,所以,在缓冲区中,视频数据不是连续存放的,这样存在着很大的内存浪费。而且,如果前端是高清设备,并且是变码流的情况下,则有时候20K根本不足以保存一帧的数据。所以,这时候,只能扩大BUF的大小。这样做了之后,对于正常的视频流,则是更大的浪费了内存占用。
c)        新版缓冲区的特点
新版缓冲区修改了传统缓冲区的不足之处。新版缓冲区为每个通道事先申请一块500K的内存(大小可变动,即每个通道只占用了500K的内存),每帧数据上来,则连续存放在申请来的内存中。这样,即可以充分的利用内存,也可以适应变码流的情况。
二、设计思想
a)    缓冲区结构
对于每个缓冲区,预先申请一个500K的内存,然后为其建立一个动态数组。数组是由结构体(见下面内容)组成。每个结构体记录:填充BUF的时间,BUF在内存中的地址,BUF的大小。
       b)    流程图
三、核心代码
a)    BUF结构体
typedef struct tagSENDBUF
{ long                buffertime;            //记录数据的时间
    LPBYTE            sendbuf;                        //记录数据的起始地址
    unsigned long          buflength;                     //记录数据的长度
}SENDBUF,*pSendBuf;
b)        通道单元的成员变量
LPBYTE             m_DataBufCache;                //缓冲区指针
CArray<SENDBUF,SENDBUF&> m_data_buffer;     //动态数组
LPBYTE                       m_NowBufCache;                //内存地址,当前写到哪了
int                                m_Valid_pos;         //有效位置。超过这个位置为无效数据;
int                                m_BufCount;         //数组的个数
int                       m_read_pos;          //记录数组中,该从第几个开始写
c)        填充缓冲区代码
MULTIBUFSIZE是个常量,指申请内存的大小。
if ((m_NowBufCache-m_DataBufCache)+dwBufSize>MULTIBUFSIZE)
              {
                     //////////////////////////////////////
//把m_read_pos置为0
                     //////////////////////////////////////
              }
              //如果m_BufCount<m_read_pos+1,则需要动态建一个SENDBUF
              //,记录要记录的信息,并加入到数组中
              if (m_BufCount<m_read_pos+1)
              {
                     SENDBUF _sendbuf;
                     //////////////////////////////////////
//记录要记录的信息/
                     //////////////////////////////////////
                     m_data_buffer.Add(_sendbuf);
                     m_BufCount=m_read_pos+1;
              }
              else  
              {
                     /////////////////////////////////////////////
                     //取出m_data_buffer[m_read_pos],
//然后修改其中的内容
                     /////////////////////////////////////////////
              }                  
        m_read_pos++;   //把数组写位置指向下一个位置
四、具体应用
使用缓冲区:
m_Binding_Channel是指绑定的一个数据流通道。
m_write_pos是指读通道数组里的第几个SENDBUF。
 
//如果超过有效位置,则从第0个开始读
if (m_write_pos>m_Binding_Channel->m_Valid_pos)
{
m_write_pos=0;
}
      
//检验m_Binding_Channel->m_data_buffer[m_write_pos]里数据的合法性
//比如时间,BUG大小等是否符合要求
    
然后就可以使用m_Binding_Channel->m_data_buffer[m_write_pos]里面记录的信息了。
 
  锐虎科技   研发部
        锐虎科技,专注安防监控平台软件设计
 
 
版权与免责声明: 凡本网注明“来源:智慧城市网”的所有作品,均为浙江兴旺宝明通网络有限公司-智慧城市网合法拥有版权或有权使用的作品,未经本网授权不得转载、摘编或利用其它方式使用上述作品。已经本网授权使用作品的,应在授权范围内使用,并注明“来源:智慧城市网www.afzhan.com”。违反上述声明者,本网将追究其相关法律责任。

本网转载并注明自其它来源(非智慧城市网www.afzhan.com)的作品,目的在于传递更多信息,并不代表本网赞同其观点或和对其真实性负责,不承担此类作品侵权行为的直接责任及连带责任。其他媒体、网站或个人从本网转载时,必须保留本网注明的作品第一来源,并自负版权等法律责任。

编辑精选

更多

本站精选

更多

视频直击

更多

专题推荐

更多

名企推荐

更多

浙公网安备 33010602000006号