以前做了很多年的视频监控客户端,有段时间是接入大华,海康,axis,一传等sdk,在我们自己的监控系统中使用。
这是十年前的问题了,大华sdk使用的时候存在速度控制,逆向播放,退出缓慢,定位控制,停止播放画面停留等问题,当时(2012年)进行了记录。
void CDevMng::CheckSpeedCtrl()
{
LONG LoginId = GetLoginId();
if(0 == LoginId)return;
#if 0
DH_DEV_ENABLE_INFO stuEnableInfo = {0};
int nRetLen = 0;
BOOL bRet = CLIENT_QuerySystemInfo(LoginId, ABILITY_DEVALL_INFO, (char*)&stuEnableInfo, sizeof(DH_DEV_ENABLE_INFO), &nRetLen);
if (!bRet)return;
if(stuEnableInfo.IsFucEnable[EN_PLAYBACK_SPEED_CTRL] != 0)
{
if(m_pDevReplay)
{
m_pDevReplay->m_bSpeedCtrl = TRUE;
}
}
else
{
::MessageBox(NULL,_T("cannot control speed!"), _T("Prompt"),MB_OK);
}
#endif
m_pDevReplay->m_bSpeedCtrl = TRUE; //查询接口显示不可以进行速度控制,现在设置默认可以。
}
可以使用CLIENT_SetFramePlayBack设置帧率,这是成功的
BOOL bRet = CLIENT_SetFramePlayBack(m_lPlayBack,nRate);
没有使用
CLIENT_FastPlayBack,CLIENT_SlowPlayBack,CLIENT_NormalPlayBack
答复
这个接口只有特定机型才支持。
远程Demo没体现的接口请谨慎使用
调用
BOOL bRet = CLIENT_PlayBackControlDirection(m_lPlayBack,TRUE);
然后调用
BOOL bRet = CLIENT_SetFramePlayBack(m_lPlayBack,25);
或者
BOOL bRet = CLIENT_NormalPlayBack(m_lPlayBack);
BOOL bRet = CLIENT_FastPlayBack(m_lPlayBack);
结果无效
答复:
只有特定的设备,特定的SDK程序才支持倒放
只要不是定制的,都不支持倒放的
接口不提供3倍速播放。
自己做实现,自己做显示,回调码流后,送播放库解码可以自行控制解码速度,解码出YUV自行刷屏
不知道是不是退出需要调用什么接口?CLIENT_Cleanup();函数已经调用。
sdk的例子程序退出很快。存在有4个线程超时退出。
例子程序中回放窗口是一个picture ctrl,而我的程序中使用的却是一个atlcom窗口。
主线程阻塞
ntdll.dll!76e47094()
[下面的框架可能不正确和/或缺失,没有为 ntdll.dll 加载符号]
ntdll.dll!76e46a24()
KernelBase.dll!74f5179c()
KernelBase.dll!74f5c31c()
kernel32.dll!76a4baf3()
kernel32.dll!76a4baa2()
dhplay.dll!01fa0deb()
dhplay.dll!01fa009c()
dhplay.dll!01fc66de()
dhplay.dll!01fc6681()
dhplay.dll!01fc6545()
dhplay.dll!01fc65dd()
ntdll.dll!76e58968()
ntdll.dll!76e22708()
ntdll.dll!76e226e7()
ntdll.dll!76e5c8b8()
KernelBase.dll!74f588bc()
ole32.dll!7584c10b()
ole32.dll!7584c1e1()
ole32.dll!7584c1f5()
ole32.dll!7585b749()
ole32.dll!7585b68f()
ole32.dll!758a0ccb()
> TestPlayer.exe!AfxOleTerm(int bJustRevoke=0) 行123 C++ //::OleUninitialize();
TestPlayer.exe!AfxOleTermOrFreeLib(int bTerm=1, int bJustRevoke=0) 行138 C++
TestPlayer.exe!AfxWinTerm() 行47 C++
其他的线程
> ntdll.dll!76e47094()
[下面的框架可能不正确和/或缺失,没有为 ntdll.dll 加载符号]
ntdll.dll!76e46a04()
KernelBase.dll!74f569dc()
kernel32.dll!76a4bc8e()
kernel32.dll!76a4bcfc()
dhplay.dll!01fa0b4a()
kernel32.dll!76a53c45()
ntdll.dll!76e6377b()
ntdll.dll!76e6374e()
表现为线程返回-1,应该是强行终止线程。
线程 'Win32 线程' (0x17c0) 已退出,返回值为 -1 (0xffffffff)。
线程 'memcmp' (0xea8) 已退出,返回值为 -1 (0xffffffff)。
线程 'Win32 线程' (0x12f0) 已退出,返回值为 -1 (0xffffffff)。
线程 'Win32 线程' (0xd18) 已退出,返回值为 -1 (0xffffffff)。
依次调用这些接口
m_bInitOK = CLIENT_Init(DisConnectFunc, (DWORD)this);
LIENT_Login(pchDVRIP,wDVRPort,pchUserName,pchPassword,&deviceInfo,&err);
DWORD dwError = CLIENT_GetLastError();
Ret = CLIENT_RealPlay(LoginID,nChannel,m_hWndDisp);//Play video directly
CLIENT_SetRealDataCallBackEx(lRet, RealDataCallBackEx, (DWORD)this, 0x1f);
bRealPlay = CLIENT_StopRealPlay(m_DispHandle);First close CLIENT_RealPlay
BOOL bSuccess = CLIENT_Logout(m_pDevMng->GetLoginId());
CLIENT_Cleanup();
退出的时候有些线程需要超时才能退出
我以前装过perl,但是发现装了之后sdk的接口无法调用成功,然后卸载就好了。
是不是这个有影响?
答复
CLIENT_SetRealDataCallBackEx回调做了什么处理?你把回调注视掉看看,是否就能快速释放了
我们Demo没有延迟释放问题?
缘(9611153) 10:40:20
去掉也一样,并且我使用了错误的ip,用户名,密码,在退出的时候也有迟延。
我把这个sdk封装到了atlcom里面,播放器的窗口是atl的界面,然后使用CreateControl的方法创建了窗口,放置到一个大的activex窗口里面。并不是直接放在mfc里面,不知道这种情况你们有没有测试过。
[5616] CDevReplay::PlayBackByTime nChannelId=0 StartTime=(2012/10/10 13:00:00) StopTime=(2012/10/10 13:27:25)
[5616] CDevReplay::GetCurTime CurOsdTime=(2012/10/10 13:22:32)
调用播放接口CLIENT_PlayBackByTimeEx,从2012/10/10 13:00:00开始播放,
但是调用CLIENT_GetPlayBackOsdTime接口获取的当前时间却是从2012/10/10 13:22:32。
不清楚这是为什么?
但是可以使用CLIENT_SeekPlayBack函数手动定位到2012/10/10 13:00:00和2012/10/10 13:22:32之间的位置, 屏幕上的时间可以看到,比如显示13:12:12.
大华录像文件正常播放没有问题,但是定位的时候有问题,不是返回的进度不正确,就是返回的数据不正确。
按时间播放:2012/10/10 14:00:00到15点,定位到14:40分的时候,通过回调PlayCallBack获取的时间点是14:10分的数据
按文件播放: 文件大小是400000B,定位到300000B的时候,录像播放的是100000B时候的数据。
大华sdk播放,停止播放之后还有图像保留,没有刷新窗口。
qq:9611153 微信lgs9611153