Loop buffer, 主要是获取到的播放数据进行缓存。对于HLS播放器的播放数据的处理有比较多的处理模式,如映射文件、LoopBuffer、切片存储等。就要看具体需要了。
现在来看这是我自定的LoopBuffer类
class CLoopBuffer
{
private:
CRITICAL_SECTION m_mutex;
__int64 m_iBufferSize; /*当前数据管理缓冲区的大小 */
__int64 m_iVaildLength; /*当前数据缓冲区中有效数据长度*/
unsigned char *m_pBuffer;
unsigned char *m_pBufTail;
unsigned char *m_pCurRead;
unsigned char *m_pCurWrite;
bool m_bInterrupt;
HANDLE hMutex;
bool m_downloadEnd_flag;
bool m_isRead; // 阅读判断符
bool m_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、__int64CLoopBuffer::_buffer_read(unsigned char* pData, __int64 iDataLen, bool bForceEnough) 读取LoopBuffer缓存数据函数
入参分析:
unsigned char* pData :待填充的Buffer
_int64 iDataLen : 需要存储的数据大小
boolbForceEnough:是否满填充,true 表示必须填充iDataLen大小的数据,false 反之
分析:
1、设定可提供的数据量。如果bForceEnough = true,则表示满数据量填充。不足则需要等待
2、拷贝数据到pData中。如果m_pCurRead到m_pBufTail的数据量小于可读取量,则需要取到尾部数据,和头部到剩余大小的数据。
注意: 等待数据足够时,小心死循环了。其中应该有强制退出标记。
__int64 CLoopBuffer::_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循环,特别关照它呀!
分享到:
相关推荐
WEB中的PC浏览器的HLS播放器。
里面有rtmp、hls 播放器及相关代码。
ckplayer播放插件
HLS Flash 播放器
http://网站nginx代理的路径/?m3u8=hls的播放地址 把本html放在nginx代理中,把其他地方获取到的hls播放地址,直接当做url传参给本HTML即可
Flash 播放器的插件支持HLS播放
html5播放器,srs 使用nginx反向代理解决chrome播放HLS的跨域问题
JS 实现的 HLS 格式播放器.zip,使用媒体源扩展的javascript hls客户端
HTML5播放m3u8(hls)格式视频以及播放直播m3u8(hls)视频完整代码,Chrome + Firefox
videojs支持hls播放
简单的实现了exoplayer的集成,和测试播放dash流、hls流。文章:https://blog.csdn.net/u012560369/article/details/80417191
内含视频服务器图文设置,以及html示例。浏览器上实现播放hls视频
网上找了很多videojs 都是各种问题,而且积分特别高,自己整理了一下。测试可用,支持 rtmp 拉流h5自带的视频拉流播放器原生态
Vivado HLS关于图像处理的数据手册。内有相关函数介绍。
hls.js是一个JavaScript库,可实现...WWDC2016期间宣布,hls.js还支持HLS + fmp4hls.js不需要任何播放器,它可以直接在标准HTML <video>元素上运行。hls.js用ECMAScript6编写,并使用Babel在ECMAScript5中转译。
HLS-demo一个简单的HLS视频播放例子,使用了MediaElement.js。
uniapp npm引入Dplayer与hls解析播放m3u8格式视频
1、本文详细描述了html采用video播放hls视频流的方法及源代码。 2、通过详细示例,让读者更直观地阅读,更清晰的理解。 3、示例代码可直接复制,编译后可直接运行。 4、根据示例以及运行结果,让读者加强记忆及...
HLS(m3u8)web页面和手机播放案例。 1.HLS视频服务器需要配置可跨域文件(crossdomain.xml) 可参考https://www.jianshu.com/p/59a5d22a24c6 2.项目需要用tomcat或iis等服务器加载 3.讲index.html中的视频地址换成...
代码来源自网络,如有侵权请联系删除