【live555】OutPacketBuffer粗浅分析
来源:互联网 发布:人体工学椅 知乎 编辑:程序博客网 时间:2024/06/05 06:22
本文仅将OutPakcetBuffer作为一个独立个体分析,内涵外延都我没看,比如下面这句话,是sink用来输出一个packet用的,sink如何充分利用这个OutPacketBuffer的呢?
要关注 如何维护 fCurOffset 和 fPacketStart
// A data structure that a sink may use for an output packet:
class OutPacketBuffer {
public:
OutPacketBuffer(unsigned preferredPacketSize, unsigned maxPacketSize);
~OutPacketBuffer();
static unsigned maxSize; //静态的
unsigned char* curPtr() const {return &fBuf[fPacketStart + fCurOffset];} //当前指针,是要跳转到下一个包的起始位置么?
unsigned totalBytesAvailable() const {
return fLimit - (fPacketStart + fCurOffset); //减去当前的包之后的剩余空间大小?
}
unsigned totalBufferSize() const { return fLimit; }
unsigned char* packet() const {return&fBuf[fPacketStart];} //返回一个包,关键是维护fPacketStart这个变量,来确定包的起始位置。
unsigned curPacketSize() const {return fCurOffset;} //看起来,fCurOffset代表的是当前的包的字节长度。
void increment(unsigned numBytes) {fCurOffset += numBytes;}
void enqueue(unsigned char const* from, unsigned numBytes);
void enqueueWord(u_int32_t word);
void insert(unsigned char const* from, unsigned numBytes, unsigned toPosition);
void insertWord(u_int32_t word, unsigned toPosition);
void extract(unsigned char* to, unsigned numBytes, unsigned fromPosition);
u_int32_t extractWord(unsigned fromPosition);
void skipBytes(unsigned numBytes);
Boolean isPreferredSize() const {return fCurOffset >= fPreferred;}
Boolean wouldOverflow(unsigned numBytes) const {
return (fCurOffset+numBytes) > fMax; // fMax 是一个包最大的大小
}
unsigned numOverflowBytes(unsigned numBytes) const {
return (fCurOffset+numBytes) - fMax;
}
Boolean isTooBigForAPacket(unsigned numBytes) const { //对一个包来说,numBytes字节确实太大了。
return numBytes > fMax;
}
void setOverflowData(unsigned overflowDataOffset,
unsigned overflowDataSize,
struct timeval const& presentationTime,
unsigned durationInMicroseconds);
unsigned overflowDataSize() const {return fOverflowDataSize;}
struct timeval overflowPresentationTime() const {return fOverflowPresentationTime;}
unsigned overflowDurationInMicroseconds() const {return fOverflowDurationInMicroseconds;}
Boolean haveOverflowData() const {return fOverflowDataSize > 0;}
void useOverflowData();
void adjustPacketStart(unsigned numBytes);
void resetPacketStart();
void resetOffset() { fCurOffset = 0; }
void resetOverflowData() { fOverflowDataOffset = fOverflowDataSize = 0; }
private:
unsigned fPacketStart, fCurOffset, fPreferred, fMax, fLimit;
unsigned char* fBuf; //其实这个缓冲是一片连续的内存地址
unsigned fOverflowDataOffset, fOverflowDataSize;
struct timeval fOverflowPresentationTime;
unsigned fOverflowDurationInMicroseconds;
};
#endif
////////// OutPacketBuffer //////////
unsigned OutPacketBuffer::maxSize = 60000; // by default //静态的
OutPacketBuffer::OutPacketBuffer(unsigned preferredPacketSize,
unsigned maxPacketSize)
: fPreferred(preferredPacketSize), fMax(maxPacketSize),
fOverflowDataSize(0) {
unsigned maxNumPackets = (maxSize + (maxPacketSize-1))/maxPacketSize;
fLimit = maxNumPackets*maxPacketSize; //fLimit为包的个数*每个包最大的大小,如此看来,这个缓冲是多个包的一个缓冲。
fBuf = new unsigned char[fLimit]; //分配一块连续内存,是个字符数组啊,最大为fLimit字节。
resetPacketStart();
resetOffset();
resetOverflowData();
}
OutPacketBuffer::~OutPacketBuffer() {
delete[] fBuf; //释放new分配的数组内存,也没让fBuf为NULL啊???
}
void OutPacketBuffer::enqueue(unsigned char const* from, unsigned numBytes) {
if (numBytes > totalBytesAvailable()) {
#ifdef DEBUG
fprintf(stderr, "OutPacketBuffer::enqueue() warning: %d > %d\n", numBytes, totalBytesAvailable());
#endif
numBytes = totalBytesAvailable(); //新写入的数据,不可以超过剩余空间。
}
if (curPtr() != from) memmove(curPtr(), from, numBytes);
increment(numBytes);
}
void OutPacketBuffer::enqueueWord(u_int32_t word) {
u_int32_t nWord = htonl(word);
enqueue((unsigned char*)&nWord, 4);
}
void OutPacketBuffer::insert(unsigned char const* from, unsigned numBytes,
unsigned toPosition) {
unsigned realToPosition = fPacketStart+ toPosition;
if (realToPosition + numBytes > fLimit) { //从实际插入位置开始插入的numBytes个字节也不可以超过fLimit的限制
if (realToPosition > fLimit) return; // we can't do this
numBytes = fLimit - realToPosition; //如果超过,最多就只能写这么多
}
memmove(&fBuf[realToPosition], from, numBytes);
if (toPosition + numBytes > fCurOffset) {
fCurOffset = toPosition + numBytes;
}
}
void OutPacketBuffer::insertWord(u_int32_t word, unsigned toPosition) {
u_int32_t nWord = htonl(word);
insert((unsigned char*)&nWord, 4, toPosition);
}
//从某个位置,开始提取连续的某些个字节的数据出来?
void OutPacketBuffer::extract(unsigned char* to, unsigned numBytes,
unsigned fromPosition) {
unsigned realFromPosition = fPacketStart + fromPosition;
if (realFromPosition + numBytes > fLimit) { // sanity check 明智;头脑清楚;精神健全;通情达理
if (realFromPosition > fLimit) return; // we can't do this
numBytes = fLimit - realFromPosition; //如果要提取的字节数目不足,最多只能提取剩余的这些。
}
memmove(to, &fBuf[realFromPosition], numBytes);
}
u_int32_t OutPacketBuffer::extractWord(unsigned fromPosition) {
u_int32_t nWord;
extract((unsigned char*)&nWord, 4, fromPosition);
return ntohl(nWord); //网络变本地?
}
void OutPacketBuffer::skipBytes(unsigned numBytes) {
if (numBytes > totalBytesAvailable()) { //要跳过的字节数目超过了剩余可用空间,只能跳过这么多了。
numBytes = totalBytesAvailable();
}
increment(numBytes);
}
void OutPacketBuffer
::setOverflowData(unsigned overflowDataOffset,
unsigned overflowDataSize,
struct timeval const& presentationTime,
unsigned durationInMicroseconds) {
fOverflowDataOffset = overflowDataOffset;
fOverflowDataSize = overflowDataSize;
fOverflowPresentationTime = presentationTime; //这是干啥用的?
fOverflowDurationInMicroseconds = durationInMicroseconds;
}
void OutPacketBuffer::useOverflowData() {
enqueue(&fBuf[fPacketStart + fOverflowDataOffset], fOverflowDataSize);
fCurOffset -= fOverflowDataSize; // undoes increment performed by "enqueue"
resetOverflowData();
}
void OutPacketBuffer::adjustPacketStart(unsigned numBytes) {
fPacketStart += numBytes;
if (fOverflowDataOffset >= numBytes) {
fOverflowDataOffset -= numBytes;
} else {
fOverflowDataOffset = 0;
fOverflowDataSize = 0; // an error otherwise
}
}
void OutPacketBuffer::resetPacketStart() {
if (fOverflowDataSize > 0) {
fOverflowDataOffset += fPacketStart;
}
fPacketStart = 0;
}
- 【live555】OutPacketBuffer粗浅分析
- 【live555】FramedFilter粗浅分析
- 【live555】OnDemandServerMediaSubsession 粗浅分析
- live555 分析
- live555 分析
- list 、set 、map 粗浅性能对比分析
- list 、set 、map 粗浅性能对比分析
- 粗浅看 Tomcat系统架构分析
- 粗浅看 Tomcat系统架构分析
- 粗浅看 Tomcat中设计模式分析
- live555代码分析
- live555 源码分析
- live555 模块分析
- Live555 RTSPServer 分析
- live555 分析- openRtsp
- live555源代码分析
- 【live555】UsageEnvrionment分析
- 【live555】WISInput类分析
- TCP建链为何一定要三次握手?
- Note for Sybase
- Read-Only Tables in Oracle Database 11g
- sql server 存储过程和触发器
- 深入理解JVM内幕:从基本结构到Java 7新特性
- 【live555】OutPacketBuffer粗浅分析
- Oracle查询表空间使用大小,使用率,剩余大小,百分比
- 判断输入是否为日期类型
- 2014DNS事件始末
- Codeforces Round #225 (Div. 1) B. Volcanoes
- MD5加密字符串处理
- MySQL-5.6.13解压版(zip版)安装配置教程
- 统计字符串中的单词个数
- 过滤非法字符,防止注入式攻击等