(HLS播放器之三)播放数据缓存机制之环形buffer
来源:互联网 发布:出国留学数据统计 编辑:程序博客网 时间:2024/05/22 13:14
Loop buffer, 主要是获取到的播放数据进行缓存。对于HLS播放器的播放数据的处理有比较多的处理模式,如映射文件、LoopBuffer、切片存储等。就要看具体需要了。
现在来看这是我自定的LoopBuffer类
class CLoopBuffer{private:CRITICAL_SECTIONm_mutex;__int64m_iBufferSize;/*当前数据管理缓冲区的大小 */__int64m_iVaildLength;/*当前数据缓冲区中有效数据长度*/unsigned char *m_pBuffer;unsigned char*m_pBufTail;unsigned char*m_pCurRead;unsigned char*m_pCurWrite;boolm_bInterrupt;HANDLEhMutex;boolm_downloadEnd_flag;boolm_isRead;// 阅读判断符boolm_isStop;// 强制终止标记public:CLoopBuffer(__int64 iBufferSize);~CLoopBuffer();__int64_buffer_read(unsigned char* pData, __int64 iDataLen, bool bForceEnough);void_buffer_write(unsigned char* pData, __int64 iDataLen);void_buffer_interrupt();void_buffer_reset();void_buffer_reset_readBegin();__int64 _buffer_getVaildLength();//获取剩余量void_buffer_setReadPos(__int64 pos); //设置播放位置__int64 _buffer_readLength();void_buffer_stopRead(); //停止读取工作};
其中最重要就是标记位置的四个指针:
m_pBuffer: 缓存的头指针
m_pBufTail: 缓存的尾指针
m_pCurRead: 读取位置指针
m_pCurWrite: 写入位置指针
现在针对特殊的几个函数进行分析:
1、__int64 CLoopBuffer::_buffer_read(unsigned char* pData, __int64 iDataLen, bool bForceEnough) 读取LoopBuffer缓存数据函数
入参分析:
unsigned char* pData :待填充的Buffer
_int64 iDataLen : 需要存储的数据大小
bool bForceEnough: 是否满填充,true 表示必须填充iDataLen大小的数据,false 反之
分析:
1、设定可提供的数据量。如果bForceEnough = true,则表示满数据量填充。不足则需要等待
2、拷贝数据到pData中。如果m_pCurRead到m_pBufTail的数据量小于可读取量,则需要取到尾部数据,和头部到剩余大小的数据。
注意: 等待数据足够时,小心死循环了。其中应该有强制退出标记。
__int64CLoopBuffer::_buffer_read(unsigned char* pData, __int64 iDataLen, bool bForceEnough){if (NULL == m_pBuffer){return 0;}__int64 iActualReadLen = iDataLen;__int64 iCurrToEndLen = 0;//1、得到需要提供的数据的长度if(true == bForceEnough){//必须等待有足够的数据可读while(m_iVaildLength < iDataLen){......Sleep(50);}}else{// 能满足条件尽量满足条件,不满足条件时有多少数据读多少数据if(m_iVaildLength < iDataLen){iActualReadLen = m_iVaildLength;}}WaitForSingleObject(hMutex, 1L); //2、根据实际情况Copy数据//得到当前位置距离队列尾的长度iCurrToEndLen = (__int64)(m_pBufTail - m_pCurRead);if(iCurrToEndLen >= iActualReadLen){//如果剩余长度足够,则直接copy并返回memcpy(pData,m_pCurRead, iActualReadLen);m_pCurRead += iActualReadLen;}else{//Step 1:有多少读多少memcpy(pData, m_pCurRead, iCurrToEndLen);//Step 2:移动到头部继续读剩余的数据memcpy(pData+iCurrToEndLen, m_pBuffer, iActualReadLen-iCurrToEndLen);m_pCurRead = m_pBuffer + (iActualReadLen - iCurrToEndLen);}//3、减少当前Buf的长度EnterCriticalSection(&m_mutex);m_iVaildLength -= iActualReadLen;LeaveCriticalSection(&m_mutex);return iActualReadLen;}
2、void CLoopBuffer::_buffer_write(unsigned char* pData, __int64 iDataLen) 写入数据到Loop buffer中
不细说了,和读取有些道理相通的。
void CLoopBuffer::_buffer_write(unsigned char* pData, __int64 iDataLen){__int64 iActualWriteLen = iDataLen;__int64 iCurrToEndLen = 0;//判断写入数据长度有效性if(iActualWriteLen > m_iBufferSize){return;}//等待有足够空间可用于写数据while( (m_iBufferSize - m_iVaildLength) < iDataLen){.....Sleep(100);}//将数据Copy到Buffer中iCurrToEndLen = (__int64)(m_pBufTail - m_pCurWrite); if(iCurrToEndLen >= iDataLen ){//如果剩余长度足够,则直接copy并返回memcpy(m_pCurWrite, pData, iDataLen);m_pCurWrite += iDataLen;}else{//Step 1:能填充多少数据先填充多少数据memcpy(m_pCurWrite, pData, iCurrToEndLen);//Step 2:移动到头部继续填充剩余的数据memcpy(m_pBuffer, pData+iCurrToEndLen, iDataLen-iCurrToEndLen);m_pCurWrite = m_pBuffer + (iDataLen-iCurrToEndLen);}//增加当前buf的长度EnterCriticalSection(&m_mutex);m_iVaildLength += iDataLen;LeaveCriticalSection(&m_mutex);}
其他的函数只要起到控制功能、清空数据等处理。
大家一定要注意别出现死循环了。其中有一些While循环,特别关照它呀!
- (HLS播放器之三)播放数据缓存机制之环形buffer
- (HLS播放器之一)HLS协议之M3U8解析
- (HLS播放器之一)HLS协议之M3U8解析
- (HLS播放器之一)HLS协议之M3U8解析
- (HLS播放器之二)HTTP数据下载之libcurl 基本使用
- Js网络视频播放器之VideoJs&&ckplayer(直播拉流rtmp、hls)
- Js网络视频播放器之VideoJs&&ckplayer(直播拉流rtmp、hls)
- HLS播放器开发
- FLASH HLS 播放器
- 音乐播放器之源码解析三
- HLS播放器开发难点
- HTML5环形音乐播放器
- Android视频播放之边缓存边播放
- Android视频播放之边缓存边播放
- Android开发之第一个小项目--我的MP3播放器之播放界面的实现(三)
- 星之播放器
- IOS之播放器
- android之播放器
- httpWatch 使用介绍
- 关于myeclipse怎么开启XML文件的自动编译
- Android SQL多表检索
- WebService 环境搭建
- 7阶乘尾数零的个数
- (HLS播放器之三)播放数据缓存机制之环形buffer
- 详解asp.net在ISAPI_rewrite 中实现伪静态的方法
- Flot 是一个很棒的 jQuery 绘图插件
- LoadRunner如何在IE7+Win2003环境下录制脚本
- autoresizingMask ,, UIViewAutoresizingFlexibleWidth
- 套合子(典型的匈牙利算法)
- 对于TextView 设置 Ellipsize ="End" 无效时的解决方法
- 分布式java应用学习笔记三
- 一个简单的MSMQ的发送和接收类