利用VC++实现局域网实时视频传输
2010-07-06 20:43:44 来源:WEB开发网3、视频帧的接收
接收端最重要的是从接受的数据流中提取出完整的一帧。方法的思想是:首先从数据流中寻找帧开始标志,再从紧挨后面的数据中提取出帧的大小,然后再从接收缓冲区中读入该帧剩余的数据。再寻找下一帧的开始标志,如此往复。图4是接收端的工作流程。
同样接收端创建一个线程专门用来执行数据接收。不妨假设线程名为recThread,核心代码实现如下:
while(temp!=SOCKET_ERROR)
{
if(!isStart) {//帧数据是否开始,true表示开始
if(endNum>3) //endNum纪录当前接收未处理的数据
endNum=0;
temp=recv(clisock,(char*)(recBuf+endNum),1000,0);//从缓冲区读取数据
startPos=serchStr(temp+endNum); //查找帧开始标志
if(startPos!=-1) {
isStart=true;
endNum=temp+endNum-startPos-4;
memcpy(imageBuf,recBuf+startPos+4,endNum); //保存帧数据
}
else{
memcpy(recBuf,recBuf+temp+endNum-3,3);//保存最后三个字节的数据
endNum=3;
}
}
else{
if(endNum<4) {//判定紧跟开始标志的数据,如果小于4表示不能获得帧大小
temp=recv(clisock,(char*)(recBuf),1000,0); //读入数据
memcpy(imageBuf+endNum,recBuf,temp);//保存数据
endNum+=temp;
if(endNum<4)
continue;
frameSize= *((int*)imageBuf);//获得帧大小
if(frameSize<500 || frameSize>50000) {//异常处理(帧大小非法)
isStart = false; //丢弃数据重新查找帧开始标志
endNum = 0;
continue;
}
frameSize-=endNum+4;
}
else{
while(frameSize>0&&temp!=SOCKET_ERROR) {//获得完整帧的剩余数据
temp=recv(clisock,(char*)(imageBuf+endNum),frameSize,0);
endNum+=temp;
frameSize-=temp;
}
if(frameSize<=0) {//帧结束置位,解压
isStart=false;
endNum=0;
deCompress();//判断数据的有效性,调用ICDecompress进行解压
}
}
}
}
以上程序执行的结果是将完整的一帧(除帧开始标志)保存在imageBuf中。
更多精彩
赞助商链接