Android 循环缓冲区
来源:互联网 发布:node 调用shell 编辑:程序博客网 时间:2024/05/29 08:37
由于需要将接受到的视频编码数据取出每一帧,需要用到循环缓冲区。在网上找了个c++版,改成了java版。
public class CirCleBufer {
private static boolean bEmpty = true;
private static boolean bFull = false;
private static int nBufSize = 1024*128;
private static byte[] pBuf = new byte[nBufSize] ;
private static int nReadPos = 0;
private static int nWritePos = 0 ;
/*
* 函数介绍 向缓冲区写入数据,返回实际写入的字节数
*/
public static int write(byte[] buf, int count)
{
if(count <= 0)
return 0;
bEmpty = false;
// 缓冲区已满,不能继续写入
if(bFull)
{
return 0;
}
else if(nReadPos == nWritePos) // 缓冲区为空时
{
/* == 内存模型 ==
(empty) m_nReadPos (empty)
|----------------------------------|-----------------------------------------|
m_nWritePos m_nBufSize
*/
int leftcount = nBufSize - nWritePos;
if(leftcount > count)
{
System.arraycopy(buf,0,pBuf,nWritePos,count);
nWritePos += count;
bFull = (nWritePos == nReadPos);
return count;
}
else
{
System.arraycopy(buf,0,pBuf,nWritePos,leftcount);
nWritePos = (nReadPos > count - leftcount) ? count - leftcount : nWritePos;
System.arraycopy(buf,leftcount,pBuf,0,nWritePos);
bFull = (nWritePos == nReadPos);
return leftcount + nWritePos;
}
}
else if(nReadPos < nWritePos) // 有剩余空间可写入
{
/* == 内存模型 ==
(empty) (data) (empty)
|-------------------|----------------------------|---------------------------|
m_nReadPos m_nWritePos (leftcount)
*/
// 剩余缓冲区大小(从写入位置到缓冲区尾)
int leftcount = nBufSize - nWritePos;
if(leftcount > count) // 有足够的剩余空间存放
{
System.arraycopy(buf,0,pBuf,nWritePos,count);
nWritePos += count;
bFull = (nReadPos == nWritePos);
return count;
}
else // 剩余空间不足
{
// 先填充满剩余空间,再回头找空间存放
System.arraycopy(buf,0,pBuf,nWritePos,leftcount);
nWritePos = (nReadPos >= count - leftcount) ? count - leftcount : nReadPos;
System.arraycopy(buf,leftcount,pBuf,0,nWritePos);
bFull = (nReadPos == nWritePos);
return leftcount + nWritePos;
}
}
else
{
/* == 内存模型 ==
(unread) (read) (unread)
|-------------------|----------------------------|---------------------------|
m_nWritePos (leftcount) m_nReadPos
*/
int leftcount = nReadPos - nWritePos;
if(leftcount > count)
{
// 有足够的剩余空间存放
System.arraycopy(buf,0,pBuf,nWritePos,count);
nWritePos += count;
bFull = (nReadPos == nWritePos);
return count;
}
else
{
// 剩余空间不足时要丢弃后面的数据
System.arraycopy(buf,0,pBuf,nWritePos,leftcount);
nWritePos += leftcount;
bFull = (nReadPos == nWritePos);
return leftcount;
}
}
}
/*
* 函数介绍 从缓冲区读数据,返回实际读取的字节数
*/
public static int read(byte[] buf, int count)
{
if(count <= 0)
return 0;
bFull = false;
if(bEmpty) // 缓冲区空,不能继续读取数据
{
return 0;
}
else if(nReadPos == nWritePos) // 缓冲区满时
{
/* == 内存模型 ==
(data) m_nReadPos (data)
|--------------------------------|--------------------------------------------|
m_nWritePos m_nBufSize
*/
int leftcount = nBufSize - nReadPos;
if(leftcount > count)
{
System.arraycopy(pBuf,nReadPos,buf,0,count);
nReadPos += count;
bEmpty = (nReadPos == nWritePos);
return count;
}
else
{
System.arraycopy(pBuf,nReadPos,buf,0,count);
nReadPos = (nWritePos > count - leftcount) ? count - leftcount : nWritePos;
System.arraycopy(pBuf,0,buf,leftcount,nReadPos);
bEmpty = (nReadPos == nWritePos);
return leftcount + nReadPos;
}
}
else if(nReadPos < nWritePos) // 写指针在前(未读数据是连接的)
{
/* == 内存模型 ==
(read) (unread) (read)
|-------------------|----------------------------|---------------------------|
m_nReadPos m_nWritePos m_nBufSize
*/
int leftcount = nWritePos - nReadPos;
int c = (leftcount > count) ? count : leftcount;
System.arraycopy(pBuf,nReadPos,buf,0,c);
nReadPos += c;
bEmpty = (nReadPos == nWritePos);
return c;
}
else // 读指针在前(未读数据可能是不连接的)
{
/* == 内存模型 ==
(unread) (read) (unread)
|-------------------|----------------------------|---------------------------|
m_nWritePos m_nReadPos m_nBufSize
*/
int leftcount = nBufSize - nReadPos;
if(leftcount > count) // 未读缓冲区够大,直接读取数据
{
System.arraycopy(pBuf,nReadPos,buf,0,count);
nReadPos += count;
bEmpty = (nReadPos == nWritePos);
return count;
}
else // 未读缓冲区不足,需回到缓冲区头开始读
{
System.arraycopy(pBuf,nReadPos,buf,0,leftcount);
nReadPos = (nWritePos >= count - leftcount) ? count - leftcount : nWritePos;
System.arraycopy(pBuf,0,buf,leftcount,nReadPos);
bEmpty = (nReadPos == nWritePos);
return leftcount + nReadPos;
}
}
}
public static boolean isFull()
{
return bFull;
}
public static boolean isEmpty()
{
return bEmpty;
}
public static void setEmpty()
{
nReadPos = 0;
nWritePos = 0;
bEmpty = true;
bFull = false;
}
/**
* 获取缓冲区有效数据长度
*/
public static int getUsedSize()
{
if(bEmpty)
{
return 0;
}
else if(bFull)
{
return nBufSize;
}
else if(nReadPos < nWritePos)
{
return nWritePos - nReadPos;
}
else
{
return nBufSize - nReadPos + nWritePos;
}
}
/**
* 获取缓冲区空闲空间数据长度
*/
public static int getFreeSize()
{
if(bEmpty)
{
return nBufSize;
}
else if(bFull)
{
return 0;
}
else if(nReadPos > nWritePos)
{
return nReadPos - nWritePos;
}
else
{
return nBufSize - nWritePos + nReadPos;
}
}
}
c++版原文地址 http://blog.csdn.net/favormm/article/details/5258697 。
- Android 循环缓冲区
- 循环缓冲区
- 循环缓冲区
- 循环缓冲区
- 循环缓冲区类
- 键盘输入循环缓冲区问题
- 队列实现循环缓冲区
- 循环缓冲区的定义
- boost 循环缓冲区
- Linux中的循环缓冲区
- 队列实现循环缓冲区
- C++版循环缓冲区类
- 循环缓冲区的一点笔记
- Linux内核中的循环缓冲区
- Linux内核中的循环缓冲区
- linux内核中的循环缓冲区
- 循环缓冲区(数据块)
- 串口实用的循环缓冲区
- 自动化实现本地化工具genstrings
- 上传文件并目录打散
- JQuery学习笔记(三)——animate() 方法
- MSP430F149内部Flash操作
- android 自动化测试Monkeyrunner
- Android 循环缓冲区
- vs2013的一些设置问题
- 4.5英寸屏怎么比4.7英寸还大
- Analysis on “Container With Most Water ”
- Mongodb启动命令mongod参数说明
- JavaScript学习十三棵--错误
- 分组统计文本信息
- SQLSERVER-存储过程-事务-小结
- iOS:适配iPad的横屏