之前采用通信结构复制方式实现多指令系统,因为通信结构不一样,实现有些复杂,现改进统一通信结构,通过增加发送端口实现多指令系统,模型图如下:
通过中枢端口2系导向到1系,实现多端口开关,还可连续增加,导向1系。
通信结构如下:
//播放协调中枢命令
//---------------------------------------------------------------------------
#define def_MaxCmdCount 3 //最大命令数
//模块列表
#define to_OptModule 1 //操作模块端口编号
#define to_FicModule 2 //Fic模块端口编号
#define to_AviModule 3 //Avi模块端口编号
#define to_MapModule 4 //Map模块端口编号
#define to_SodModule 5 //Sod模块端口编号
//Opt模块命令集
#define CMD_Opt_ShowParam 1 //显示参数
#define CMD_Opt_ShowProgress 2 //显示进度
//FIC模块命令集
#define CMD_FIC_OpenR 3 //打开准备读文件
#define CMD_FIC_OpenW 4 //打开准备写文件
#define CMD_FIC_Close 5 //关闭资源
#define CMD_FIC_DeFrame 6 //FIC压缩一帧
#define CMD_FIC_EnFrame 7 //FIC压缩一帧
//AVI模块命令集
#define CMD_AVI_OpenR 8 //打开准备读文件
#define CMD_AVI_OpenW 9 //打开准备写文件
#define CMD_AVI_Close 10 //关闭资源
#define CMD_AVI_DeFrame 11 //AVI解压一帧
#define CMD_AVI_EnFrame 12 //AVI压缩一帧
//Map模块命令集
#define CMD_Map_SetParam 13//设置屏幕参数
#define CMD_Map_Close 14 //关闭资源
#define CMD_Map_Updata 15 //更新屏幕
//Sod模块命令集
#define CMD_Sod_SetInterval 16//设置帧间定时
#define CMD_Sod_Close 17 //关闭资源
#define CMD_Sod_Updata 18 //更新音频数据
//操作模式
#define OptMode_AviPlay 1 //Avi播放模式
#define OptMode_WriteFic 2 //Fic写模式
#define OptMode_FicPlay 3 //Fic播放模式
//参数编号定义
#define def_Param0 0 //参数0
#define def_Param1 1 //参数1
#define def_Param2 2 //参数2
#define def_Param3 3 //参数3
#define def_Param4 4 //参数4
#define def_Param5 5 //参数5
#define def_Param6 6 //参数6
struct TCommPort//通信端口结构
{
bool bActive,//命令有效标志
bErr,//错误或无错误
bOK;//成功或失败,或应答
DWORD dwToModule,//目的模块
dwCommand,//命令
dwOptMode,//操作模式
dwParam[8];//参数
float fParam[2];//浮点参数
BYTE *pPtr;//指针参数
String sStr;//字符串
};
//---------------------------------------------------------------------------
费这么大劲是为了简化程序,目前采用步进命令符形式,使得各模块关系变得简单。以下是命令片段:
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)//打开读AVI文件
{
OpenDialog1->Title = "打开AVI文件";
OpenDialog1->Filter = "AVI文件(*.avi)|*.avi";
if(OpenDialog1->Execute())//找到文件
{
StaticText1->Caption = OpenDialog1->FileName;//显示路径
InParamStr(&TxPort1, OpenDialog1->FileName);//传递路径
TxCmmand(&TxPort1, to_AviModule, CMD_AVI_OpenR);//发送命令
ST100->Caption = " 打开读Avi文件。";
SetCurrentDir(ExtractFilePath(Application->ExeName));
}
}
void __fastcall TForm1::SpeedButton7Click(TObject *Sender)//播放AVI文件
{
ProgressBar1->Max = pRxPort->dwParam[0];//设置进度板
//输入到Map参数
InParam(&TxPort1, pRxPort->dwParam[1], def_Param0);//输入AVI宽度
InParam(&TxPort1, pRxPort->dwParam[2], def_Param1);//输入AVI高度
TxCmmand(&TxPort1, to_MapModule, CMD_Map_SetParam);//发送设置Map参数命令
//初始设置
ProgressBar1->Position = 0;
Timer1->Enabled = true; //启动定时器
ST100->Caption = " 正在播放Avi文件...";
}
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
TxCmmand(&TxPort1, to_AviModule, CMD_AVI_DeFrame, CMD_AVI_DeFrame);//发送Avi解压命令,Avi解压模式
}
//Avi解压项
case CMD_AVI_DeFrame: pThread->dwFrameNumber = (DWORD)cvGetCaptureProperty(pThread->capture, CV_CAP_PROP_POS_FRAMES);//返回播放视频帧位置
if(pThread->DeCoderOneFrame())
{
InParamOK(&pThread->TxPort1, true);//成功完成
InParam(&pThread->TxPort1, pThread->dwFrameNumber, def_Param0);//传递帧位置
InParamPtr(&pThread->TxPort2, pThread->pFrameBuf);//传递帧指针
switch(pThread->pRxPort->dwOptMode)
{
case CMD_AVI_DeFrame: TxCmmand(&pThread->TxPort1, to_OptModule, CMD_Opt_ShowProgress);
TxCmmand(&pThread->TxPort2, to_MapModule, CMD_Map_Updata);
break;
case CMD_FIC_OpenW: TxCmmand(&pThread->TxPort1, to_OptModule, CMD_Opt_ShowProgress);//显示进度
TxCmmand(&pThread->TxPort2, to_FicModule, CMD_FIC_EnFrame);//到FicModule压缩
break;
}
}
else//失败或结束
{
InParamOK(&pThread->TxPort1, false);
InParam(&pThread->TxPort1, pThread->dwFrameNumber, def_Param0);//传递帧位置
switch(pThread->pRxPort->dwOptMode)
{
case CMD_AVI_DeFrame: TxCmmand(&pThread->TxPort1, to_OptModule, CMD_Opt_ShowProgress, CMD_AVI_DeFrame);
break;
case CMD_FIC_OpenW: TxCmmand(&pThread->TxPort1, to_OptModule, CMD_Opt_ShowProgress, CMD_FIC_OpenW);
break;
}
}
break;
其中解压完成后,通过两个指令,完成对数据的分配,指令如下:
TxCmmand(&pThread->TxPort1, to_OptModule, CMD_Opt_ShowProgress);//第一个指令
TxCmmand(&pThread->TxPort2, to_MapModule, CMD_Map_Updata);//第二个指令
第一个指令到操作模块,显示视频“属性”,比如当前帧号(进度)等,第二个指令到屏幕数据映射模块,显示“数据”。