• 3、设计中拖动 videoSourcePlayer控件 做显示预览视频,pictureBox控件做拍照显示(注:不按步骤2添加dll可能在工具箱中找不到该空间) 4、代码 using AForge.Video.DirectShow; using Syst...

    1、准备工作:dll 源码中有

    在这里插入图片描述

    2、工具箱中右键、选择项、浏览找到AForge.Controls.dll添加进去,既可以使用其中的空间

    在这里插入图片描述
    在这里插入图片描述

    3、设计器中拖动 videoSourcePlayer控件 做显示预览视频,pictureBox控件做拍照显示(注:不按步骤2添加dll可能在工具箱中找不到该空间)

    在这里插入图片描述

    4、代码

    using AForge.Video.DirectShow;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace test1
    {
        public partial class Form1 : Form
        {
    private  AForge.Controls.VideoSourcePlayer videoSourcePlayer;
    private FilterInfoCollection videoDevices;
            public Form1()
            {
                InitializeComponent();
            }
    
            /// <summary>
            /// 启动视频预览
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void button1_Click(object sender, EventArgs e)
            {
               //count = 1;
                //枚举所有视频输入设备
                videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
    
                if (videoDevices.Count == 0)
                {
                    MessageBox.Show("未发现视频设备!");
                    return;
                }
               
               VideoCaptureDevice source = new VideoCaptureDevice(this.videoDevices[0].MonikerString);
               this.videoSourcePlayer1.SignalToStop();
               this.videoSourcePlayer1.WaitForStop();
               this.videoSourcePlayer1.VideoSource = source;
               this.videoSourcePlayer1.Start();
    
    
            }
          
            /// <summary>
            /// 拍照
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
    
            private void button2_Click(object sender, EventArgs e)
            {
                pictureBox1.BackgroundImage = Image.FromHbitmap(videoSourcePlayer1.GetCurrentVideoFrame().GetHbitmap());
            }
    
            /// <summary>
            /// 停止预览
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void button3_Click(object sender, EventArgs e)
            {
                this.videoSourcePlayer1.Stop();
                GC.Collect();
            }
        }
    }
    
    

    5、运行效果

    在这里插入图片描述

    展开全文
  • USB协议版本有USB1.0、USB1.1、USB2.0、USB3.1等,USB2.0目前比较常用,USB是主从模式的结构,设备与设备之间、主机与主机之间不能互连,为解决这个问题,扩大USB的应用范围,出现了USB OTG,全拼 ON The Go。USB ...

          USB(Universal Serial Bus)全称通用串口总线,USB为解决即插即用需求而诞生,支持热插拔。USB协议版本有USB1.0、USB1.1、USB2.0、USB3.1等,USB2.0目前比较常用,USB是主从模式的结构,设备与设备之间、主机与主机之间不能互连,为解决这个问题,扩大USB的应用范围,出现了USB OTG,全拼 ON The Go。USB OTG 同一个设备,在不同的场合下可行在主机和从机之间切换。

        1、USB特点

             USB1.0和USB1.1支持1.5Mb/s的低速模式和12Mb/bs的全速模式。在USB2.0以上支持480Mb/s的高速模式。 

     2、  自供电设备:设备从外部电源获取工作电压 总线供电设备:设备从VBUS(5v) 取电 。对总线供电设备,区分低功耗和高功耗USB设备 

    低功耗总线供电设备:最大功耗不超过100mA 
    高功耗总线供电设备: 枚举时最大功耗不超过100mA,枚举完成配置结束后功耗不超过500mA 
    设备在枚举过程中,通过设备的配置描述符向主机报告它的供电配置(自供电/总线供电)以及它的功耗要求

    3、 USB总线信号:
            USB使用的是差分传输模式,两个数据线D+和D- 
            差分信号1:D+ > VOH(min) (2.8V) 且D- < VOL(max)(0.3V) 
            差分信号0:D- > VOH and D+ < VOL  

    总有以下个状态,

    J状态(高电平):D+ 高,D- 低
    K状态(低电平):D+低,D- 高
    SEO状态:D+ 低,D- 高
    Reset信号:D+ and D- < VOL for >= 10ms 
    主机在要和设备通信之前会发送Reset信号来把设备设置到默认的未配置状态。即主机拉低两根信号线(SE0状态)
    并保持10ms 
    Idle状态:J状态数据发、送前后总线的状态 
    Suspend状态:3ms以上的J状态 

                                   SYNC: 3个KJ状态切换,后跟随2位时间的K状态

    Resume信号:20ms的K状态+低速EOP 
    主机在挂起设备后可通过翻转数据线上的极性并保持20ms来唤醒设备,并以低速EOP信号结尾 
    带远程唤醒功能的设备还可自己发起该唤醒信号;前提是设备已进入idle状态至少5ms,然后发出唤醒K信号,维持1ms到15ms并由主机在1ms内接管来继续驱动唤醒信号 
    SOP:从IDLE状态切换到K状态 
    EOP:持续2位时间的SE0信号,后跟随1位时间的J状态 
    Keep alive即低速EOP信号

    唤醒slave设备操作

    4、USB插入检测和速度检测

         全速高速设备在D+接上拉1.5k电阻,低速设备在D-接上拉1.5K电阻。主机检测到某一个数据线电平拉高并保持了一段时间,就认为有设备连上来了, 先把高速设备检测为全速设备,然后再通过“Chirp序列”的总线握手机制来识别高速和全速设备。主机必需在驱动SE0状态以复位设备之前,立刻采样总线状态来判断设备的速度 。

        D+和D-数据线上的下拉电阻起作用,使得二者都在低电平;主机端看来就是个SE0状态;同样地,当数据线上的SE0状态持续一段时间了,就被主机认为是断开状态。

    5、USB传输

         一个传输有多个事务组成,一个事务由2到3个包组成。传输又分为四种类型:批量传输、等时(同步)传输、中断传输、控制传输。注意:USB传输数据先发数据低位再发高位数据。

       USB协议定义了四种传输类型: 
    批量(大容量数据)传输(Bulk Transfers): 非周期性,突发  
    大容量数据的通信,数据可以占用任意带宽,并容忍延迟 。如USB打印机、扫描仪、大容量储存设备等 

    低速 USB 设备不支持批量传输,高速批量端点的最大包长度为 512,全速批量端点的最大包长度可以为 8、16、32、64。

          批量传输在访问 USB 总线时,相对其他传输类型具有最低的优先级,USB HOST 总是优先安排其他类型的传输,当总线带宽有富余时才安排批量传输。

          高速的批量端点必须支持PING 操作,向主机报告端点的状态,NYET 表示否定应答,没有准备好接收下一个数据包,ACK 表示肯定应答,已经准备好接收下一个数据包。


    中断传输(Interrupt Transfers): 周期性,低频率
    允许有限延迟的通信 如人机接口设备(HID)中的鼠标、键盘、轨迹球等

    中断传输是一种保证查询频率的传输。中断端点在端点描述符中要报告它的查询间隔,主机会保证在小于
    这个时间间隔的范围内安排一次传输。

    中断传输是一种轮询的传输方式,是一种单向的传输,HOST通过固定的间隔对中断端点进行查询,若有数据传输或可以接收数据则返回数据或发送数据,否则返回NAK,表示尚未准备好。

          中断传输的延迟有保证,但并非实时传输,它是一种延迟有限的可靠传输,支持错误重传。 
          对于高速/全速/低速端点,最大包长度分别可以达到1024/64/8 Bytes。

          高速中断传输不得占用超过 80%的微帧时间,全速和低速不得超过 90%。

          中断端点的轮询间隔由在端点描述符中定义,全速端点的轮询间隔可以是1~255mS,低速端点为10~255mS,高速端点为(2interval-1)*125uS,其中 interval取 1到 16之间的值。

          除高速高带宽中断端点外,一个微帧内仅允许一次中断事务传输,高速高带宽端点最多可以在一个微帧内进行三次中断事务传输,传输高达 3072 字节的数据。

          所谓单向传输,并不是说该传输只支持一个方向的传输,而是指在某个端点上该传输仅支持一个方向,或输出,或输入。如果需要在两个方向上进行某种单向传输,需要占用两个端点,

          分别配置成不同的方向,可以拥有相同的端点编号。


    等时(同步)传输(Isochronous Transfers): 周期性 
    持续性的传输,用于传输与时效相关的信息,并且在数据中保存时间戳的信息 ,如音频视频设备

    等时(同步)传输用在数据量大、对实时性要求高的场合,如音频设备,视频设备等,这些设备对数据的延迟很敏感。对于音频或视频设备数据的100%正确性要求不高,少量的数据错误是可以容忍的,主要是保证数据不能停顿,所以等时传输是不保证数据100%正确的。当数据错误时,不再重传操作。因此等时传输没有应答包,数据是否正确,由数据的CRC校验来确认。


    控制传输(Control Transfers): 非周期性,突发
    用于命令和状态的传输

                                  控制传输可分为三个过程:(1)建立过程 (2)数据过程(可选) (3)状态过程
                                  特性:  
                                 每个USB设备都必须有控制端点,支持控制传输来进行命令和状态的传输。USB主机驱动将通过控制传输与USB设备的控制端点通信,完成USB设备的枚举和配置 
                                 方向:  
                                 控制传输是双向的传输,必须有IN和OUT两个方向上的特定端点号的控制端点来完成两个方向上的控制传输

    控制传输是一种可靠的双向传输,一次控制传输可分为三个阶段。第一阶段为从HOST到Device的SETUP事务传输,这个阶段指定了此次控制传输的请求类型;

          第二阶段为数据阶段,也有些请求没有数据阶段;第三阶段为状态阶段,通过一次IN/OUT 传输表明请求是否成功完成。

          控制传输通过控制管道在应用软件和 Device 的控制端点之间进行,控制传输过程中传输的数据是有格式定义的,USB 设备或主机可根据格式定义解析获得的数据含义。

          其他三种传输类型都没有格式定义。

          控制传输对于最大包长度有固定的要求。对于高速设备该值为 64Byte;对于低速设备该值为 8;全速设备可以是 8或 16或 32或 64。

          最大包长度 表征了一个端点单次接收/发送数据的能力,实际上反应的是该端点对应的Buffer 的大小。Buffer 越大,单次可接收/发送的数据包越大,反之亦反。

          当通过一个端点进行数据传输时,  若数据的大小超过该端点的最大包长度时,需要将数据分成若干个数据包传输,并且要求除最后一个包外,所有的包长度均等于该最大包长度。

          这也就是说如果一个端点收到/发送了一个长度小于最大包长度的包,即意味着数据传输结束。

          控制传输在访问总线时也受到一些限制,如:

            a. 高速端点的控制传输不能占用超过 20%的微帧,全速和低速的则不能超过 10%。 
            b. 在一帧内如果有多余的未用时间,并且没有同步和中断传输,可以用来进行控制传输。

    6、USB的编码方案

         USB采用不归零取反来传输数据,当传输线上的差分数据输入0时就取反,输入1时就保持原值,为了确保信号发送的准确性,当在USB总线上发送一个包时,传输设备就要进行位插入***作(即在数据流中每连续6个1后就插入一个0)。

    7、USB的数据格式

       (一)域:是USB数据最小的单位,由若干位组成(至于是多少位由具体的域决定),域可分为七个类型:

    1、同步域(SYNC),八位,值固定为0000 0001,用于本地时钟与输入同步

    2、标识域(PID),由四位标识符+四位标识符反码构成,表明包的类型和格式,这是一个很重要的部分,这里可以计算出,USB的标识码有16种,具体分类请看问题五。

    3、地址域(ADDR):七位地址,代表了设备在主机上的地址,地址000 0000被命名为零地址,是任何一个设备第一次连接到主机时,在被主机配置、枚举前的默认地址,由此可以知道为什么一个USB主机只能接127个设备的原因。

    4、端点域(ENDP),四位,由此可知一个USB设备有的端点数量最大为16个。

    5、帧号域(FRAM),11位,每一个帧都有一个特定的帧号,帧号域最大容量0x800,对于同步传输有重要意义(同步传输为四种传输类型之一,请看下面)。

    6、数据域(DATA):长度为0~1023字节,在不同的传输类型中,数据域的长度各不相同,但必须为整数个字节的长度

    7、校验域(CRC):对令牌包和数据包(对于包的分类请看下面)中非PID域进行校验的一种方法,CRC校验在通讯中应用很泛,是一种很好的校验方法,至于具体的校验方法这里就不多说,请查阅相关资料,只须注意CRC码的除法是模2运算,不同于10进制中的除法。

    (二)包:由域构成的包有四种类型,分别是令牌包、数据包、握手包和特殊包,前面三种是重要的包,不同的包的域结构不同,介绍如下

    1、令牌包:可分为输入包、输出包、设置包和帧起始包(注意这里的输入包是用于设置输入命令的,输出包是用来设置输出命令的,而不是放据数的)

    其中输入包、输出包和设置包的格式都是一样的:

    SYNC+PID+ADDR+ENDP+CRC5(五位的校验码)

    帧起始包的格式:

    SYNC+PID+11位FRAM+CRC5(五位的校验码)

    2、数据包:分为DATA0包和DATA1包,当USB发送数据的时候,当一次发送的数据长度大于相应端点的容量时,就需要把数据包分为好几个包,分批发送,DATA0包和DATA1包交替发送,即如果第一个数据包是 DATA0,那第二个数据包就是DATA1。但也有例外情况,在同步传输中(四类传输类型中之一),所有的数据包都是为DATA0,格式如下:

    SYNC+PID+0~1023字节+CRC16

    3、握手包:结构最为简单的包,格式如下

    SYNC+PID

    8、USB 2.0 和USB 3.0 对比 

    1. USB 2.0基于半双工二线制总线,两根线的差分信号来传输数据,只能提供单向数据流传输;而USB 3.0采用了TxRx四线制差分信号线,类似于PCIe总线,故而支持双向并发数据流传输。
    2.  USB3.0的最大数据传输速率为5Gbps,与USB2.0的480Mbps相比,提升到了10倍以上。
    3.   USB3.0芯片大小目标与现有的USB2.0芯片相当,封装尺寸为6mm×6mm~7mm×7mm
    4.  USB3.0连接器为了保证与现有标准的兼容性,USB3.0引入了新的连接器,包括两种类型:标准规格和面向便携设备的Micro规格。标准规格又包含两种类型:A型与B型。

      A型接口:USB2.0连接器在前,而USB3.0连接器在后

      B型接口:USB3.0连接器设置于USB2.0连接器的上方。

    5. 电源电流在同样的5V电压下,USB3.0的电源电流可达到900mA,而USB2.0的100mA。
    6. USB3.0将会智能管理USB设备,最大限度地杜绝空置的电能浪费,此举对笔记本用户会带来一定的好处;USB3.0增大了供应电流。在之前的USB规范中,设备取电一般最大可以得到100毫安的电流,如果采用高电量的模式,则得到的电流是500毫安,如果需要更大的电流,则只能借助变压器,然而USB3.0可供应的最大电流是900毫安。这意味着,对于MP3、手机充电来说,采用USB3.0传输的话,充电效率将成倍的提高,从而大大节约充电时间。据悉这是由于USB3.0增加5个针脚造成的。

     

    转载于:https://www.cnblogs.com/uiojhi/p/9466597.html

    展开全文
  • c#设置示波并获取TEK公司的示波的波形数据,但是毫无起色,希望有大神们能给个实例程序 谢谢啦。
  • C#开发通过引用Visa获取泰克示波器采集的数据,大致过程为:打开会话,通过读写函数对示波进行相关设置并读取相应数据,关闭会话
  • USB产品开发的软件部分和硬件部分都有着一定的难度,如果想实现复杂的功能,必须冲破接口芯片厂商提供的软硬件资料设计出更完善的硬件系统和更复杂的上层软件。如果能够把USB各种应用下的复杂开发过程归纳总结,在软...

           USB接口广泛应用于各种外设与PC或嵌入式系统的通信,在各行各业发挥着巨大的作用。如今已经成为最常见的数字接口,全球总设备量超过150亿,并以每年20亿的数量递增(by CNN)。


           然而USB的设备的开发却有着不小的难度。USB功能主要由USB接口芯片来实现,主流的方案有Cypress、FTDI。其中Cypress的FX2(CY7C68013A)/FX3(CYUSB3014)系列由于技术领先,最受市场青睐。

           接口芯片厂商一般会提供一套基础的函数库给用户用来开发上位机程序和接口芯片固件程序用于与外设的数据通信及控制。

           为了提高和外部设备的适应性,Cypress内建了模拟FPGA状态机功能的GPIF接口(FX3是8/16/32位),能够帮助用户实现一些基础的接口通信。

           然而GPIF的状态机功能是模拟出来的,有诸多限制,易用度上和真正的FPGA状态机有一定的差距,很多朋友普遍反映比较难搞,比如:

    •     能使用的输入输出控制信号只有14根@32bits位宽;
    •     每一个状态的跳出路径不能超过2个;
    •     状态机跳转条件不能使用超过4个触发变量;
    •     只能使用3个计数器功能,其中一个计数器是16位,另外两个是32位;
    •     内建的标志信号在不同的GPIF配置下会有不同的延迟时间;
    •     最让人头疼的是GPIF状态机没有办法像FPGA状态机一样灵活调试,如果碰上复杂一些的应用,需要花费大量的时间在调试上。

           USB接口的通信速度比较快,3.0达到300MiB/s+,3.1能达到600MiB/s+。在设计的过程中需要加入大容量SDRAM缓存来提高传输可靠性,由于USB接口芯片没有集成SDRAM控制器,并且下一代接口芯片的数据接口由并行口升级成了LVDS(FX3PD),这些都需要加入FPGA来提供辅助支持。

           所以,USB产品开发的软件部分和硬件部分都有着一定的难度,如果想实现复杂的功能,必须冲破接口芯片厂商提供的软硬件资料设计出更完善的硬件系统和更复杂的上层软件。

           如果能够把USB各种应用下的复杂开发过程归纳总结,在软硬件上将其公共部分提取出来,把USB接口芯片的固件做成统一化,并重新开发出一套面向FPGA的上位机API和FPGA IPcore。会极大的缩减USB新项目的开发风险、难度和花费,提升开发灵活度,开发出更复杂的USB产品应用。这就是USB免固件开发方案。

           免固件开发并不是指没有固件程序而是固件不需要修改,直接调用上位机API开发FPGA USB应用。


    如需更多信息,请搜索www.pionway.com

    预告:7天内完成基础USB开发(2)——FPGA+USB高速数据采集系统的硬件设计技巧


    展开全文
  • 录像是直接复制了网上的。 压缩是一个同事做的。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing;...using System.Threa

    录像是直接复制了网上的。

    压缩是一个同事做的。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Threading;
    using System.Windows.Forms;
    using System.IO;

    namespace Basic
    {
        public class VideoAPI  //视频API类
        {
            //  视频API调用
            [DllImport("avicap32.dll")]//包含了执行视频捕获的函数,它给AVI文件I/O和视频、音频设备驱动程序提供一个高级接口
            public static extern IntPtr capCreateCaptureWindow(string lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hwndParent, int nID);
            [DllImport("AVICAP32.dll", CharSet = CharSet.Unicode)]
            public static extern bool capGetDriverDescription(int wDriverIndex, StringBuilder lpszName, int cbName, StringBuilder lpszVer, int cbVer);
            [DllImport("avicap32.dll")]
            public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
            [DllImport("avicap32.dll")]
            public static extern bool capGetDriverDescriptionA(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer);
            [DllImport("User32.dll")]
            public static extern bool SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam);
            [DllImport("User32.dll")]
            public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, int lParam);
            [DllImport("User32.dll")]
            public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
            [DllImport("User32.dll")]
            public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, FrameEventHandler lParam);
            [DllImport("User32.dll")]
            public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref BITMAPINFO lParam);
            [DllImport("User32.dll")]
            public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPDRIVERCAPS lParam);
            [DllImport("User32.dll")]
            public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPTUREPARMS lParam);
            [DllImport("User32.dll")]
            public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPSTATUS lParam);
            [DllImport("User32.dll")]
            public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
            [DllImport("avicap32.dll")]
            public static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize);

            //  常量
            // public const int WM_USER = 0x400;
            public const int WS_CHILD = 0x40000000;
            public const int WS_VISIBLE = 0x10000000;

            public const int SWP_NOMOVE = 0x2;
            public const int SWP_NOZORDER = 0x4;
            // public const int WM_CAP_DRIVER_CONNECT = WM_USER + 10;
            //   public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + 11;
            public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + 5;
            //   public const int WM_CAP_SET_PREVIEW = WM_USER + 50;
            //  public const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52;
            //  public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + 45;
            //   public const int WM_CAP_START = WM_USER;
            public const int WM_CAP_SAVEDIB = WM_CAP_START + 25;

            public const string avicap32 = "avicap32.dll";
            public const int WM_USER = 1024;
            /// <summary>
            ///WM_CAP_START=WM_USER=1024
            /// </summary>
            public const int WM_CAP_START = WM_USER;

            // start of unicode messages
            /// <summary>
            /// 开始   WM_USER + 100=1124
            /// </summary>
            public const int WM_CAP_UNICODE_START = WM_USER + 100; //开始   1124
            /// <summary>
            /// /获得 CAPSTR EAMPTR   
            /// WM_CAP_START + 1=1025
            /// </summary>
            public const int WM_CAP_GET_CAPSTREAMPTR = (WM_CAP_START + 1); //获得 CAPSTR EAMPTR
            /// <summary>
            /// 设置收回错误   WM_CAP_START + 2=1026
            /// </summary>
            public const int WM_CAP_SET_CALLBACK_ERROR = (WM_CAP_START + 2); //设置收回错误
            /// <summary>
            /// 设置收回状态 WM_CAP_START + 3=1027
            /// </summary>
            public const int WM_CAP_SET_CALLBACK_STATUS = (WM_CAP_START + 3); //设置收回状态
            /// <summary>
            /// 设置收回出产  WM_CAP_START + 4=1028
            /// </summary>
            public const int WM_CAP_SET_CALLBACK_YIELD = (WM_CAP_START + 4); //设置收回出产
            /// <summary>
            /// 设置收回结构  WM_CAP_START + 5=1029
            /// </summary>
            public const int WM_CAP_SET_CALLBACK_FRame = (WM_CAP_START + 5); //设置收回结构
            /// <summary>
            /// 设置收回视频流  WM_CAP_START + 6=1030
            /// </summary>
            public const int WM_CAP_SET_CALLBACK_VIDEOSTREAM = (WM_CAP_START + 6); //设置收回视频流
            /// <summary>
            /// 设置收回视频波流  WM_CAP_START +7=1031
            /// </summary>
            public const int WM_CAP_SET_CALLBACK_WAVESTREAM = (WM_CAP_START + 7); //设置收回视频波流
            /// <summary>
            /// 获得使用者数据 WM_CAP_START + 8=1032
            /// </summary>
            public const int WM_CAP_GET_USER_DATA = (WM_CAP_START + 8); //获得使用者数据
            /// <summary>
            /// 设置使用者数据 WM_CAP_START + 9=1033
            /// </summary>
            public const int WM_CAP_SET_USER_DATA = (WM_CAP_START + 9); //设置使用者数据
            /// <summary>
            /// 驱动程序连接  WM_CAP_START + 10=1034
            /// </summary>
            public const int WM_CAP_DRIVER_CONNECT = (WM_CAP_START + 10); //驱动程序连接
            /// <summary>
            /// 断开启动程序连接 WM_CAP_START + 11=1035
            /// </summary>
            public const int WM_CAP_DRIVER_DISCONNECT = (WM_CAP_START + 11); //断开启动程序连接
            /// <summary>
            /// 获得驱动程序名字 WM_CAP_START + 12=1036
            /// </summary>
            public const int WM_CAP_DRIVER_GET_NAME = (WM_CAP_START + 12); //获得驱动程序名字
            /// <summary>
            /// 获得驱动程序版本 WM_CAP_START + 13=1037
            /// </summary>
            public const int WM_CAP_DRIVER_GET_VERSION = (WM_CAP_START + 13); //获得驱动程序版本
            /// <summary>
            /// 获得驱动程序帽子 WM_CAP_START + 14=1038
            /// </summary>
            public const int WM_CAP_DRIVER_GET_CAPS = (WM_CAP_START + 14); //获得驱动程序帽子
            /// <summary>
            /// 设置捕获文件 WM_CAP_START + 20=1044
            /// </summary>
            public const int WM_CAP_FILE_SET_CAPTURE_FILE = (WM_CAP_START + 20); //设置捕获文件
            /// <summary>
            /// 获得捕获文件 WM_CAP_START + 21=1045
            /// </summary>
            public const int WM_CAP_FILE_GET_CAPTURE_FILE = (WM_CAP_START + 21); //获得捕获文件
            /// <summary>
            /// 另存文件为  WM_CAP_START + 23=1047
            /// </summary>
            public const int WM_CAP_FILE_SAVEAS = (WM_CAP_START + 23); //另存文件为
            /// <summary>
            /// 保存文件    WM_CAP_START + 25=1049
            /// </summary>
            public const int WM_CAP_FILE_SAVEDIB = (WM_CAP_START + 25); //保存文件

            // out of order to save on ifdefs
            /// <summary>
            /// 分派文件  WM_CAP_START + 22=1044
            /// </summary>
            public const int WM_CAP_FILE_ALLOCATE = (WM_CAP_START + 22); //分派文件
            /// <summary>
            /// 设置开始文件  WM_CAP_START + 24=1046
            /// </summary>
            public const int WM_CAP_FILE_SET_INFOCHUNK = (WM_CAP_START + 24); //设置开始文件
            /// <summary>
            /// 编辑复制   WM_CAP_START + 30=1054
            /// </summary>
            public const int WM_CAP_EDIT_COPY = (WM_CAP_START + 30); //编辑复制
            /// <summary>
            /// 设置音频格式  WM_CAP_START + 35=1059
            /// </summary>
            public const int WM_CAP_SET_AUDIOFORMAT = (WM_CAP_START + 35); //设置音频格式
            /// <summary>
            /// 捕获音频格式  WM_CAP_START + 36=1060
            /// </summary>
            public const int WM_CAP_GET_AUDIOFORMAT = (WM_CAP_START + 36); //捕获音频格式
            /// <summary>
            /// 打开视频格式设置对话框  WM_CAP_START + 41=1065
            /// </summary>
            public const int WM_CAP_DLG_VIDEOFORMAT = (WM_CAP_START + 41); //1065 打开视频格式设置对话框
            /// <summary>
            /// 打开属性设置对话框,设置对比度、亮度等   WM_CAP_START + 42=1066
            /// </summary>
            public const int WM_CAP_DLG_VIDEOSOURCE = (WM_CAP_START + 42); //1066 打开属性设置对话框,设置对比度、亮度等。
            /// <summary>
            /// 打开视频显示 WM_CAP_START + 43=1067
            /// </summary>
            public const int WM_CAP_DLG_VIDEODISPLAY = (WM_CAP_START + 43); //1067 打开视频显示
            /// <summary>
            /// 获得视频格式 WM_CAP_START + 44=1068
            /// </summary>
            public const int WM_CAP_GET_VIDEOFORMAT = (WM_CAP_START + 44); //1068 获得视频格式
            /// <summary>
            /// 设置视频格式 WM_CAP_START + 45=1069
            /// </summary>
            public const int WM_CAP_SET_VIDEOFORMAT = (WM_CAP_START + 45); //1069 设置视频格式
            /// <summary>
            /// 打开压缩设置对话框 WM_CAP_START + 46=1070
            /// </summary>
            public const int WM_CAP_DLG_VIDEOCOMPRESSION = (WM_CAP_START + 46); //1070 打开压缩设置对话框
            /// <summary>
            /// 设置预览 WM_CAP_START + 50=1074
            /// </summary>
            public const int WM_CAP_SET_PREVIEW = (WM_CAP_START + 50); //设置预览
            /// <summary>
            /// 设置覆盖 WM_CAP_START + 51=1075
            /// </summary>
            public const int WM_CAP_SET_OVERLAY = (WM_CAP_START + 51); //设置覆盖
            /// <summary>
            /// 设置预览比例 WM_CAP_START + 52=1076
            /// </summary>
            public const int WM_CAP_SET_PREVIEWRATE = (WM_CAP_START + 52); //设置预览比例
            /// <summary>
            /// 设置刻度 WM_CAP_START + 53=1077
            /// </summary>
            public const int WM_CAP_SET_SCALE = (WM_CAP_START + 53); //设置刻度
            /// <summary> 
            /// 获得状态 WM_CAP_START + 54=1078
            /// </summary>
            public const int WM_CAP_GET_STATUS = (WM_CAP_START + 54); //获得状态
            /// <summary>
            /// 设置卷 WM_CAP_START + 55=1079
            /// </summary>
            public const int WM_CAP_SET_SCROLL = (WM_CAP_START + 55); //设置卷
            /// <summary>
            /// 逮捕结构 WM_CAP_START + 60=1084
            /// </summary>
            public const int WM_CAP_GRAB_FRame = (WM_CAP_START + 60); //逮捕结构
            /// <summary>
            /// 停止逮捕结构 WM_CAP_START + 61=1085
            /// </summary>
            public const int WM_CAP_GRAB_FRame_NOSTOP = (WM_CAP_START + 61); //停止逮捕结构
            /// <summary>
            /// 次序 WM_CAP_START + 62=1086
            /// </summary>
            public const int WM_CAP_SEQUENCE = (WM_CAP_START + 62); //次序
            /// <summary>
            /// 没有文件 WM_CAP_START + 63=1087
            /// </summary>
            public const int WM_CAP_SEQUENCE_NOFILE = (WM_CAP_START + 63); //没有文件
            /// <summary>
            /// 设置安装次序 WM_CAP_START + 64=1088
            /// </summary>
            public const int WM_CAP_SET_SEQUENCE_SETUP = (WM_CAP_START + 64); //设置安装次序
            /// <summary>
            /// 获得安装次序 WM_CAP_START + 65=1089
            /// </summary>
            public const int WM_CAP_GET_SEQUENCE_SETUP = (WM_CAP_START + 65); //获得安装次序
            /// <summary>
            /// 设置媒体控制接口 WM_CAP_START + 66=1090
            /// </summary>
            public const int WM_CAP_SET_MCI_DEVICE = (WM_CAP_START + 66); //设置媒体控制接口
            /// <summary>
            /// 获得媒体控制接口 WM_CAP_START + 67=1091
            /// </summary>
            public const int WM_CAP_GET_MCI_DEVICE = (WM_CAP_START + 67); //获得媒体控制接口 
            /// <summary>
            /// 停止 WM_CAP_START + 68=1092
            /// </summary>
            public const int WM_CAP_STOP = (WM_CAP_START + 68); //停止
            /// <summary>
            /// 异常中断 WM_CAP_START + 69=1093
            /// </summary>
            public const int WM_CAP_ABORT = (WM_CAP_START + 69); //异常中断
            /// <summary>
            /// 打开单一的结构 WM_CAP_START + 68=1094
            /// </summary>
            public const int WM_CAP_SINGLE_FRame_OPEN = (WM_CAP_START + 70); //打开单一的结构
            /// <summary>
            /// 关闭单一的结构 WM_CAP_START + 71=1095
            /// </summary>
            public const int WM_CAP_SINGLE_FRame_CLOSE = (WM_CAP_START + 71); //关闭单一的结构
            /// <summary>
            /// 单一的结构 WM_CAP_START + 72=1096
            /// </summary>
            public const int WM_CAP_SINGLE_FRame = (WM_CAP_START + 72); //单一的结构
            /// <summary>
            /// 打开视频 WM_CAP_START + 80=1104
            /// </summary>
            public const int WM_CAP_PAL_OPEN = (WM_CAP_START + 80); //打开视频
            /// <summary>
            /// 保存视频 WM_CAP_START + 81=1105
            /// </summary>
            public const int WM_CAP_PAL_SAVE = (WM_CAP_START + 81); //保存视频
            /// <summary>
            /// 粘贴视频 WM_CAP_START + 82=1106
            /// </summary>
            public const int WM_CAP_PAL_PASTE = (WM_CAP_START + 82); //粘贴视频
            /// <summary>
            /// 自动创造 WM_CAP_START + 83=1107
            /// </summary>
            public const int WM_CAP_PAL_AUTOCREATE = (WM_CAP_START + 83); //自动创造
            /// <summary>
            /// 手动创造 WM_CAP_START + 84=1108
            /// </summary>
            public const int WM_CAP_PAL_MANUALCREATE = (WM_CAP_START + 84); //手动创造

            // Following added post VFW 1.1
            /// <summary>
            /// 设置收回的错误 WM_CAP_START + 85=1109
            /// </summary>
            public const int WM_CAP_SET_CALLBACK_CAPCONTROL = (WM_CAP_START + 85); // 设置收回的错误

            public const int WM_CAP_END = WM_CAP_SET_CALLBACK_CAPCONTROL;

            public delegate void FrameEventHandler(IntPtr lwnd, IntPtr lpVHdr);

            #region 公共函数
            //公共函数
            public static object GetStructure(IntPtr ptr, ValueType structure)
            {
                return Marshal.PtrToStructure(ptr, structure.GetType());
            }

            public static object GetStructure(int ptr, ValueType structure)
            {
                return GetStructure(new IntPtr(ptr), structure);
            }

            public static void Copy(IntPtr ptr, byte[] data)
            {
                Marshal.Copy(ptr, data, 0, data.Length);
            }

            public static void Copy(int ptr, byte[] data)
            {
                Copy(new IntPtr(ptr), data);
            }

            public static int SizeOf(object structure)
            {
                return Marshal.SizeOf(structure);
            }
            #endregion 公共函数
            #region 结构 VIDEOHDR|BITMAPINFOHEADER|BITMAPINFO|CAPTUREPARMS|CAPDRIVERCAPS|CAPSTATUS
            //========================================================VideoHdr 结构=====================================================================
            //VideoHdr 结构   定义了视频数据块的头信息,在编写回调函数时常用到其数据成员lpData(指向数据缓存的指针)和dwBufferLength(数据缓存的大小)。     
            //视频帧到缓存的捕获则需要应用回调函数和相应的数据块结构 VIDEOHDR 
            [StructLayout(LayoutKind.Sequential)]
            public struct VIDEOHDR
            {
                public IntPtr lpData;              /* 指向数据缓存的指针 */
                public int dwBufferLength;         /* 数据缓存的大小 */
                public int dwBytesUsed;            /* Bytes actually used */
                public int dwTimeCaptured;         /* Milliseconds from start of stream */
                public int dwUser;                 /* for client's use */
                public int dwFlags;                /* assorted flags (see defines) */
                public int dwReserved;             /* reserved for driver */
            }
            //=======================================================BitmapInfoHeader结构===================================================================
            //BitmapInfoHeader定义了位图的头部信息
            [StructLayout(LayoutKind.Sequential)]
            public struct BITMAPINFOHEADER
            {
                public int biSize;
                public int biWidth;
                public int biHeight;
                public short biPlanes;
                public short biBitCount;
                public int biCompression;
                public int biSizeImage;
                public int biXPelsPerMeter;
                public int biYPelsPerMeter;
                public int biClrUsed;
                public int biClrImportant;
            }
            //=========================================================================================================================================

            //======================================================BitmapInfo结构=====================================================================
            //BitmapInfo   位图信息
            [StructLayout(LayoutKind.Sequential)]
            public struct BITMAPINFO
            {
                public BITMAPINFOHEADER bmiHeader;
                public int bmiColors;
            }

            //=====================================================CAPTUREPARMS结构======================================================================
            //CAPTUREPARMS 包含控制视频流捕获过程的参数,如捕获帧频、指定键盘或鼠标键以终止捕获、捕获时间限制等; 
            [StructLayout(LayoutKind.Sequential)]
            public struct CAPTUREPARMS
            {
                public int dwRequestMicroSecPerFrame;             // 期望的桢播放率,以毫秒为单位,默认为66667,相当于15桢每秒。
                public bool fMakeUserHitOKToCapture;             // Show "Hit OK to cap" dlg?开始捕获标志位,如果值为真,则在开始捕获前要产生一个询问对话框,默认为假。
                public uint wPercentDropForError;               //所允许的最大丢桢百分比,可以从0变化到100,默认值为10。
                public bool fYield;                     /*另起线程标志位,如果为真,则程序重新启动一个线程用于视频流的捕获,默认值是假。
                                                         但是如果你是为了真,你必须要在程序中处理一些潜在的操作,因为当视频捕获时,其他操作并没有被屏蔽。*/
                public int dwIndexSize;                       // 在AVI文件中所允许的最大数目的索引项(32K)
                public uint wChunkGranularity;               // AVI文件的逻辑尺寸,以字节为单位。如果值是0,则说明该尺寸渐增 在 Win32程序中无用。(2K)
                public bool fUsingDOSMemory;                // Use DOS buffers?
                public uint wNumVideoRequested;            // 所被允许分配的最大视频缓存
                public bool fCaptureAudio;                // 音频标志位,如果音频流正在捕获,则该值为真。
                public uint wNumAudioRequested;          // 最大数量的音频缓存,默认值为10。
                public uint vKeyAbort;                  // 终止流捕获的虚拟键盘码,默认值为VK_ESCAPE
                [MarshalAs(UnmanagedType.Bool)]
                public bool fAbortLeftMouse;           // 终止鼠标左键标志位,如果该值为真,则在流捕获过程中如果点击鼠标左键则该捕获终止,默认值为真。
                public bool fAbortRightMouse;                 // Abort on right mouse?
                public bool fLimitEnabled;                   // 捕获操作时间限制,如果为真,则时间到了以后捕获操作终止,默认为假
                public uint wTimeLimit;                     // 具体终止时间,只有 fLimitEnabled是真时.该位才有效
                public bool fMCIControl;                   // Use MCI video source?
                public bool fStepMCIDevice;               // Step MCI device?MCI 设备标志。
                public int dwMCIStartTime;               // Time to start in MS
                public int dwMCIStopTime;               // Time to stop in MS
                public bool fStepCaptureAt2x;          // Perform spatial averaging 2x
                public int wStepCaptureAverageFrames; // 当基于平均采样来创建桢时,桢的采样时间,典型值是5
                public int dwAudioBufferSize;        // 音频缓存的尺寸,如果用默认值0,缓存尺寸是最大0.5秒,或10k字节。
                public int fDisableWriteCache;      // Attempt to disable write cache
                public int AVStreamMaster;         //音视频同步标志。
            }
            //=========================================================================================================================================

            //=================================================CAPDRIVERCAPS结构=======================================================================
            //CAPDRIVERCAPS定义了捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等; 
            [StructLayout(LayoutKind.Sequential)]
            public struct CAPDRIVERCAPS
            {
                [MarshalAs(UnmanagedType.U2)]
                public UInt16 wDeviceIndex;         //捕获驱动器的索引值,该值可以由0到9变化。
                [MarshalAs(UnmanagedType.Bool)]
                public bool fHasOverlay;            // 视频叠加标志,如果设备支持视频叠加这该位是真。
                [MarshalAs(UnmanagedType.Bool)]
                public bool fHasDlgVideoSource;     //视频资源对话框标志位,如果设备支持视频选择、控制对话框,该值为真。
                [MarshalAs(UnmanagedType.Bool)]
                public bool fHasDlgVideoFormat;     //视频格式对话框标志位,如果设备支持对视频格式对话框的选择,该位真。
                [MarshalAs(UnmanagedType.Bool)]
                public bool fHasDlgVideoDisplay;    //视频展示对话框标志位,如果设备支持对视频捕获缓存区的重新播放,该位是真。
                [MarshalAs(UnmanagedType.Bool)]
                public bool fCaptureInitialized;    //捕获安装标志位,如果捕获驱动器已经成功连接,该值为真。
                //[MarshalAs(UnmanagedType.Bool)]
                public bool fDriverSuppliesPalettes; //驱动器调色板标志位,如果驱动器能创建调色板,则该位是真。
                [MarshalAs(UnmanagedType.I4)]
                public int hVideoIn;
                [MarshalAs(UnmanagedType.I4)]
                public int hVideoOut;
                [MarshalAs(UnmanagedType.I4)]
                public int hVideoExtIn;
                [MarshalAs(UnmanagedType.I4)]
                public int hVideoExtOut;
            }
            //=========================================================================================================================================


            //=====================================================CAPSTATUS结构========================================================================
            //CAPSTATUS定义了捕获窗口的当前状态,如图像的宽、高等;
            [StructLayout(LayoutKind.Sequential)]
            public struct CAPSTATUS
            {
                public int uiImageWidth;                         //图像宽度
                public int uiImageHeight;                       //图像高度
                public bool fLiveWindow;                       //活动窗口标记,如果窗口正以预览的方式展示图像,那么该值为真
                public bool fOverlayWindow;                   //叠加窗口标志位,如果正在使用硬件叠加,则该位是真。
                public bool fScale;                          //输入所放标志位,如果窗口是正在缩放视频到客户区,那么该位是真。当使用硬件叠加时,改位无效。
                public Point ptScroll;                      //被展示在窗口客户区左上角的那个象素的x、y坐标偏移量。
                public bool fUsingDefaultPalette;          //默认调色板标志位,如果捕获窗口正在使用当前默认调色板,该值为真
                public bool fAudioHardware;               // 音频硬件标志位,如果系统已经安装了音频硬件,该值为真。
                public bool fCapFileExists;              //捕获文件标志位,如果一个捕获文件已经被创建,该值为真
                public int dwCurrentVideoFrame;         // 当前或最近流捕获过程中,所处理的桢的数目。包括丢弃的桢。
                public int dwCurrentVideoFramesDropped;//当前流捕获过程中丢弃的桢的数目。
                public int dwCurrentWaveSamples;      // # of wave samples cap'td
                public int dwCurrentTimeElapsedMS;   // 从当前流捕获开始计算,程序所用的时间,以毫秒为单位。
                public IntPtr hPalCurrent;          // 当前剪切板的句柄。
                public bool fCapturingNow;         // 捕获标志位,当捕获是正在进行时,改位是真
                public int dwReturn;              // 错误返回值,当你的应用程序不支持错误回调函数时可以应用改位
                public int wNumVideoAllocated;   // 被分配的视频缓存的数目。
                public int wNumAudioAllocated;  // 被分配的音频缓存的数目。
            }
            //=========================================================================================================================================


            #endregion 结构 VIDEOHDR|BITMAPINFOHEADER|BITMAPINFO|CAPTUREPARMS|CAPDRIVERCAPS|CAPSTATUS

        }
        public class cVideo     //视频类
        {
            public bool flag = true;
            private IntPtr lwndC;       //保存无符号句柄
            private IntPtr mControlPtr; //保存管理指示器
            private int mWidth;
            private int mHeight;
            public delegate void RecievedFrameEventHandler(byte[] data);
            public event RecievedFrameEventHandler RecievedFrame;

            public VideoAPI.CAPTUREPARMS Capparms;
            private VideoAPI.FrameEventHandler mFrameEventHandler;
            public VideoAPI.CAPDRIVERCAPS CapDriverCAPS;//捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等;
            public VideoAPI.CAPSTATUS CapStatus;//该结构用于保存视频设备捕获窗口的当前状态,如图像的宽、高等
            string strFileName;
            public cVideo(IntPtr handle, int width, int height)
            {
                CapDriverCAPS = new VideoAPI.CAPDRIVERCAPS();//捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等;
                CapStatus = new VideoAPI.CAPSTATUS();//该结构用于保存视频设备捕获窗口的当前状态,如图像的宽、高等
                mControlPtr = handle; //显示视频控件的句柄
                mWidth = width;      //视频宽度
                mHeight = height;    //视频高度
            }
            /// <summary>
            /// 打开视频设备
            /// </summary>
            public bool StartWebCam()
            {
                //byte[] lpszName = new byte[100];
                //byte[] lpszVer = new byte[100];
                //VideoAPI.capGetDriverDescriptionA(0, lpszName, 100, lpszVer, 100);
                //this.lwndC = VideoAPI.capCreateCaptureWindowA(lpszName, VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);
                //if (VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))
                //{
                //    VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 100, 0);
                //    VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEW, true, 0);
                //    return true;
                //}
                //else
                //{
                //    return false;
                //}
                this.lwndC = VideoAPI.capCreateCaptureWindow("", VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);//AVICap类的捕捉窗口
                VideoAPI.FrameEventHandler FrameEventHandler = new VideoAPI.FrameEventHandler(FrameCallback);
                VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_ERROR, 0, 0);//注册错误回调函数
                VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_STATUS, 0, 0);//注册状态回调函数 
                VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);//注册视频流回调函数
                VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_FRAME, 0, FrameEventHandler);//注册帧回调函数

                //if (!CapDriverCAPS.fCaptureInitialized)//判断当前设备是否被其他设备连接已经连接
                //{

                if (VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))
                {
                    //-----------------------------------------------------------------------
                    VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_DRIVER_GET_CAPS, VideoAPI.SizeOf(CapDriverCAPS), ref CapDriverCAPS);//获得当前视频 CAPDRIVERCAPS定义了捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等;
                    VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_STATUS, VideoAPI.SizeOf(CapStatus), ref CapStatus);//获得当前视频流的尺寸 存入CapStatus结构

                    VideoAPI.BITMAPINFO bitmapInfo = new VideoAPI.BITMAPINFO();//设置视频格式 (height and width in pixels, bits per frame). 
                    bitmapInfo.bmiHeader = new VideoAPI.BITMAPINFOHEADER();
                    bitmapInfo.bmiHeader.biSize = VideoAPI.SizeOf(bitmapInfo.bmiHeader);
                    bitmapInfo.bmiHeader.biWidth = mWidth;
                    bitmapInfo.bmiHeader.biHeight = mHeight;
                    bitmapInfo.bmiHeader.biPlanes = 1;
                    bitmapInfo.bmiHeader.biBitCount = 24;
                    VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 40, 0);//设置在PREVIEW模式下设定视频窗口的刷新率 设置每40毫秒显示一帧,即显示帧速为每秒25帧
                    VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_SCALE, 1, 0);//打开预览视频的缩放比例
                    VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_VIDEOFORMAT, VideoAPI.SizeOf(bitmapInfo), ref bitmapInfo);

                    this.mFrameEventHandler = new VideoAPI.FrameEventHandler(FrameCallback);
                    this.capSetCallbackOnFrame(this.lwndC, this.mFrameEventHandler);


                    VideoAPI.CAPTUREPARMS captureparms = new VideoAPI.CAPTUREPARMS();
                    VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_SEQUENCE_SETUP, VideoAPI.SizeOf(captureparms), ref captureparms);
                    if (CapDriverCAPS.fHasOverlay)
                    {
                        VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_OVERLAY, 1, 0);//启用叠加 注:据说启用此项可以加快渲染速度    
                    }
                    VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEW, 1, 0);//设置显示图像启动预览模式 PREVIEW
                    VideoAPI.SetWindowPos(this.lwndC, 0, 0, 0, mWidth, mHeight, VideoAPI.SWP_NOZORDER | VideoAPI.SWP_NOMOVE);//使捕获窗口与进来的视频流尺寸保持一致
                    return true;
                }
                else
                { 
                  
                    flag = false;
                    return false;
                }
            }
            public void get()
            {
                VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_SEQUENCE_SETUP, VideoAPI.SizeOf(Capparms), ref Capparms);
            }
            public void set()
            {
                VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_SEQUENCE_SETUP, VideoAPI.SizeOf(Capparms), ref Capparms);
            }
            private bool capSetCallbackOnFrame(IntPtr lwnd, VideoAPI.FrameEventHandler lpProc)
            {
                return VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_FRAME, 0, lpProc);
            }
            /// <summary>
            /// 关闭视频设备
            /// </summary>
            public void CloseWebcam()
            {
                VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_DISCONNECT, 0, 0);
            }
            ///   <summary>   
            ///   拍照
            ///   </summary>   
            ///   <param   name="path">要保存bmp文件的路径</param>   
            public void GrabImage(IntPtr hWndC, string path)
            {
                IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
                VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SAVEDIB, 0, hBmp.ToInt32());
            }
            public void StarKinescope(string path)
            {
                strFileName = path;
                string dir=path.Remove(path.LastIndexOf("\\"));
                if (!File.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
                int hBmp = Marshal.StringToHGlobalAnsi(path).ToInt32();
               bool b= VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_FILE_SET_CAPTURE_FILE, 0, hBmp);
              b=  VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SEQUENCE, 0, 0);
            }
            /// <summary>
            /// 停止录像
            /// </summary>
            public void StopKinescope()
            {
                VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_STOP, 0, 0);
            }
            private void FrameCallback(IntPtr lwnd, IntPtr lpvhdr)
            {
                VideoAPI.VIDEOHDR videoHeader = new VideoAPI.VIDEOHDR();
                byte[] VideoData;
                videoHeader = (VideoAPI.VIDEOHDR)VideoAPI.GetStructure(lpvhdr, videoHeader);
                VideoData = new byte[videoHeader.dwBytesUsed];
                VideoAPI.Copy(videoHeader.lpData, VideoData);
                if (this.RecievedFrame != null)
                    this.RecievedFrame(VideoData);
            }
            private Thread myThread;

            public void CompressVideoFfmpeg()
            {
                //myThread = new Thread(new ThreadStart(testfn));
                //myThread.Start();
                testfn();
            }
            private void testfn() // 压缩视频
            {
                string file_name = strFileName;
                string command_line = " -i " + file_name + " -vcodec libx264 -cqp 25 -y " + file_name.Replace(".avi", "_264") + ".avi";
                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                proc.StartInfo.WorkingDirectory = Application.StartupPath;
                proc.StartInfo.UseShellExecute = false; //use false if you want to hide the window
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.FileName = "ffmpeg";
                proc.StartInfo.Arguments = command_line;
                proc.Start();
                proc.WaitForExit();
                proc.Close();

                // 删除原始avi文件
                FileInfo file = new FileInfo(file_name);
                if (file.Exists)
                {
                    try
                    {
                        file.Delete(); //删除单个文件
                    }
                    catch(Exception e) {
                        Common.writeLog("删除视频文件“"+file_name+"”出错!"+e.Message);
                    }
                }
                //myThread.Abort();
            }
        }
    }

    用到的压缩软件http://download.csdn.net/source/2453028


    调用:
    cVideo video = new cVideo(picCapture.Handle, 640, 480);
    //打开视频
    if (video.StartWebCam(320, 240))
                {
                    video.get();
                    video.Capparms.fYield = true;
                    video.Capparms.fAbortLeftMouse = false;
                    video.Capparms.fAbortRightMouse = false;
                    video.Capparms.fCaptureAudio = false;
                    video.Capparms.dwRequestMicroSecPerFrame = 0x9C40; // 设定帧率25fps: 1*1000000/25 = 0x9C40
                    video.set();
                    setCap();
                    VideoStart = true;
                }
    //开始录像
      video.StarKinescope(System.IO.Path.Combine(Record.VideoDir, System.DateTime.Now.ToString("yyyy-MM-dd(HH.mm.ss)") + ".avi")))
    //停止录像
    video.StopKinescope();
    //压缩(压缩效率还是很低,不要用于实际开发)
     video.CompressVideoFfmpeg();

    展开全文
  • 简仪是一家利用微软.net/C#技术开发开源数据采集的公司,软件有开源的锐视测控平台,硬件涵盖各种性能、接口的数据采集卡。既然是基于.net/C#技术的,编程使用的微软的Visual Studio,这就意味着简仪的数据采集和NI...
    说起简仪的USB-101口袋数据采集卡,就得先说说简仪公司(www.jytek.com)。简仪是一家利用微软.net/C#技术开发开源数据采集的公司,软件有开源的锐视测控平台,硬件涵盖各种性能、接口的数据采集卡和PXI工控机。

    初衷

    对于追求技术实践的博主,把简仪数据采集卡和NI的LabVIEW生拉硬拽扯到一起,是博主努力的方向。

    关于简仪数据采集卡的驱动程序

    简仪公司是基于微软.net/C#技术的,那么简仪的软件开发环境首推的是微软自家的Visual Studio,这就意味着简仪的数据采集和NI的LabVIEW基本没有交集。为什么这里会提到NI LabVIEW?因为在数据采集领域LabVIEW有不可忽视的份额。当然,我们也注意到简仪官方是不提供数据采集卡在使用LabVIEW方面的技术支持。

    简单技术背景

    简仪的数据采集卡提供的是基于.net的驱动程序,一般情况下非NI生产的数据采集卡一般是提供.dll形式的SDK,比如Digilent、研华、阿尔泰等等数据采集卡的厂商,而NI生产的数据采集卡是天生支持自家的数据采集DAQmx驱动方法的,DAQmx提供丰富的数据采集功能支持。

    因此在LabVIEW支持数据采集卡的技术方面,通常是三种方法:

    第一种:NI自己生产的数据采集卡使用DAQmx驱动,在LabVIEW中通过DAQmx驱动编写数据采集程序。
    第二种:使用数据采集卡厂商提供的DLL,在LabVIEW中导入DLL方式,再将DLL中的函数转换成对应的子vi。当然,还有类似的调用库函数节点方法。在此都归为第二种方法。
    第三种:LabVIEW在互联接口方面支持.net调用,所以理论上说LabVIEW调用.net开发的驱动,可以驱动第三方数据采集卡。

    现实情况

    博主接触的采用.net开发驱动的数据采集卡少,目前只接触到简仪的卡,而且查阅有关数据采集卡的.net开发的文献也几乎没有。

    工作进度

    在LabVIEW中编程,除了看一些基本的教程以外,最大帮助的应该就是LabVIEW的范例查找器。在里面找到互联接口——.net的例子,范例学起来。
    .net的范例并不是关于数据采集的,是通过.net构造的函数进行运算的,但也能通过这个例子了解LabVIEW中调用.net函数是怎么实现的。

    实践过程通过LabVIEW 2015版本实现,相对而言是顺利的,但也遇到了无数次的蓝屏经历。好在博主不断重启电脑。。。克服了蓝屏。。。

    TLA发布简仪USB-101数据采集卡LabVIEW编程视频


    从录制的视频中可以看到,LabVIEW中运行的vi成功的驱动的了简仪的USB-101数据采集卡,并实现了了模拟信号的采集,采集到的信号在LabVIEW中进行了频率和幅值的测量。模拟信号源由NI的myDAQ的AO提供。

    通用工具发布

    接下来直接的干货,免费提供软件下载,软件的名字叫DAQWare for JY USB-101,是LabVIEW环境下开发的简仪USB-101数据采集卡的数据采集工具软件,免费的。目前提供双通道的模拟信号采集功能和数据存储功能。
    在这里插入图片描述

    DAQWare for JY USB-101下载地址

    下载:https://www.lanzous.com/i7mp2ab 密码:9qbi


    使用方法:

    (DAQWare for JY USB101支持Win7、Win10操作系统,LabVIEW Run-time Engine支持2015版本及以上。)

    1、下载简仪科技USB-101驱动,下载地址:https://www.lanzous.com/i7mqlde 密码:680f

    2、在计算机的USB口插入USB-101口袋数据采集卡。

    3、计算机设备管理器的通用总线控制器项目中发现新的设备JYTEK USBDAQ 101 Device。

    4、下载并安装LabVIEW 2105 Run-time Engine,下载地址:http://ftp.ni.com/support/softlib/labview/labview_runtime/2015%20SP1/Windows/f1/LVRTE2015SP1_f1Patchstd.exe

    5、解压DAQWare for JY USB-101压缩文件。

    6、运行DAQWare for JY USB101.exe开始测量。

    展开全文
  • 这是一个擦PG的活,由于前期和甲方没有沟通好,导致甲方Vxworks没办法读USB HID触摸屏的数据,然后同事摊手就绕到我这来了。我的第一想法是甲方技术能力不足,USB Host获取不到正确数据怪我咯?在后面的联系中才知道...
  • 本攻略中软件兼容的简仪数据采集卡为USB101口袋数据采集卡(http://www.jytek.com/product/278163686)。 应用范围 攻略中涉及的内容为在LabVIEW中通过数据采集助手快速实现模拟信号(Analog Input)数据采集编程。 ...
  • C#中用DirectShow做的媒体播放机概述:我的这个程序仅仅只是告诉大家如何用DirectShow 在C#中做一个播放机,世上并不能有太多的功能.也许你只要花上五分种就可以解决问题.是的如果你用的是IDE,我感保证一切都只是用...
  • 基于USB的虚拟示波

    2010-11-02 11:24:00
     最近在研发一款基于USB2.0的虚拟示波USB与计算机通信的接口电路已经开发完毕!期待数据采集电路的开发能顺利完成!
  • VS2010C#工程,接收单片机系统串口传输的4字节温度数据并显示,附带数据库查询指令参考 (本科生时期项目,没有数据表,谨慎下载)
  • 这个项目是关于如何从网络摄像头或者视频文件(*.AVI)中捕获视频的,这个项目是用C#和OPENCV编写的。 这将有助于那些喜欢C#和OpenCV环境的人。这个程序完全基于Visual Studio 2010 version C#.NET环境。这个程序...
  • 一、蓝牙模块XLBT232‐D01介绍(外部设备蓝牙) 1.1、蓝牙模块简介 XLBT232-D0101蓝牙模块采用CSR BlueCore 芯片,配置6-8Mbit 的软件存储空间, 支持AT 指令,用户可根据需要更改SPP 角色(主、从模式)以及串口...
  • usb协议基础

    2016-12-18 01:59:05
    usb简介usb是一种支持热插拔的高速串行传输总线,使用差分信号来传输数据,高速模式下传输速率为480Mb/S,全速模式为12Mb/S,低速模式为1.5Mb/S,USB支持“总线供电”和“自供电”两种供电模式,在总线模式下,设备...
  • 很多人都为两个usb摄像头同步采集图像而苦恼,而且在网上也有很多基于opencv的usb摄像头的采集图像方法。 我也曾经为了实现同步采集而烦恼了。。。 可现在终于知道了很简单而且很好地方法。   方法如下: 首先...
  • 一、问题描述 我用Aforge类库打开了本地的摄像头,可以在PC看到实时画面。但是,我想把该实时画面通过局域网络,传输给另一台PC。Aforge类库或Socket的...(六)WPF/C# 使用Aforge类库打开USB摄像头:实现拍照/重...
  • 《Visual C#.NET串口通信及测控应用典型实例》是一本书籍,该书从工程应用的角度出发,通过8个典型应用实例,包括PC与PC、PC与单片机、PC与PLC、PC与远程I/O模块、PC与智能仪器、PC与无线数传模块、Pc与USB数据采集...
  • 最近公司开发一个项目 需要用到海康的视频sh
  • 最近由于兴趣学习了下在C#上使用AForge录制摄像头视频并压缩编码。总体上来说这个第三方.net视觉开发库还是比较稳定的(AForge lib下载、离线帮助文档下载)。但是由于这个第三方库维护不怎么样,导致会出现不兼容的...
1 2 3 4 5 ... 20
收藏数 748
精华内容 299
热门标签