AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > VC编程

利用VC++实现局域网实时视频传输

51自学网 2015-08-30 http://www.wanshiok.com

  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中。

  4、“停等”控制策略

  如果局域网通信速率很高,而且工作稳定,则按照以上说的方法进行实时视频传输,不需要任何控制策略,就可以达到非常好的效果。但是在很多情况下,网络会出现异常,这样会导致数据传输率明显下降,造成发送端数据积压,等待发送的数据不能正常发出去。此时就要采取一定的策略来控制发送端,以达到实时性的要求。

  上文发送程序中,变量isOK是用来表示发送端当前帧有没有发完,如果发完则置为true,同时也表示发送端准备就绪,可以继续发送数据,否则为false。那么可以用isOK来通知视频采集和压缩线程,如果isOK为true,则可以采集视频并且压缩,然后唤醒发送线程继续发送新来的帧数据,否则一直等待,直到网络可以继续发送数据(isOK为true)。当然,视频采集一直不停的进行,那么当网络发生数据堵塞时,只要不让编码器进行压缩则可解决;当网络恢复正常时,继续进行压缩传输,换句话说,当网络发生堵塞时,直接抛弃等待发送的帧,保证一旦网络恢复时,发送最新的压缩帧。当然要保证一旦有一帧开始发送,就要将其完全发出。

  按照这样的“停等”策略进行实时视频传输,只会带来一个问题:当网络质量差时,接收端画面中的移动目标会出现瞬间移动的现象。但是这种策略会保证不会出现重影,抖动,花屏等现象。

  结论

  本文提出的实时视频传输方案在100M的局域网、10M局域网和11M无线局域网中进行了测试。测试时让一个目标在镜头前(发送端)移动,观察接收端视频的显示。在不同的局域网中进行了多次测试,每次测试时间从10分钟到30分钟不等,并且改变目标的运动速度进行实验。最后将数据汇总,得出统计结果。测试结果如表1所示。

  表1 不同局域网下的测试结果



剧烈运动

正常运动

缓慢运动

100M局域网

图像清晰,很流畅

图像清晰,很流畅

图像清晰,很流畅

10M局域网

偶尔出现停顿,丢帧率1%左右

图像清晰,人眼感觉流畅

图像清晰,很流畅

11M无线局域网

经常出现停顿,丢帧率5%-6%

经常出现停顿,丢帧率2%-3%

偶尔出现停顿,丢帧率1%左右


  其中,

  注:11M无线网卡是通过USB1.0接口和PC机连接的,如果采用USB2.0接口效果会更好。

  从实际测试的结果看,效果是良好的,除了出现瞬间移动外,图像能够保持清晰,消除了由于网络质量差而导致的重影、抖动等现象,对于不同的局域网都能满足实时传输的要求。

 
 
说明
:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。

上一篇:简单SNMP管理程序的VC++代码实例实现  下一篇:Visual&nbsp;C++程序调试方法入门