1适用范围
大华网络SDK支持IPC/NVR/EVS等网络设备
演示程序\Mfc分类Demo中有04.远程抓图19.枪球联动等功能说明
2Demo工程编译
1)无法解析的外部符_xMonitorFromWindow@8
1>BSWndContainer.obj : error LNK2019: 无法解析的外部符号 _xMonitorFromWindow@8,该符号在函数 "int __cdecl GetCurrentScreenMonitorRect(struct HWND__ *,struct tagRECT &)" (?GetCurrentScreenMonitorRect@@YAHPAUHWND__@@AAUtagRECT@@@Z) 中被引用
1>BSWndContainer.obj : error LNK2019: 无法解析的外部符号 _xGetMonitorInfo@8,该符号在函数 "int __cdecl GetCurrentScreenMonitorRect(struct HWND__ *,struct tagRECT &)" (?GetCurrentScreenMonitorRect@@YAHPAUHWND__@@AAUtagRECT@@@Z) 中被引用
源代码
#include "BSWndContainer.h"
#pragma warning(disable:4706)
//#define COMPILE_MULTIMON_STUBS
#include <multimon.h>
#pragma warning(default:4706)
修改后
#include "BSWndContainer.h"
#pragma warning(disable:4706)
#define COMPILE_MULTIMON_STUBS //取消注释
#include <multimon.h>
#pragma warning(default:4706)
2)error C3861: “_Min”: 找不到标识符
源代码:
int nMinChannel = _Min(m_ChannelNum, _Min(nNum, MAX_RECORD_CHANNEL));
修改后:
int nMinChannel = min(m_ChannelNum, min(nNum, MAX_RECORD_CHANNEL));
3私有协议取流
1)设置取流协议PS,未成功
尝试使用如下代码设置视音频数据的格式为PS,而不是大华的私有流协议,暂时无效
NET_ENCODE_VIDEO_PACK_INFO struEnCodeInfo = { 0 };
struEnCodeInfo.dwSize = sizeof(struEnCodeInfo);
//指定主码流
struEnCodeInfo.emFormatType = EM_FORMAT_MAIN_NORMAL;
//先查看当前的视频流格式
bool bRet = CLIENT_GetConfig(id, NET_EM_CFG_ENCODE_VIDEO_PACK, 1, (void*)&struEnCodeInfo, sizeof(struEnCodeInfo));
DWORD err = 0;
if (!bRet)
{
err = CLIENT_GetLastError()&(0x7fffffff);
}
//设置PS流格式
struEnCodeInfo.emPackType = EM_PACK_PS;
bRet = CLIENT_SetConfig(id, NET_EM_CFG_ENCODE_VIDEO_PACK, 1, (void*)&struEnCodeInfo, sizeof(struEnCodeInfo));
bRet = CLIENT_GetConfig(id, NET_EM_CFG_ENCODE_VIDEO_PACK, 1, (void*)&struEnCodeInfo, sizeof(struEnCodeInfo));
注意:06.编码配置例子中对视音频的编码可以设置,目前通过OnVideoDlgToStu设置PS,抓包没有找到对应的PS头字段,需要保存文件分析
2)设置私有流回调函数的接口
场景
向家坝项目对接大华告警柱,无法通过CLIENT_StartRealPlay接口获取到码流数据
提示出错(CLIENT_GetLastError()&(0x7fffffff);):
错误码:23 (当前SDK未支持该版本)
错误码:79 (设备不支持该操作)(更换最新的SDK提示)
解决方案:采用新接口
CLIENT_RealPlayEx
CLIENT_SetRealDataCallBackEx2(handle, RealDataCallBackEx, (LDWORD)id, 0x0f);
结束点播接口为CLIENT_StopRealPlayEx
尝试方案
尝试通过CLIENT_SetRealDataCallBackEx2(handle, RealDataCallBackEx, (LDWORD)id, REALDATA_FLAG_DATA_WITH_FRAME_INFO),指定参数获取帧的信息REALDATA_FLAG_DATA_WITH_FRAME_INFO,不仅获取不到帧的信息,反而连码流数据都无法获取到
3)大华私有流对接优势
1)大华设备进行rtsp交互耗时1500毫秒
2)SDK私有协议对接耗时600毫秒
3)如下是大华私有视频流的说明
4DHFS视频监控帧格式解析
帧是视频监控数据组成的基本单位,视频监控数据是由许多帧按照一定的顺序组合而成,帧存在多种类型,而且帧的大小不固定,每个帧的起始位置不一定只出现在扇区或块的起始地址,它可以出现在任何合理的物理地址范围内。大华视频监控文件中视频帧是由其自定义的网络通讯协议封装RTP载荷的H.264码流组成,大华视频帧与一般的H.264编码的视频帧是不同的,它对原始H.264视频数据进行了多次封装。
由于大华视频每帧中都含有特定的网络通讯协议头部信息和尾部信息,通过分析帧中网络通讯协议头或尾部的数据特点可以实现对视频帧进行搜索和定位,经过大量实验发现其帧起始特定标志为大写字母DHAV,十六进制表示为0x44484156,帧结束标志为小写字母dhav,十六进制表示为0x64686176(见图1)。大华帧头部结构中记录了基本的视频属性信息,例如帧的编号、帧所属通道号、帧长度以及帧的创建时间等等。这些属性是视频监控数据进行通道分离与重组的关键信息,其中与视频监控恢复相关的属性信息,如表1所示,头部结构中相对DHAV标识偏移量为0x04描述的是帧类型;如图1中偏移0x06位置描述通道号,此帧的通道号是0x0005,具体含义表示为6通道,因为通道号是0作为基数表示1通道;0x08描述的是此帧编号,考虑到大小端表达形式,十六进制表示为0x47D0;相对DHFS偏移0x0C是此帧的长度,此帧长度是0x00000F80,十进制表示为3698字节;相对DHAV偏移0x10是描述此帧的创建时间信息,十六进制表示为0x39308EBB。如图1中dhav后四个字节为帧长度,十六进制表达式为0x20F8,转换成十进制为8840字节,用于校验。尾部结束标志为小写字母dhav,具体帧尾部结构见表2。
图1 DHFS文件系统的帧头与帧尾
Fig.1 Frame head and tail in DHFS
2 DHFS视频监控存储方式研究
2.1 DHFS视频文件存储方式分析
视频监控采用实时文件顺序存储方式,整体的基本布局结构如图2上所示,从文件系统数据区可以分析出大华视频监控文件系统的标识,视频监控存储块大小等信息,这些参数对于大华视频监控数据的恢复有十分重要的作用,例如DHFS会实时分配给各个视频通道2 MB存储空间,该值由启动扇区中相应参数定义,各通道的视频片段以2 MB为分割,在磁盘中顺序交替存储,但是有些情况下也存在连续存放单一通道2 MB视频片段的情况,假设CHn表示所属通道的2 MB视频片段,在只有3个通道的视频监控系统中,DHFS文件系统中各通道视频片段存储排列情况如图2下所示,视频片段代表视频存储过程中一个2 MB的视频数据块,其中编号为1~6的视频片段为正常录制视频监控的情况,各个通道视频片段交替存储。编号6~10属于连续录制同一通道监控视频的情况。如果DHFS文件系统误格式化或部分视频覆盖的情况下,视频监控系统的文件系统遭到破坏,视频监控的恢复需要通过通道分离与重组进行还原,即分离出1、4、8编号的视频片段,重组成通道一的视频监控文件,分离出2、5、9、10编号的视频片段,重组成通道二的视频监控文件,分离出3、6、7编号的视频片段,重组成通道三的视频监控文件。因此对于DHFS文件系统数据取证问题,将转化成如何确
表1 DHFS帧头部结构
Table 1 Frame head structure of DHFS
┌───────┬───────┬─────────────────────┐
│偏移量 │占用字节 │含义 │
├───────┼───────┼─────────────────────┤
│0x00 │4 │帧起始标识0x44484156 │
├───────┼───────┼─────────────────────┤
│0x04 │2 │帧类型 │
├───────┼───────┼─────────────────────┤
│0x06 │2 │帧通道 │
├───────┼───────┼─────────────────────┤
│0x08 │4 │帧编号 │
├───────┼───────┼─────────────────────┤
│0x0C │4 │帧长度 │
├───────┼───────┼─────────────────────┤
│0x10 │4 │帧创建时间 │
└───────┴───────┴─────────────────────┘
表2 DHFS帧尾部结构
Table 2 Frame tail structure of DHFS
┌────────┬────────┬───────────────────┐
│偏移量 │占用字节 │含义 │
├────────┼────────┼───────────────────┤
│0x00 │4 │帧结束标识0x64686176 │
├────────┼────────┼───────────────────┤
│0x04 │4 │帧长度 │
└────────┴────────┴───────────────────┘
5 API接口
CLIENT_Login
耗时500毫秒
大华DEMO采用的是这个登陆接口
CLIENT_LoginEx2
接口偶尔返回102
等待登录返回超时 |
两个登陆接口耗时都差不多,没有任何的改善
CLIENT_OperateMasterSlaveGroup
调用CLIENT_OperateMasterSlaveGroup进行枪球联动控制,返回错误信息:NET_RETURN_DATA_ERROR _EC(21) 对返回数据的校验出错
过程记录
1)获取到匹配版本的SDK,更新测试返回结果一样
2)联系厂商,提供相关的信息资料
3)排查网页上的枪球联动是否配置正确,标定是否成功
4)通过\演示程序\Mfc分类Demo\19.枪球联动\bin\x64release,重现问题
5)球机通道无法显示视频,demo中硬编码通道号,播放的都是全景的画面
6)修改demo中的通道号,重新编译,标定出错:获取球机中心位置失败
7)得到回复:联系区域人员配置好设备
CLIENT_GetDevConfig
dwOutBufferSize传递进来的结构体尽可能大,避免现场通道数量过多,反而同步不到通道名称,或者不全。
struct DHDEV_CHANNEL_CFG* channelArray = (struct DHDEV_CHANNEL_CFG*)malloc(1024 * sizeof(struct DHDEV_CHANNEL_CFG));
申请1024长度的数组