UPNPServer 说明文档
作者:梁锦明 日期:2008-2-16
 
一、利用vfw来实现捕捉摄相头数据:
1. 建立视频预览窗口 hWndVideo = capCreateCaptureWindow(………)
2. 枚举pc中所安装的摄相头
While (1)
{
If (capGetDriverDescription(iTotalDevice, szDeviceName, sizeof(szDeviceName), szDeviceVersion , sizeof(szDeviceVersion)))
{
++iTotalDevice;
}
Else
Break;
}
3.连接摄相头
SendMessage(hWndVideo, WM_CAP_DRIVER_CONNECT, index, 0L); //index为第二步中枚举pc中所安装的摄相头的索引值, 0为第一个, 1为第二个,依次类推。
SendMessage(hWndVideo, WM_CAP_DRIVER_GET_CAPS, sizeof(CAPDRIVERCAPS), (long) (LPVOID)&CapDrvCaps);
//取得设备的描述
capPreviewRate(hWndVideo, rate); //设置预览的速率,默认为25帧每秒, 1000/25 = 40 , 所以rate为40
capPreview(hWndVideo, true); //true 为预览, false为不预览
capPreviewScale(hWndVideo, true); // If scaling is enabled, the captured video frame is stretched to the dimensions of the capture window.
设置捕获数据的回调函数,当摄相头捕获数据后操作系统会自动调用该函数
capSetCallbackOnFrame(hWndVideo, FrameCallbackProc);
4.改变摄相头的参数
(1)改变视频源的属性
      If (CapDrvCaps.fHasDlgVideoSource)
          capDlgVideoSource(hWndVideo)
(2) 改变视频源的格式
     If (CapDrvCaps.fHasDlgVideoFormat)
         capDlgVideoFormat(hWndVideo) ;
(3) 检查驱动器是否有叠加功能,有则起用
     If (CapDrvCaps.fHasOverlay)
         capOverlay(hWndVideo, TRUE);
5.停止捕获
capPreview(hWndVideo, false);
capDriverDisconnect(hWndVideo);
    
二、数据压缩
 1.压缩初始化
gCompressBitIn.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// 取得摄相头所输出的每一帧位图的格式
     capGetVideoFormat(hWndVideo, &gCompressBitIn, sizeof(BITMAPINFO));
     ZeroMemory(&gCompvar,sizeof(gCompvar)); 
     gCompvar.cbSize = sizeof(gCompvar);  
     gCompvar.dwFlags = ICMF_COMPVARS_VALID;  
     gCompvar.cbState = 0;  
     gCompvar.fccHandler = mmioFOURCC('D','i','v','x');//利用divx压缩器来压缩
     gCompvar.fccType = ICTYPE_VIDEO;  
     //打开解码器
     gCompressHic = ICOpen(gCompvar.fccType,gCompvar.fccHandler,ICMODE_FASTCOMPRESS);
     if (gCompressHic)
     {
         DWORD dwSize = ICCompressGetFormatSize(gCompressHic, &gCompressBitIn);
         gCompressBitOut.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
          // 取得压缩后的位图格式
         if (ICERR_OK == ICCompressGetFormat(gCompressHic, &gCompressBitIn, CompressBitOut))
         {
              gCompvar.hic = gCompressHic;
              gCompressBitOut.bmiHeader.biCompression = gCompvar.fccHandler;
              //启动压缩器
              ICSeqCompressFrameStart(&gCompvar, &gCompressBitIn))
   }
     }
3. 利用ICSeqCompressFrame来压缩每一帧数据
4. 停止压缩
ICSeqCompressFrameEnd(&gCompvar) ; //
ICCompressorFree(&gCompvar);        //释放资源
ICClose(gCompressHic);
三、建立用来传输的服务器
1.建立服务器
    wVersion = MAKEWORD(2.2);
    WSAStartup(mVersion, &wsaData);
    gCapServerSocket = socket(PF_INET, SOCK_STREAM, 0)//创建TCP Socket
    WSAAsyncSelect(gCapServerSocket, hWndMain, WM_CAPTURESERVER, FD_ACCEPT | FD_READ);
    gServerAddr.sin_family = AF_INET;
    gServerAddr.sin_port = htons(TRANST_PORT);
    gServerAddr.sin_addr.S_un.S_addr = INADDR_ANY;
    bind(gCapServerSocket, (struct sockaddr FAR*) &gServerAddr, sizeof(gServerAddr)) //绑定端口
    listen(gCapServerSocket, MAX_CONTROL_POINT);
 2.服务器接受连接
         Accept(gCapServerSocket, (struct sockaddr *)& clientAddr, &len) ;
 3.停止服务器
         WSAAsynclSelect(gCapServerSocket, hWndMain, 0, 0) ;
         Closesocket(gCapServerSocket);
4. 发送线程实现
      DWORD WINAPI sendThreadProc(LPVOID lparam)
{
     int length; //待发数据长度
     int n     ;
     int sendCount ;
     while(!EndSendData)
     {       
         bSendData = false; //线程正在发送数据
         for (int i = 0; i < iMaxCtrlPNo; ++i)
         {
              length = gSendLen;
              n      = 0        ;
              sendCount = 0;
              if (sCtrlPoint[i] == INVALID_SOCKET)
                   continue;
              while(length > 0)
              {
                   n = send(sCtrlPoint[i],(const char*)(gSendData + sendCount), length, 0);
//发送数据
                   if (n == SOCKET_ERROR)
                   {                 
                       break; //网络出现异常,则退出
                  }
                   length    -= n;
                   sendCount += n;
              }
         }
         bSendData = true; //准备就绪
         SetEvent(hSendEvent);
         SuspendThread(hSendThread); //数据发送完毕挂起线程,等待下一次发送
     }
     return 0;
}
四.建立UPNP服务器
关于upnp协议的简单介绍
第一步发现, 在将一个设备添加到网络之后, upnp发现协议允许该设备向网络中的控制点宣告其服务。同样,当一个控制点被添加到网络后,upnp发现协议允许该控制点在网上搜感兴趣的设备。两种情况下的根本消息交换均为一个发现消息,包含有关该设备或其中服务之一的一些基本消息。Upnp发现协议基于简单服务发现协议(SSDP).
第二步描述.控制点在发现一个设备之后仍然对其知之甚少。为了使控制点了解到更多关于设备及其能力的信息或设备进行交互,则控制点必须取得来自该设备在发现消息中所提供之URL的设备描述。
第三步控制。当一个控制点取得设备描述后,该控制点可将动作发至一个设备的服务。为此,控制点将一条适当的控制消息发至服务的控制URL,控制消息同样利用简单对象访问协议(SOAP)通过XML来表达。
第四步事件触发。针对服务的UPNP描述包括一个服务响应的动作列表,以及一个对服务器运行时状态进行展示的变量列表。在这些变量变更时服务会发布更新,一个控制点可以预定接收此信息。服务通过发送事件消息来发布更新。事件消息包含一个或多个状态变量名和这些变量的当前值。这些消息同样通过XML来表达,并采用通用事件通知结构(GENA)格式。
第五步展示。如果设备有用于展示的URL,那么控制点就可以通过此URL取得一个页面,在浏览器中加载该页面,并且根据页面的功能,支持用户控制设备或浏览设备状态。
1. 启动UPNP服务器StartUPNPServer()
(1). OpenAndConfSSDPReceiveSocket()
1.建立一个udp Socket绑定到1900端口,并且增加多播地址239.255.255.250到该socket上。
(2)OpenAndConfHTTPSocket()
1.建立udp Socket用来处理进来的HTTP连接。
(3)OpenAndConfSSDPNotifySockets()
1.建立udp Socket用来发送SSDP 通知消息到多播组。
2.UPNP服务器线程 UPNPThreadProc
SendSSDPNotifies2() //发送SSDP通知消息
ProcessSSDPRequest() //处理接收到的SSDP请求
Process_upnphttp();//处理接收到的http请求
SendSSDPGoodbye() // 广播SSDP:byebye通知消息

upnp+摄相头捕捉服务器端程序相关推荐

  1. FTP服务器端程序分类

    FTP服务器端程序有很多种,其中最常见的是vsftpd,顾名思义就是very secure ftp daemon(非常安全的ftp进程). 除此之外还有比vsftpd功能更强大的几种ftp程序: ①  ...

  2. 线程模型、pthread 系列函数 和 简单多线程服务器端程序

    一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属于1:1模型. (一).N:1用户线程模型 "线程实现"建立在&qu ...

  3. 使用udp协议实现服务器端程序时,用VisualC#实现UDP协议(二)

    12.并以下面代码替换Form.cs中由系统产生的InitializeComponent过程. private void InitializeComponent ( ) { this.button1 ...

  4. 控制台应用程序换换为窗体应用_Epic为开发者设计了一套iPhone使用的运动捕捉应用程序...

    玩懂手机网7月13日资讯,我们都知道对于游戏或者是动漫开发者来说,运动捕捉设备是一套非常昂贵的设备,需要非常专业的独立开发人员,大量的时间才能完成,最近Epic为开发者设计了一套iPhone使用的运动 ...

  5. 嵌入式成长轨迹25 【Linux应用编程强化】【Linux下的C编程 下】【实例:客户端/服务器端程序】...

    给出一个客户/服务器程序开发的案例,实现从服务器状态的远程监视功能.同时,客户端采用图形界面来显示数据.这个案例涵盖了网络编程和GUI编程的相关知识,读者应该注意其中的结合点.具体内容包括: 服务器端 ...

  6. 利用原始socket简单实现FTP的客户端和服务器端程序

    1.设计目的 本设计旨在利用原始socket简单实现FTP(File Transfer Protocol,文件传输协议)的客户端和服务器端程序,能够实现get.put.pwd.dir.cd等基本交互命 ...

  7. 摄像头动态捕捉小程序

    Opencv摄像头实时捕捉小程序 驱动摄像头 加入Canny边缘检测 加入Sobel边缘检测 先上一个好玩的动图看看结果: 驱动摄像头 首先先驱动摄像头 实现的代码如下: #include <o ...

  8. C#网络编程服务器端程序实现源码浅析

    C#网络编程服务器端程序实现源码是怎么样的呢?让我们来看看其中重要的一部分: 由于在此次程序中我们采用的结构是异步阻塞方式,所以在实际的程序中,为了不影响服务器端程序的运行速度,我们在程序中设计了一个 ...

  9. 所给服务器端程序改写为能够同时响应多个客户端连接请求的服务器程序_一文读懂客户端请求是如何到达服务器的...

    点击上方"蓝色字体",选择 "设为星标" 关键讯息,D1时间送达! 互联网是人类历史上最伟大的发明创造之一,而构成互联网架构的核心在于TCP/IP协议.那么TC ...

  10. Linux DBUS服务器端程序

    DBus 服务器端接收方式 DBus 服务器端用来接收signal和method调用.从收集的资料中发现,主要有三种接收方式. 一,采用while循环,监听dbus_connection_read_w ...

最新文章

  1. 201771010101 白玛次仁 《2018面向对象程序设计(Java)课程学习进度条》
  2. cms建站系统有哪些,各自的特点是什么?
  3. python怎么用excel-python怎么连接excel
  4. 20155225 实验三《敏捷开发与XP实践》实验报告
  5. Could not load java.net.BindException错误解决
  6. Maven学习之 仓库镜像
  7. 【蓝桥杯官网试题 - 算法训练 】K好数(线性dp与优化)
  8. 知方可补不足~sqlserver中使用ROW_NUMBER进行的快速分页
  9. github怎么搜索开源的代码_5.2.PYTHON开发利器之使用VS Code+GitHub进行python开源项目开发...
  10. 9个超级实用的 ES6 特性,超级实用哦!
  11. cf519D . A and B and Interesting Substrings 数据结构map
  12. ROS:激光雷达+laser_scan_matcher 运行gmapping
  13. 如何用计算机算tan2,arctan计算器(万能计算器在线使用)
  14. 利用outlook邮箱申请teams账号
  15. 拉普拉斯矩阵(Laplace Matrix)与瑞利熵(Rayleigh quotient
  16. Arch Linux fcitx 新世纪五笔配置
  17. 自动化手游测试视频震撼发布
  18. FOJ 1402 猪的安家
  19. 关于File()中的pathname的路径
  20. ExcelVBA之 sheet隐藏

热门文章

  1. 做互联网最重要的是希望! 【水木周平】
  2. 敏捷史话系列(一)| 用一半的时间做两倍的事——Jeff Sutherland
  3. worksheet怎么读_worksheet是什么意思_worksheet怎么读_worksheet翻译_用法_发音_词组_同反义词_工作表_学习单-新东方在线英语词典...
  4. 商米D1S一体机设置搜狗手写输入法图解
  5. mysql身份证来算年龄_MySQL 根据身份证出生年月计算年龄户籍地性别
  6. 打印机共享无法访问该计算机,共享打印机拒绝访问怎么办详细解决方案
  7. matlab实现色彩迁移,图像的色彩风格迁移
  8. 奇兔recovery卡刷教程_OPPO A59s 刷入奇兔recovery及root权限刷机教程
  9. excel 自动生成目录
  10. 100以内的平方数记忆法