资源描述
一、 监控方案分析。
1、 监控原有文档中相关上墙方案以下。
电视墙控制步骤以下图所表示:
电视墙控制步骤
1. 登录后从AAS服务器获取电视墙配置
2. 假如没有电视墙配置, 则进行电视墙分屏方法编辑, 电视墙分屏与解码器关联设置, 设置分屏对应通道或是通道序列, 都会经过AAS保留配置
3. 对于电视墙每一个分屏, 将其对应通道打开, 或是将其对应通道序列依次打开
该方案与实际代码不符合。代码中唯一可能方案以下。为何说可能, 因为代码有原有方案相关代码, 即使这些代码大部分被屏蔽掉了, 但还有一部分在用, 经过分析也没发觉在用这一部分到底有什么用。
2、 个人分析原有监控代码得出可能方案:
1)前提条件: 每个装有VCT(视频、 指挥、 监控三合一用户端)PC上配一张视频解码卡。
2)具体上墙原理:
每个视频播放窗口与解码卡一个通道绑定, 这么播放窗口视频在播放同时输送到与目前播放窗口绑定解码卡通道中。解码卡与电视墙直接相连, 这么画面也就显示到电视墙上了。
视频上墙原理图
二、 视频上墙关键代码.
1、 输出流到视频解码卡某个通道中。
BOOL CCDMMediaPlayer::InPutYUVStream(long nChannel,char* streamPtr,int width,int height,int colorspace)
{
if( nChannel < HB15_GetChannels())
{
CString strLog;
time_t t;
time(&t);
struct tm* pTM = localtime(&t);
int ret = 0;
ret = HB15_InputData(nChannel,streamPtr, width, height, colorspace);
if (ret > 0)
{
return TRUE;
}
else
{
strLog.Format(_T("%02d:%02d:%02d InPutYUVStream error chnl[%d],ret:[%d],w[%d],h[%d]."),
pTM->tm_hour,pTM->tm_min,pTM->tm_sec,nChannel, ret, width, height);
theLog.WriteLog(strLog);
return FALSE;
}
}
return FALSE;
}
2、 底层OCX控件将视频流传给上层步骤。
BEGIN_EVENTSINK_MAP(CCDMClientOcxCtrlDlg, CDialog)
ON_EVENT(CCDMClientOcxCtrlDlg, IDC_IPCDMCLIENT, 3, CCDMClientOcxCtrlDlg::FileInfoNotifyIpcdmclient, VTS_BSTR VTS_BSTR VTS_BSTR VTS_I4)
ON_EVENT(CCDMClientOcxCtrlDlg, IDC_IPCDMCLIENT, 1, CCDMClientOcxCtrlDlg::NotifyIpcdmclient, VTS_BSTR VTS_I4)
ON_EVENT(CCDMClientOcxCtrlDlg, IDC_IPCDMCLIENT, 2, CCDMClientOcxCtrlDlg::AlarmNotifyIpcdmclient, VTS_BSTR VTS_BSTR VTS_BSTR VTS_BSTR VTS_BSTR VTS_BSTR VTS_I4 VTS_BSTR VTS_I4 VTS_I4)
ON_EVENT(CCDMClientOcxCtrlDlg, IDC_IPCDMCLIENT, 4, CCDMClientOcxCtrlDlg::SubEventNotifyIpcdmclient, VTS_BSTR VTS_BSTR VTS_BSTR VTS_BSTR)
ON_EVENT(CCDMClientOcxCtrlDlg, IDC_IPCDMCLIENT, 6, CCDMClientOcxCtrlDlg::SubExchangeNotifyIpcdmclient, VTS_BSTR VTS_I4 VTS_BSTR)
ON_EVENT(CCDMClientOcxCtrlDlg, IDC_IPCDMCLIENT, 7, CCDMClientOcxCtrlDlg::StreamNotifyIpcdmclient, VTS_I4 VTS_I4)
ON_EVENT(CCDMClientOcxCtrlDlg, IDC_IPCDMCLIENT, 8, CCDMClientOcxCtrlDlg::KickoffNotifyIpcdmclient, VTS_I4)
ON_EVENT(CCDMClientOcxCtrlDlg, IDC_IPCDMCLIENT, 9, CCDMClientOcxCtrlDlg::TVStreamNotifyIpcdmclient, VTS_I4 VTS_I4 VTS_I4 VTS_I4 VTS_I4)
END_EVENTSINK_MAP()
void CCDMClientOcxCtrlDlg::TVStreamNotifyIpcdmclient(long nChannel,long streamPtr,long width,long height,long colorspace)
{
if(m_pNotifyReceiver)
{
m_pNotifyReceiver->OnTVStreamNotify(nChannel, streamPtr, width, height, colorspace);
}
}
3、 打开某窗口流上墙开关
BOOL CMultiDisplayDlg::OpenLive(int nWndIndex, CChannel* pChannel)
{
if(!IS_VALID_PLAYWND_INDEX(nWndIndex))
{
return FALSE;
}
m_lpPlyInfo[nWndIndex].lpPlayer->Stop();
BOOL bOpen = m_lpPlyInfo[nWndIndex].lpPlayer->OpenLive(pChannel);
m_lpPlyInfo[nWndIndex].lpPlayer->GetMediaPlayer()->AdaptWnd(m_bAllAdapt);
m_lpPlyInfo[nWndIndex].lpPlayer->GetMediaPlayer()->OpenTVChannel(nWndIndex);
CDisplayMessage Message(DISPLAY_STREAM_SOURCE_CHANGED, this);
Message.m_nWndIndex = nWndIndex;
Message.Send();
return bOpen;
}
BOOL CCDMMediaPlayer::OpenTVChannel(int nChannel)
{
if(theAppData.IsOutToTVWall())
{
if(!m_bOpenChannel[nChannel])
{
unsigned int n = HB15_GetChannels();
if (nChannel < n)
{
m_CDMClientPlayer.m_CDMClientOcxCtrl.IsTvOpenChannel(nChannel,TRUE);
CString strLog;
strLog.Format(_T("IsTvOpenChannel Chnl[%d]."),nChannel);
theLog.WriteLog(strLog);
if(HB15_OpenChannel(nChannel))
{
// HB15_ClearVideoOutput(nChannel);
CString strLog;
strLog.Format(_T("HB15_OpenChannel Chnl[%d]"),nChannel);
theLog.WriteLog(strLog);
m_bOpenChannel[nChannel] = TRUE;
return TRUE;
}
else //if open error, then uinit/init card again.
{
CString strLog;
strLog.Format(_T("HB15_OpenChannel Chnl[%d] error."),nChannel);
theLog.WriteLog(strLog);
UninitTVCard();
InitTVCard();
CCDMPlatformClientDlg* pMainDlg = (CCDMPlatformClientDlg*)AfxGetMainWnd();
pMainDlg->m_dlgTvWallMain.LoadScreenChannels(0);
return TRUE;
}
}
return FALSE;
}
}
else
{
return TRUE;
}
return TRUE;
}
展开阅读全文