该文由处提供代码加已修改。
说明:
1:天敏VC系列卡片,在SDK的提供上,没有很好的兼容性,DLL或驱动版本不同会导致某些功能不能实现。此处我用的是:Sa7134Capture.dll[6.0.0.0],SAA7134.sys[4.1.1.0]。
2:视频捕获回调时报错:“对“XXX!vc4000.SDKAPI+PrcVidCapCallBack::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。”原因分析:如果不用成员变量,而用局部变量引用被new出来的委托,那么非托管代码可能刚开始的几次回调是OK的,但是接下来就会出现上面所说的异常,原因就在于GC将局部变量和局部变量引用的委托对象都销毁了,非托管代码再去访问那个函数指针时发现指针指向的地址已经无效。
SDKAPI申明与引用:
SDKAPI.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace vc4000
{
class SDKAPI
{
public enum DISPLAYTRANSTYPE
{
NOT_DISPLAY = 0,
PCI_VIEDOMEMORY = 1,
PCI_MEMORY_VIDEOMEMORY = 2,
PCI_OFFSCREEN_VIDEOMEMORY = 3
}
public enum eFieldFrequency
{
Field frequency
FIELD_FREQ_50HZ = 0, source is 50 Hz (PAL)
FIELD_FREQ_60HZ = 1, source is 60 Hz (NTSC)
FIELD_FREQ_0HZ = 2, source is 0 Hz (NO SIGNL)
FIELD_FREQ_50HZ_NULL = 3,
FIELD_FREQ_60HZ_NULL = 4
}
public enum CAPMODEL
{
CAP_NULL_STREAM = 0, //捕获无效
CAP_ORIGIN_STREAM = 1, /*原始流回调*/
CAP_MPEG4_STREAM = 2, /*Mpeg4流*/
CAP_MPEG4_XVID_STREAM = 3,
CAP_ORIGIN_MPEG4_STREAM = 4,
CAP_ORIGIN_XVID_STREAM = 5,
CAP_WMV9_STREAM = 6,
CAP_ORIGIN_WMV9_STREAM = 7
}
public enum MP4MODEL
{
MPEG4_AVIFILE_ONLY = 0, //存为MPEG文件
MPEG4_CALLBACK_ONLY = 1, //MPEG数据回调
MPEG4_AVIFILE_CALLBACK = 2 //存为MPEG文件并回调
}
public enum COMPRESSMODE
{
XVID_CBR_MODE = 0,
XVID_VBR_MODE = 1//,
}
public enum COLORCONTROL
{
BRIGHTNESS = 0, control for brightness
CONTRAST = 1, control for contrast
SATURATION = 2, control for saturation
HUE = 3, control for hue
SHARPNESS = 4 control for sharpness
}
// init sdk
//origin stream callback
public delegate void PrcVidCapCallBack(int dwCard,ref IntPtr pBuffer, int dwSize);//回调函数委托
//motion detection callback
public delegate void PrcCbMotionDetect(int dwCard, bool bMove, byte[] pbuff, int dwSize, IntPtr lpContext);
//mpg stream callback
public delegate void PrcVidMpegCallBack(int dwCard, bool bMove, byte[] pbuff, int dwSize, bool isKeyFrm);
//copy memory
[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
public static extern void MoveMemory(IntPtr dest, IntPtr src, int size);
//write ini file
[DllImport("kernel32")]
public static extern long WritePrivateProfileString(string section, string key,
string val, string filePath);
//read ini file
[DllImport("kernel32")]
public static extern int GetPrivateProfileString(string section,
string key, string def,
StringBuilder retVal, int size, string filePath);
[DllImport("Sa7134Capture.dll")]
public static extern int VCAInitSdk(IntPtr hWndMain, DISPLAYTRANSTYPE eDispTransType, bool bInitAudDev);
// get card channels number
[DllImport("Sa7134Capture.dll")]
public static extern int VCAGetDevNum();
//open device
[DllImport("Sa7134Capture.dll")]
public static extern int VCAOpenDevice(int dwCard, IntPtr hPreviewWnd);
[DllImport("Sa7134Capture.dll")]
public static extern int VCACloseDevice(int dwCard);
[DllImport("Sa7134Capture.dll")]
public static extern int VCAStartVideoPreview(int dwCard);
[DllImport("Sa7134Capture.dll")]
public static extern int VCAStopVideoPreview(int dwCard);
[DllImport("Sa7134Capture.dll")]
public static extern int VCAUpdateOverlayWnd(IntPtr hOverlayWnd);
[DllImport("Sa7134Capture.dll")]
public static extern int VCAUpdateVideoPreview(int dwCard, IntPtr hPreviewWnd);
[DllImport("Sa7134Capture.dll")]
public static extern void VCAUnInitSdk();
[DllImport("Sa7134Capture.dll")]
public static extern int VCASetVidCapSize(int dwCard, int dwWidth, int dwHeight);
[DllImport("Sa7134Capture.dll")]
public static extern int VCASaveAsJpegFile(int dwCard, string lpFileName, int dwQuality);
[DllImport("Sa7134Capture.dll")]
public static extern int VCASaveAsBmpFile(int dwCard, string lpFileName);
[DllImport("Sa7134Capture.dll")]
public static extern int VCAStartVideoCapture(int dwCard,
CAPMODEL enCapMode,
MP4MODEL enMp4Mode,
string lpFileName);
[DllImport("Sa7134Capture.dll")]
public static extern int VCAStopVideoCapture(int dwCard);
[DllImport("Sa7134Capture.dll")]
public static extern int VCAPauseCapture(int dwCard);
[DllImport("Sa7134Capture.dll")]
public static extern int VCASetVidCapFrameRate(int dwCard, int dwFrameRate, bool bFrameRateReduction);
[DllImport("Sa7134Capture.dll")]
public static extern int VCASetBitRate(int dwCard, int dwBitRate);
[DllImport("Sa7134Capture.dll")]
public static extern int VCASetKeyFrmInterval(int dwCard, int dwKeyFrmInterval);
[DllImport("Sa7134Capture.dll")]
public static extern int VCASetXVIDQuality(int dwCard, int dwQuantizer, int dwMotionPrecision);
[DllImport("Sa7134Capture.dll")]
public static extern int VCASetXVIDCompressMode(int dwCard, COMPRESSMODE enCompessMode);
[DllImport("Sa7134Capture.dll")]
public static extern int VCASetVidDeviceColor(int dwCard, COLORCONTROL enCtlType, int dwValue);
[DllImport("Sa7134Capture.dll")]
public static extern int VCARegVidCapCallBack(int dwCard, PrcVidCapCallBack ppCall);
[DllImport("Sa7134Capture.dll")]
public static extern int VCAGetVidCapSize(int dwCard, ref int dwWidth, ref int dwHeight);
[DllImport("Sa7134Capture.dll")]
public static extern int VCAGetVidFieldFrq(int dwCard, ref eFieldFrequency eVidSourceFieldRate);
[DllImport("Sa7134Capture.dll")]
public static extern int VCAEnableMotionDetect(int dwCard,
bool bEnaDetect,
byte[] pAreaMap,
int nSizeOfMap,
int nPersistTime,
int nFrameRateReduce,
IntPtr lpContext,
PrcCbMotionDetect OnObjectMove);
[DllImport("CapturePicture.dll")]
public static extern int CaptureFileAsBmp(string AFileName,
IntPtr pYUVBuffer,
IntPtr pRGBBuffer,
int nWidth, int nHeight);
}
}