zoukankan      html  css  js  c++  java
  • C#写的一个视频转换解码器

    C#写的一个视频转换解码器

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Drawing;
      6 using System.Runtime.InteropServices;
      7 using System.Threading;
      8 using System.Windows.Forms;
      9 using System.IO;
     10 
     11 namespace Basic
     12 {
     13     public class VideoAPI  //视频API类
     14     {
     15         //  视频API调用
     16         [DllImport("avicap32.dll")]//包含了执行视频捕获的函数,它给AVI文件I/O和视频、音频设备驱动程序提供一个高级接口
     17         public static extern IntPtr capCreateCaptureWindow(string lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hwndParent, int nID);
     18         [DllImport("AVICAP32.dll", CharSet = CharSet.Unicode)]
     19         public static extern bool capGetDriverDescription(int wDriverIndex, StringBuilder lpszName, int cbName, StringBuilder lpszVer, int cbVer);
     20         [DllImport("avicap32.dll")]
     21         public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
     22         [DllImport("avicap32.dll")]
     23         public static extern bool capGetDriverDescriptionA(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer);
     24         [DllImport("User32.dll")]
     25         public static extern bool SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam);
     26         [DllImport("User32.dll")]
     27         public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, int lParam);
     28         [DllImport("User32.dll")]
     29         public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
     30         [DllImport("User32.dll")]
     31         public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, FrameEventHandler lParam);
     32         [DllImport("User32.dll")]
     33         public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref BITMAPINFO lParam);
     34         [DllImport("User32.dll")]
     35         public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPDRIVERCAPS lParam);
     36         [DllImport("User32.dll")]
     37         public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPTUREPARMS lParam);
     38         [DllImport("User32.dll")]
     39         public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPSTATUS lParam);
     40         [DllImport("User32.dll")]
     41         public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
     42         [DllImport("avicap32.dll")]
     43         public static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize);
     44 
     45         //  常量
     46         // public const int WM_USER = 0x400;
     47         public const int WS_CHILD = 0x40000000;
     48         public const int WS_VISIBLE = 0x10000000;
     49 
     50         public const int SWP_NOMOVE = 0x2;
     51         public const int SWP_NOZORDER = 0x4;
     52         // public const int WM_CAP_DRIVER_CONNECT = WM_USER + 10;
     53         //   public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + 11;
     54         public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + 5;
     55         //   public const int WM_CAP_SET_PREVIEW = WM_USER + 50;
     56         //  public const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52;
     57         //  public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + 45;
     58         //   public const int WM_CAP_START = WM_USER;
     59         public const int WM_CAP_SAVEDIB = WM_CAP_START + 25;
     60 
     61         public const string avicap32 = "avicap32.dll";
     62         public const int WM_USER = 1024;
     63         /// <summary>
     64         ///WM_CAP_START=WM_USER=1024
     65         /// </summary>
     66         public const int WM_CAP_START = WM_USER;
     67 
     68         // start of unicode messages
     69         /// <summary>
     70         /// 开始   WM_USER + 100=1124
     71         /// </summary>
     72         public const int WM_CAP_UNICODE_START = WM_USER + 100; //开始   1124
     73         /// <summary>
     74         /// /获得 CAPSTR EAMPTR   
     75         /// WM_CAP_START + 1=1025
     76         /// </summary>
     77         public const int WM_CAP_GET_CAPSTREAMPTR = (WM_CAP_START + 1); //获得 CAPSTR EAMPTR
     78         /// <summary>
     79         /// 设置收回错误   WM_CAP_START + 2=1026
     80         /// </summary>
     81         public const int WM_CAP_SET_CALLBACK_ERROR = (WM_CAP_START + 2); //设置收回错误
     82         /// <summary>
     83         /// 设置收回状态 WM_CAP_START + 3=1027
     84         /// </summary>
     85         public const int WM_CAP_SET_CALLBACK_STATUS = (WM_CAP_START + 3); //设置收回状态
     86         /// <summary>
     87         /// 设置收回出产  WM_CAP_START + 4=1028
     88         /// </summary>
     89         public const int WM_CAP_SET_CALLBACK_YIELD = (WM_CAP_START + 4); //设置收回出产
     90         /// <summary>
     91         /// 设置收回结构  WM_CAP_START + 5=1029
     92         /// </summary>
     93         public const int WM_CAP_SET_CALLBACK_FRame = (WM_CAP_START + 5); //设置收回结构
     94         /// <summary>
     95         /// 设置收回视频流  WM_CAP_START + 6=1030
     96         /// </summary>
     97         public const int WM_CAP_SET_CALLBACK_VIDEOSTREAM = (WM_CAP_START + 6); //设置收回视频流
     98         /// <summary>
     99         /// 设置收回视频波流  WM_CAP_START +7=1031
    100         /// </summary>
    101         public const int WM_CAP_SET_CALLBACK_WAVESTREAM = (WM_CAP_START + 7); //设置收回视频波流
    102         /// <summary>
    103         /// 获得使用者数据 WM_CAP_START + 8=1032
    104         /// </summary>
    105         public const int WM_CAP_GET_USER_DATA = (WM_CAP_START + 8); //获得使用者数据
    106         /// <summary>
    107         /// 设置使用者数据 WM_CAP_START + 9=1033
    108         /// </summary>
    109         public const int WM_CAP_SET_USER_DATA = (WM_CAP_START + 9); //设置使用者数据
    110         /// <summary>
    111         /// 驱动程序连接  WM_CAP_START + 10=1034
    112         /// </summary>
    113         public const int WM_CAP_DRIVER_CONNECT = (WM_CAP_START + 10); //驱动程序连接
    114         /// <summary>
    115         /// 断开启动程序连接 WM_CAP_START + 11=1035
    116         /// </summary>
    117         public const int WM_CAP_DRIVER_DISCONNECT = (WM_CAP_START + 11); //断开启动程序连接
    118         /// <summary>
    119         /// 获得驱动程序名字 WM_CAP_START + 12=1036
    120         /// </summary>
    121         public const int WM_CAP_DRIVER_GET_NAME = (WM_CAP_START + 12); //获得驱动程序名字
    122         /// <summary>
    123         /// 获得驱动程序版本 WM_CAP_START + 13=1037
    124         /// </summary>
    125         public const int WM_CAP_DRIVER_GET_VERSION = (WM_CAP_START + 13); //获得驱动程序版本
    126         /// <summary>
    127         /// 获得驱动程序帽子 WM_CAP_START + 14=1038
    128         /// </summary>
    129         public const int WM_CAP_DRIVER_GET_CAPS = (WM_CAP_START + 14); //获得驱动程序帽子
    130         /// <summary>
    131         /// 设置捕获文件 WM_CAP_START + 20=1044
    132         /// </summary>
    133         public const int WM_CAP_FILE_SET_CAPTURE_FILE = (WM_CAP_START + 20); //设置捕获文件
    134         /// <summary>
    135         /// 获得捕获文件 WM_CAP_START + 21=1045
    136         /// </summary>
    137         public const int WM_CAP_FILE_GET_CAPTURE_FILE = (WM_CAP_START + 21); //获得捕获文件
    138         /// <summary>
    139         /// 另存文件为  WM_CAP_START + 23=1047
    140         /// </summary>
    141         public const int WM_CAP_FILE_SAVEAS = (WM_CAP_START + 23); //另存文件为
    142         /// <summary>
    143         /// 保存文件    WM_CAP_START + 25=1049
    144         /// </summary>
    145         public const int WM_CAP_FILE_SAVEDIB = (WM_CAP_START + 25); //保存文件
    146 
    147         // out of order to save on ifdefs
    148         /// <summary>
    149         /// 分派文件  WM_CAP_START + 22=1044
    150         /// </summary>
    151         public const int WM_CAP_FILE_ALLOCATE = (WM_CAP_START + 22); //分派文件
    152         /// <summary>
    153         /// 设置开始文件  WM_CAP_START + 24=1046
    154         /// </summary>
    155         public const int WM_CAP_FILE_SET_INFOCHUNK = (WM_CAP_START + 24); //设置开始文件
    156         /// <summary>
    157         /// 编辑复制   WM_CAP_START + 30=1054
    158         /// </summary>
    159         public const int WM_CAP_EDIT_COPY = (WM_CAP_START + 30); //编辑复制
    160         /// <summary>
    161         /// 设置音频格式  WM_CAP_START + 35=1059
    162         /// </summary>
    163         public const int WM_CAP_SET_AUDIOFORMAT = (WM_CAP_START + 35); //设置音频格式
    164         /// <summary>
    165         /// 捕获音频格式  WM_CAP_START + 36=1060
    166         /// </summary>
    167         public const int WM_CAP_GET_AUDIOFORMAT = (WM_CAP_START + 36); //捕获音频格式
    168         /// <summary>
    169         /// 打开视频格式设置对话框  WM_CAP_START + 41=1065
    170         /// </summary>
    171         public const int WM_CAP_DLG_VIDEOFORMAT = (WM_CAP_START + 41); //1065 打开视频格式设置对话框
    172         /// <summary>
    173         /// 打开属性设置对话框,设置对比度、亮度等   WM_CAP_START + 42=1066
    174         /// </summary>
    175         public const int WM_CAP_DLG_VIDEOSOURCE = (WM_CAP_START + 42); //1066 打开属性设置对话框,设置对比度、亮度等。
    176         /// <summary>
    177         /// 打开视频显示 WM_CAP_START + 43=1067
    178         /// </summary>
    179         public const int WM_CAP_DLG_VIDEODISPLAY = (WM_CAP_START + 43); //1067 打开视频显示
    180         /// <summary>
    181         /// 获得视频格式 WM_CAP_START + 44=1068
    182         /// </summary>
    183         public const int WM_CAP_GET_VIDEOFORMAT = (WM_CAP_START + 44); //1068 获得视频格式
    184         /// <summary>
    185         /// 设置视频格式 WM_CAP_START + 45=1069
    186         /// </summary>
    187         public const int WM_CAP_SET_VIDEOFORMAT = (WM_CAP_START + 45); //1069 设置视频格式
    188         /// <summary>
    189         /// 打开压缩设置对话框 WM_CAP_START + 46=1070
    190         /// </summary>
    191         public const int WM_CAP_DLG_VIDEOCOMPRESSION = (WM_CAP_START + 46); //1070 打开压缩设置对话框
    192         /// <summary>
    193         /// 设置预览 WM_CAP_START + 50=1074
    194         /// </summary>
    195         public const int WM_CAP_SET_PREVIEW = (WM_CAP_START + 50); //设置预览
    196         /// <summary>
    197         /// 设置覆盖 WM_CAP_START + 51=1075
    198         /// </summary>
    199         public const int WM_CAP_SET_OVERLAY = (WM_CAP_START + 51); //设置覆盖
    200         /// <summary>
    201         /// 设置预览比例 WM_CAP_START + 52=1076
    202         /// </summary>
    203         public const int WM_CAP_SET_PREVIEWRATE = (WM_CAP_START + 52); //设置预览比例
    204         /// <summary>
    205         /// 设置刻度 WM_CAP_START + 53=1077
    206         /// </summary>
    207         public const int WM_CAP_SET_SCALE = (WM_CAP_START + 53); //设置刻度
    208         /// <summary> 
    209         /// 获得状态 WM_CAP_START + 54=1078
    210         /// </summary>
    211         public const int WM_CAP_GET_STATUS = (WM_CAP_START + 54); //获得状态
    212         /// <summary>
    213         /// 设置卷 WM_CAP_START + 55=1079
    214         /// </summary>
    215         public const int WM_CAP_SET_SCROLL = (WM_CAP_START + 55); //设置卷
    216         /// <summary>
    217         /// 逮捕结构 WM_CAP_START + 60=1084
    218         /// </summary>
    219         public const int WM_CAP_GRAB_FRame = (WM_CAP_START + 60); //逮捕结构
    220         /// <summary>
    221         /// 停止逮捕结构 WM_CAP_START + 61=1085
    222         /// </summary>
    223         public const int WM_CAP_GRAB_FRame_NOSTOP = (WM_CAP_START + 61); //停止逮捕结构
    224         /// <summary>
    225         /// 次序 WM_CAP_START + 62=1086
    226         /// </summary>
    227         public const int WM_CAP_SEQUENCE = (WM_CAP_START + 62); //次序
    228         /// <summary>
    229         /// 没有文件 WM_CAP_START + 63=1087
    230         /// </summary>
    231         public const int WM_CAP_SEQUENCE_NOFILE = (WM_CAP_START + 63); //没有文件
    232         /// <summary>
    233         /// 设置安装次序 WM_CAP_START + 64=1088
    234         /// </summary>
    235         public const int WM_CAP_SET_SEQUENCE_SETUP = (WM_CAP_START + 64); //设置安装次序
    236         /// <summary>
    237         /// 获得安装次序 WM_CAP_START + 65=1089
    238         /// </summary>
    239         public const int WM_CAP_GET_SEQUENCE_SETUP = (WM_CAP_START + 65); //获得安装次序
    240         /// <summary>
    241         /// 设置媒体控制接口 WM_CAP_START + 66=1090
    242         /// </summary>
    243         public const int WM_CAP_SET_MCI_DEVICE = (WM_CAP_START + 66); //设置媒体控制接口
    244         /// <summary>
    245         /// 获得媒体控制接口 WM_CAP_START + 67=1091
    246         /// </summary>
    247         public const int WM_CAP_GET_MCI_DEVICE = (WM_CAP_START + 67); //获得媒体控制接口 
    248         /// <summary>
    249         /// 停止 WM_CAP_START + 68=1092
    250         /// </summary>
    251         public const int WM_CAP_STOP = (WM_CAP_START + 68); //停止
    252         /// <summary>
    253         /// 异常中断 WM_CAP_START + 69=1093
    254         /// </summary>
    255         public const int WM_CAP_ABORT = (WM_CAP_START + 69); //异常中断
    256         /// <summary>
    257         /// 打开单一的结构 WM_CAP_START + 68=1094
    258         /// </summary>
    259         public const int WM_CAP_SINGLE_FRame_OPEN = (WM_CAP_START + 70); //打开单一的结构
    260         /// <summary>
    261         /// 关闭单一的结构 WM_CAP_START + 71=1095
    262         /// </summary>
    263         public const int WM_CAP_SINGLE_FRame_CLOSE = (WM_CAP_START + 71); //关闭单一的结构
    264         /// <summary>
    265         /// 单一的结构 WM_CAP_START + 72=1096
    266         /// </summary>
    267         public const int WM_CAP_SINGLE_FRame = (WM_CAP_START + 72); //单一的结构
    268         /// <summary>
    269         /// 打开视频 WM_CAP_START + 80=1104
    270         /// </summary>
    271         public const int WM_CAP_PAL_OPEN = (WM_CAP_START + 80); //打开视频
    272         /// <summary>
    273         /// 保存视频 WM_CAP_START + 81=1105
    274         /// </summary>
    275         public const int WM_CAP_PAL_SAVE = (WM_CAP_START + 81); //保存视频
    276         /// <summary>
    277         /// 粘贴视频 WM_CAP_START + 82=1106
    278         /// </summary>
    279         public const int WM_CAP_PAL_PASTE = (WM_CAP_START + 82); //粘贴视频
    280         /// <summary>
    281         /// 自动创造 WM_CAP_START + 83=1107
    282         /// </summary>
    283         public const int WM_CAP_PAL_AUTOCREATE = (WM_CAP_START + 83); //自动创造
    284         /// <summary>
    285         /// 手动创造 WM_CAP_START + 84=1108
    286         /// </summary>
    287         public const int WM_CAP_PAL_MANUALCREATE = (WM_CAP_START + 84); //手动创造
    288 
    289         // Following added post VFW 1.1
    290         /// <summary>
    291         /// 设置收回的错误 WM_CAP_START + 85=1109
    292         /// </summary>
    293         public const int WM_CAP_SET_CALLBACK_CAPCONTROL = (WM_CAP_START + 85); // 设置收回的错误
    294 
    295         public const int WM_CAP_END = WM_CAP_SET_CALLBACK_CAPCONTROL;
    296 
    297         public delegate void FrameEventHandler(IntPtr lwnd, IntPtr lpVHdr);
    298 
    299         #region 公共函数
    300         //公共函数
    301         public static object GetStructure(IntPtr ptr, ValueType structure)
    302         {
    303             return Marshal.PtrToStructure(ptr, structure.GetType());
    304         }
    305 
    306         public static object GetStructure(int ptr, ValueType structure)
    307         {
    308             return GetStructure(new IntPtr(ptr), structure);
    309         }
    310 
    311         public static void Copy(IntPtr ptr, byte[] data)
    312         {
    313             Marshal.Copy(ptr, data, 0, data.Length);
    314         }
    315 
    316         public static void Copy(int ptr, byte[] data)
    317         {
    318             Copy(new IntPtr(ptr), data);
    319         }
    320 
    321         public static int SizeOf(object structure)
    322         {
    323             return Marshal.SizeOf(structure);
    324         }
    325         #endregion 公共函数
    326         #region 结构 VIDEOHDR|BITMAPINFOHEADER|BITMAPINFO|CAPTUREPARMS|CAPDRIVERCAPS|CAPSTATUS
    327         //========================================================VideoHdr 结构=====================================================================
    328         //VideoHdr 结构   定义了视频数据块的头信息,在编写回调函数时常用到其数据成员lpData(指向数据缓存的指针)和dwBufferLength(数据缓存的大小)。     
    329         //视频帧到缓存的捕获则需要应用回调函数和相应的数据块结构 VIDEOHDR 
    330         [StructLayout(LayoutKind.Sequential)]
    331         public struct VIDEOHDR
    332         {
    333             public IntPtr lpData;              /* 指向数据缓存的指针 */
    334             public int dwBufferLength;         /* 数据缓存的大小 */
    335             public int dwBytesUsed;            /* Bytes actually used */
    336             public int dwTimeCaptured;         /* Milliseconds from start of stream */
    337             public int dwUser;                 /* for client's use */
    338             public int dwFlags;                /* assorted flags (see defines) */
    339             public int dwReserved;             /* reserved for driver */
    340         }
    341         //=======================================================BitmapInfoHeader结构===================================================================
    342         //BitmapInfoHeader定义了位图的头部信息
    343         [StructLayout(LayoutKind.Sequential)]
    344         public struct BITMAPINFOHEADER
    345         {
    346             public int biSize;
    347             public int biWidth;
    348             public int biHeight;
    349             public short biPlanes;
    350             public short biBitCount;
    351             public int biCompression;
    352             public int biSizeImage;
    353             public int biXPelsPerMeter;
    354             public int biYPelsPerMeter;
    355             public int biClrUsed;
    356             public int biClrImportant;
    357         }
    358         //=========================================================================================================================================
    359 
    360         //======================================================BitmapInfo结构=====================================================================
    361         //BitmapInfo   位图信息
    362         [StructLayout(LayoutKind.Sequential)]
    363         public struct BITMAPINFO
    364         {
    365             public BITMAPINFOHEADER bmiHeader;
    366             public int bmiColors;
    367         }
    368 
    369         //=====================================================CAPTUREPARMS结构======================================================================
    370         //CAPTUREPARMS 包含控制视频流捕获过程的参数,如捕获帧频、指定键盘或鼠标键以终止捕获、捕获时间限制等; 
    371         [StructLayout(LayoutKind.Sequential)]
    372         public struct CAPTUREPARMS
    373         {
    374             public int dwRequestMicroSecPerFrame;             // 期望的桢播放率,以毫秒为单位,默认为66667,相当于15桢每秒。
    375             public bool fMakeUserHitOKToCapture;             // Show "Hit OK to cap" dlg?开始捕获标志位,如果值为真,则在开始捕获前要产生一个询问对话框,默认为假。
    376             public uint wPercentDropForError;               //所允许的最大丢桢百分比,可以从0变化到100,默认值为10。
    377             public bool fYield;                     /*另起线程标志位,如果为真,则程序重新启动一个线程用于视频流的捕获,默认值是假。
    378                                                      但是如果你是为了真,你必须要在程序中处理一些潜在的操作,因为当视频捕获时,其他操作并没有被屏蔽。*/
    379             public int dwIndexSize;                       // 在AVI文件中所允许的最大数目的索引项(32K)
    380             public uint wChunkGranularity;               // AVI文件的逻辑尺寸,以字节为单位。如果值是0,则说明该尺寸渐增 在 Win32程序中无用。(2K)
    381             public bool fUsingDOSMemory;                // Use DOS buffers?
    382             public uint wNumVideoRequested;            // 所被允许分配的最大视频缓存
    383             public bool fCaptureAudio;                // 音频标志位,如果音频流正在捕获,则该值为真。
    384             public uint wNumAudioRequested;          // 最大数量的音频缓存,默认值为10。
    385             public uint vKeyAbort;                  // 终止流捕获的虚拟键盘码,默认值为VK_ESCAPE
    386             [MarshalAs(UnmanagedType.Bool)]
    387             public bool fAbortLeftMouse;           // 终止鼠标左键标志位,如果该值为真,则在流捕获过程中如果点击鼠标左键则该捕获终止,默认值为真。
    388             public bool fAbortRightMouse;                 // Abort on right mouse?
    389             public bool fLimitEnabled;                   // 捕获操作时间限制,如果为真,则时间到了以后捕获操作终止,默认为假
    390             public uint wTimeLimit;                     // 具体终止时间,只有 fLimitEnabled是真时.该位才有效
    391             public bool fMCIControl;                   // Use MCI video source?
    392             public bool fStepMCIDevice;               // Step MCI device?MCI 设备标志。
    393             public int dwMCIStartTime;               // Time to start in MS
    394             public int dwMCIStopTime;               // Time to stop in MS
    395             public bool fStepCaptureAt2x;          // Perform spatial averaging 2x
    396             public int wStepCaptureAverageFrames; // 当基于平均采样来创建桢时,桢的采样时间,典型值是5
    397             public int dwAudioBufferSize;        // 音频缓存的尺寸,如果用默认值0,缓存尺寸是最大0.5秒,或10k字节。
    398             public int fDisableWriteCache;      // Attempt to disable write cache
    399             public int AVStreamMaster;         //音视频同步标志。
    400         }
    401         //=========================================================================================================================================
    402 
    403         //=================================================CAPDRIVERCAPS结构=======================================================================
    404         //CAPDRIVERCAPS定义了捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等; 
    405         [StructLayout(LayoutKind.Sequential)]
    406         public struct CAPDRIVERCAPS
    407         {
    408             [MarshalAs(UnmanagedType.U2)]
    409             public UInt16 wDeviceIndex;         //捕获驱动器的索引值,该值可以由0到9变化。
    410             [MarshalAs(UnmanagedType.Bool)]
    411             public bool fHasOverlay;            // 视频叠加标志,如果设备支持视频叠加这该位是真。
    412             [MarshalAs(UnmanagedType.Bool)]
    413             public bool fHasDlgVideoSource;     //视频资源对话框标志位,如果设备支持视频选择、控制对话框,该值为真。
    414             [MarshalAs(UnmanagedType.Bool)]
    415             public bool fHasDlgVideoFormat;     //视频格式对话框标志位,如果设备支持对视频格式对话框的选择,该位真。
    416             [MarshalAs(UnmanagedType.Bool)]
    417             public bool fHasDlgVideoDisplay;    //视频展示对话框标志位,如果设备支持对视频捕获缓存区的重新播放,该位是真。
    418             [MarshalAs(UnmanagedType.Bool)]
    419             public bool fCaptureInitialized;    //捕获安装标志位,如果捕获驱动器已经成功连接,该值为真。
    420             //[MarshalAs(UnmanagedType.Bool)]
    421             public bool fDriverSuppliesPalettes; //驱动器调色板标志位,如果驱动器能创建调色板,则该位是真。
    422             [MarshalAs(UnmanagedType.I4)]
    423             public int hVideoIn;
    424             [MarshalAs(UnmanagedType.I4)]
    425             public int hVideoOut;
    426             [MarshalAs(UnmanagedType.I4)]
    427             public int hVideoExtIn;
    428             [MarshalAs(UnmanagedType.I4)]
    429             public int hVideoExtOut;
    430         }
    431         //=========================================================================================================================================
    432 
    433 
    434         //=====================================================CAPSTATUS结构========================================================================
    435         //CAPSTATUS定义了捕获窗口的当前状态,如图像的宽、高等;
    436         [StructLayout(LayoutKind.Sequential)]
    437         public struct CAPSTATUS
    438         {
    439             public int uiImageWidth;                         //图像宽度
    440             public int uiImageHeight;                       //图像高度
    441             public bool fLiveWindow;                       //活动窗口标记,如果窗口正以预览的方式展示图像,那么该值为真
    442             public bool fOverlayWindow;                   //叠加窗口标志位,如果正在使用硬件叠加,则该位是真。
    443             public bool fScale;                          //输入所放标志位,如果窗口是正在缩放视频到客户区,那么该位是真。当使用硬件叠加时,改位无效。
    444             public Point ptScroll;                      //被展示在窗口客户区左上角的那个象素的x、y坐标偏移量。
    445             public bool fUsingDefaultPalette;          //默认调色板标志位,如果捕获窗口正在使用当前默认调色板,该值为真
    446             public bool fAudioHardware;               // 音频硬件标志位,如果系统已经安装了音频硬件,该值为真。
    447             public bool fCapFileExists;              //捕获文件标志位,如果一个捕获文件已经被创建,该值为真
    448             public int dwCurrentVideoFrame;         // 当前或最近流捕获过程中,所处理的桢的数目。包括丢弃的桢。
    449             public int dwCurrentVideoFramesDropped;//当前流捕获过程中丢弃的桢的数目。
    450             public int dwCurrentWaveSamples;      // # of wave samples cap'td
    451             public int dwCurrentTimeElapsedMS;   // 从当前流捕获开始计算,程序所用的时间,以毫秒为单位。
    452             public IntPtr hPalCurrent;          // 当前剪切板的句柄。
    453             public bool fCapturingNow;         // 捕获标志位,当捕获是正在进行时,改位是真
    454             public int dwReturn;              // 错误返回值,当你的应用程序不支持错误回调函数时可以应用改位
    455             public int wNumVideoAllocated;   // 被分配的视频缓存的数目。
    456             public int wNumAudioAllocated;  // 被分配的音频缓存的数目。
    457         }
    458         //=========================================================================================================================================
    459 
    460 
    461         #endregion 结构 VIDEOHDR|BITMAPINFOHEADER|BITMAPINFO|CAPTUREPARMS|CAPDRIVERCAPS|CAPSTATUS
    462 
    463     }
    464     public class cVideo     //视频类
    465     {
    466         public bool flag = true;
    467         private IntPtr lwndC;       //保存无符号句柄
    468         private IntPtr mControlPtr; //保存管理指示器
    469         private int mWidth;
    470         private int mHeight;
    471         public delegate void RecievedFrameEventHandler(byte[] data);
    472         public event RecievedFrameEventHandler RecievedFrame;
    473 
    474         public VideoAPI.CAPTUREPARMS Capparms;
    475         private VideoAPI.FrameEventHandler mFrameEventHandler;
    476         public VideoAPI.CAPDRIVERCAPS CapDriverCAPS;//捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等;
    477         public VideoAPI.CAPSTATUS CapStatus;//该结构用于保存视频设备捕获窗口的当前状态,如图像的宽、高等
    478         string strFileName;
    479         public cVideo(IntPtr handle, int width, int height)
    480         {
    481             CapDriverCAPS = new VideoAPI.CAPDRIVERCAPS();//捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等;
    482             CapStatus = new VideoAPI.CAPSTATUS();//该结构用于保存视频设备捕获窗口的当前状态,如图像的宽、高等
    483             mControlPtr = handle; //显示视频控件的句柄
    484             mWidth = width;      //视频宽度
    485             mHeight = height;    //视频高度
    486         }
    487         public bool StartWebCam()
    488         {
    489            return  StartWebCam(mWidth, mHeight);
    490         }
    491        /// <summary>
    492         ///  打开视频设备
    493        /// </summary>
    494         /// <param name="width">捕获窗口的宽度</param>
    495         /// <param name="height">捕获窗口的高度</param>
    496        /// <returns></returns>
    497         public bool StartWebCam(int width,int height)
    498         {
    499             //byte[] lpszName = new byte[100];
    500             //byte[] lpszVer = new byte[100];
    501             //VideoAPI.capGetDriverDescriptionA(0, lpszName, 100, lpszVer, 100);
    502             //this.lwndC = VideoAPI.capCreateCaptureWindowA(lpszName, VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);
    503             //if (VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))
    504             //{
    505             //    VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 100, 0);
    506             //    VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEW, true, 0);
    507             //    return true;
    508             //}
    509             //else
    510             //{
    511             //    return false;
    512             //}
    513             this.lwndC = VideoAPI.capCreateCaptureWindow("", VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);//AVICap类的捕捉窗口
    514             VideoAPI.FrameEventHandler FrameEventHandler = new VideoAPI.FrameEventHandler(FrameCallback);
    515             VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_ERROR, 0, 0);//注册错误回调函数
    516             VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_STATUS, 0, 0);//注册状态回调函数 
    517             VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);//注册视频流回调函数
    518             VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_FRAME, 0, FrameEventHandler);//注册帧回调函数
    519 
    520             //if (!CapDriverCAPS.fCaptureInitialized)//判断当前设备是否被其他设备连接已经连接
    521             //{
    522 
    523             if (VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))
    524             {
    525                 //-----------------------------------------------------------------------
    526                 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_DRIVER_GET_CAPS, VideoAPI.SizeOf(CapDriverCAPS), ref CapDriverCAPS);//获得当前视频 CAPDRIVERCAPS定义了捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等;
    527                 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_STATUS, VideoAPI.SizeOf(CapStatus), ref CapStatus);//获得当前视频流的尺寸 存入CapStatus结构
    528 
    529                 VideoAPI.BITMAPINFO bitmapInfo = new VideoAPI.BITMAPINFO();//设置视频格式 (height and width in pixels, bits per frame). 
    530                 bitmapInfo.bmiHeader = new VideoAPI.BITMAPINFOHEADER();
    531                 bitmapInfo.bmiHeader.biSize = VideoAPI.SizeOf(bitmapInfo.bmiHeader);
    532                 bitmapInfo.bmiHeader.biWidth = mWidth;
    533                 bitmapInfo.bmiHeader.biHeight = mHeight;
    534                 bitmapInfo.bmiHeader.biPlanes = 1;
    535                 bitmapInfo.bmiHeader.biBitCount = 24;
    536                 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 40, 0);//设置在PREVIEW模式下设定视频窗口的刷新率 设置每40毫秒显示一帧,即显示帧速为每秒25帧
    537                 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_SCALE, 1, 0);//打开预览视频的缩放比例
    538                 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_VIDEOFORMAT, VideoAPI.SizeOf(bitmapInfo), ref bitmapInfo);
    539 
    540                 this.mFrameEventHandler = new VideoAPI.FrameEventHandler(FrameCallback);
    541                 this.capSetCallbackOnFrame(this.lwndC, this.mFrameEventHandler);
    542 
    543 
    544                 VideoAPI.CAPTUREPARMS captureparms = new VideoAPI.CAPTUREPARMS();
    545                 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_SEQUENCE_SETUP, VideoAPI.SizeOf(captureparms), ref captureparms);
    546                 if (CapDriverCAPS.fHasOverlay)
    547                 {
    548                     VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_OVERLAY, 1, 0);//启用叠加 注:据说启用此项可以加快渲染速度    
    549                 }
    550                 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEW, 1, 0);//设置显示图像启动预览模式 PREVIEW
    551                 VideoAPI.SetWindowPos(this.lwndC, 0, 0, 0, width, height, VideoAPI.SWP_NOZORDER | VideoAPI.SWP_NOMOVE);//使捕获窗口与进来的视频流尺寸保持一致
    552                 return true;
    553             }
    554             else
    555             { 
    556               
    557                 flag = false;
    558                 return false;
    559             }
    560         }
    561         public bool   ReSizePic(int width, int height)
    562         {
    563             try
    564             {
    565               //  CloseWebcam();
    566               //  StartWebCam();
    567               //  this.lwndC = VideoAPI.capCreateCaptureWindow("", VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);
    568 
    569               //  VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_STATUS, VideoAPI.SizeOf(CapStatus), ref CapStatus);//获得当前视频流的尺寸 存入CapStatus结构
    570              //   VideoAPI.FrameEventHandler FrameEventHandler = new VideoAPI.FrameEventHandler(FrameCallback);
    571              //   VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_ERROR, 0, 0);//注册错误回调函数
    572              //   VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_STATUS, 0, 0);//注册状态回调函数 
    573              //   VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);//注册视频流回调函数
    574              //   VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_FRAME, 0, FrameEventHandler);//注册帧回调函数
    575              ////   if (VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))
    576              //   {
    577              //       VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_SCALE, 1, 0);
    578              //       VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 40, 0);
    579              //       VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEW, 1, 0);
    580 
    581                     return VideoAPI.SetWindowPos(this.lwndC, 0, 0, 0, width, height, VideoAPI.SWP_NOZORDER | VideoAPI.SWP_NOMOVE) > 0;
    582               //  }
    583                // return false;
    584             }
    585             catch
    586             {
    587                 return false;
    588             }
    589         }
    590         public void get()
    591         {
    592             VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_SEQUENCE_SETUP, VideoAPI.SizeOf(Capparms), ref Capparms);
    593         }
    594         public void set()
    595         {
    596             VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_SEQUENCE_SETUP, VideoAPI.SizeOf(Capparms), ref Capparms);
    597         }
    598         private bool capSetCallbackOnFrame(IntPtr lwnd, VideoAPI.FrameEventHandler lpProc)
    599         {
    600             return VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_FRAME, 0, lpProc);
    601         }
    602         /// <summary>
    603         /// 关闭视频设备
    604         /// </summary>
    605         public void CloseWebcam()
    606         {
    607             VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_DISCONNECT, 0, 0);
    608         }
    609         ///   <summary>   
    610         ///   拍照
    611         ///   </summary>   
    612         ///   <param   name="path">要保存bmp文件的路径</param>   
    613         public void GrabImage(IntPtr hWndC, string path)
    614         {
    615             IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
    616             VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SAVEDIB, 0, hBmp.ToInt32());
    617         }
    618         public bool StarKinescope(string path)
    619         {
    620             try
    621             {
    622                 strFileName = path;
    623                 string dir = path.Remove(path.LastIndexOf("\"));
    624                 if (!File.Exists(dir))
    625                 {
    626                     Directory.CreateDirectory(dir);
    627                 }
    628                 int hBmp = Marshal.StringToHGlobalAnsi(path).ToInt32();
    629                 bool b = VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_FILE_SET_CAPTURE_FILE, 0, hBmp);
    630                 b = b && VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SEQUENCE, 0, 0);
    631                 return b;
    632             }
    633             catch
    634             {
    635                 return false;
    636             }
    637         }
    638         /// <summary>
    639         /// 停止录像
    640         /// </summary>
    641         public bool StopKinescope()
    642         {
    643           return  VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_STOP, 0, 0);
    644         }
    645         private void FrameCallback(IntPtr lwnd, IntPtr lpvhdr)
    646         {
    647             VideoAPI.VIDEOHDR videoHeader = new VideoAPI.VIDEOHDR();
    648             byte[] VideoData;
    649             videoHeader = (VideoAPI.VIDEOHDR)VideoAPI.GetStructure(lpvhdr, videoHeader);
    650             VideoData = new byte[videoHeader.dwBytesUsed];
    651             VideoAPI.Copy(videoHeader.lpData, VideoData);
    652             if (this.RecievedFrame != null)
    653                 this.RecievedFrame(VideoData);
    654         }
    655         private Thread myThread;
    656 
    657         public void CompressVideoFfmpeg()
    658         {
    659             myThread = new Thread(new ThreadStart(testfn));
    660             myThread.Start();
    661             testfn();
    662         }
    663         private void testfn()
    664         {
    665             string file_name = strFileName;
    666             string command_line = " -i " + file_name + " -vcodec libx264 -cqp 25 -y " + file_name.Replace(".avi", "_264") + ".avi";
    667             System.Diagnostics.Process proc = new System.Diagnostics.Process();
    668             proc.StartInfo.WorkingDirectory = Application.StartupPath;
    669             proc.StartInfo.UseShellExecute = false; //use false if you want to hide the window
    670             proc.StartInfo.CreateNoWindow = true;
    671             proc.StartInfo.FileName = "ffmpeg";
    672             proc.StartInfo.Arguments = command_line;
    673             proc.Start();
    674             proc.WaitForExit();
    675             proc.Close();
    676             Common.writeLog("视频"+strFileName+"压缩完毕");
    677             // 删除原始avi文件
    678             FileInfo file = new FileInfo(file_name);
    679             if (file.Exists)
    680             {
    681                 try
    682                 {
    683                     file.Delete(); //删除单个文件
    684                 }
    685                 catch (Exception e)
    686                 {
    687                    // Common.writeLog("删除视频文件“" + file_name + "”出错!准备" );
    688                    
    689                     (new Thread(() =>
    690                     {
    691                         bool b = false;
    692                         for (int i = 0; i < 5; i++)
    693                         {
    694                             Thread.Sleep(10000*(i*i));
    695                             try
    696                             {
    697                                 file.Delete();
    698                                 b = true;
    699                                 break;
    700                             }
    701                             catch
    702                             {
    703                             }
    704                         };
    705                         if (!b)
    706                             Common.writeLog("删除视频文件“" + file_name + "”出错");
    707                     }
    708                     )).Start();
    709                 }
    710             }
    711             //myThread.Abort();
    712         }
    713     }
    714 }
  • 相关阅读:
    面试问题整理Andorid版本 date: 2017-1-12 21:14:36 categories: 技术
    轻量级的C++插件框架
    C++程序在Windows平台上各种定位内存泄漏的方法,并对比了它们的优缺点
    Facebook App 的头文件会有更多的收获
    合并Excel工作薄中成绩表的VBA代码,非常适合教育一线的朋友_python
    使用python在校内发人人网状态(人人网看状态)_python
    使用PYTHON创建XML文档_python
    优秀的缓存请求库,快速请求接口和图片:WTRequestCenter
    让读者快速了解RocketMQ消息中间件需要解决哪些问题
    编绎调试HotSpot JVM及在Eclipse里调试HotSpot一些步骤
  • 原文地址:https://www.cnblogs.com/endv/p/6790949.html
Copyright © 2011-2022 走看看