为了实现数据的有效传递以及进程间的有效同步,自定义了几个消息和结构体,如下。(变量名中体现的capture即为进程A,processor即为进程B)
首先说明一点,由于B是处理来自A的数据,A的数据要发给B处理,故二者需要相互监视,如果A在指定时间内发现发送给B的数据还没有被处理,则认为B进程已经不存在,便重新启动一个B进程,重新交换各自的主线程ID;相反,如果B在指定时间内发现一直没有新的数据传来,并且标志位flgCaptureRunning为false,则认为进程A已经不存在,那么B也没有存在的必要了,便自行终止。这种相互监视的机制主要用于A或B的进程被强行终止的情况(如在任务管理器中被杀掉)。由于B是控制台程序,无法使用timer,于是定义了TIME_OUT_FRAMES常量,通过对视频帧的计数,来判断是否超时。该常量在A中定义为100,因为经过调试,发现一般在A等待了80多个帧之后,B能够完成上一帧的处理,转而读取新的一帧。在B中,该常量被定义为1000,为的是B等待足够长的时间,以说明A的确已经不复存在了。正常情况下,主程序(也就是A)正常退出时,它还要通知B,使得B也能够自行正常退出;而B在启动时,也要判断是否已经有了B的实例进程在运行,如果有,就退出,以免重复运行多个B的实例。
FRMRST_* 常量是移动侦测的结果,用于移动侦测处理函数的返回结果。
自定义的各消息,其意义大体可以从字面理解。
RECTANGLE结构体记录了一个矩形,其用途是:我们要求在移动侦测过程中,可以在A的视频画面上用鼠标画出一个矩形,以指定移动侦测运算只关心该矩形的范围内的内容。为了便于应用在B中的托管代码,这个结构体中的各个元素是参照.NET中的Rectangle结构设计的:
public: Rectangle(
int x,
int y,
int width,
int height
);
CONTROLFLAGS结构体中是一些控制变量,用于在两个进程间传递一些控制参数。flgProcessorRunning标识进程B(即processor)是否还在运行;flgCaptureRunning用于表示进程A(即capture)是否还在运行。被注释掉的两个变量flgNewFrame和flgTerminate是在第一个版本(即通过传递一些变量数据实现进程同步)中分别用来标识是否有新视频帧和是否要退出程序的,在新的使用消息机制的版本中,这两个事件是通过消息传递的。
结构体FRAME记录了视频帧的信息,包括两个进程的主线程ID等。其中byte bit[3145728]; //1024*768*4记录的就是视频帧的实际像素数据,我采用了1024×768×4的大小,即1024×768、32位彩色位图,一般情况下够用了。
#define TIME_OUT_FRAMES 100
#define FRMRST_NOMOTION 0
#define FRMRST_MOTION 1
#define FRMRST_ERROR -1
#define USR_WM_MIN (WM_USER + 109)
#define USR_WM_NEW_FRAME (WM_USER + 110)
#define USR_WM_NO_MOTION (WM_USER + 111)
#define USR_WM_MOTION_DETECTED (WM_USER +112)
#define USR_WM_TERMINATE (WM_USER + 113)
#define USR_WM_PROCESSOR_ERROR (WM_USER + 114)
#define USR_WM_PROCSESSOR_OK (WM_USER + 115)
#define USR_WM_MAX (WM_USER + 116)
//图像帧上画的矩形坐标。无矩形时各坐标为0
typedef struct tagRECTANGLE {
int x; //左上角横坐标
int y; //左上角纵坐标
int width; //宽
int height; //高
} RECTANGLE;
typedef struct tagMYCONTROLFLAGS {
//bool flgNewFrame;
//bool flgTerminate;
bool flgProcessorRunning;
bool flgCaptureRunning;
} CONTROLFLAGS;
typedef struct tagMYSTRUCT {
DWORD CaptureTID;
DWORD ProcessorTID;
CONTROLFLAGS flags;
BITMAP image;
byte bit[3145728]; //1024*768*4
RECTANGLE rect;
float fMotionLevel;
} FRAME;