使用海康的解码库playctrl.dll来解码海康的录像。下面的代码仅供参考。
下面的代码演示了这样一种机制:在多个工程中共享代码的时候,有的工程需要调用某些库,有的工程不需要,但是由于源代码互相引用导致即使用不到某个库的程序,也需要随同发布这个库,否则程序会在启动的时候报错找不到指定的库。
解决这个问题的方法之一是使用动态装载,用 LoadLibrary 动态装载库,用 GetProcAddress 获得要调用的函数的地址,用函数指针调用。但是这个方法比较麻烦。
下面代码解决的方法是使用延时装载(DelayLoad)机制,同时使用 LoadLibrary 来判断是否有库。
(1)用延时装载库来避免启动的时候就需要库
#pragma comment(linker, "/DelayLoad:PlayCtrl.dll")
#pragma comment(lib, "Delayimp.lib")
(2)当执行到库里面的函数的时候,会自动延时装载(此时若无法装载库程序会报错)
程序代码里面都是直接静态链接调用库里面的函数。
(3)但在执行之前,用动态装载的方法先判断是否有这个库,如果没有,则返回失败,不继续执行
#ifndef __HSS_HIK_MP4_HSS__
#define __HSS_HIK_MP4_HSS__
/**************************************************************************************************\
* 2012-09-13
播放海康的录像
用法:
int __stdcall auto_hikmp4_callback_imp(LPARAM lParam, DWORD dwTick, LPBITMAPINFOHEADER pbih, LPBYTE pBits)
{
if (dwTick == 0)
{
//播放停止了
}
else
{
ProcessRgb(0, lParam, dwTick, pbih, pBits, pbih->biSizeImage, 0, 0);
}
return 0;
}
auto_hikmp4 ahk;
ahk.param.pCallback = auto_hikmp4_callback_imp;
ahk.param.lParma = (LPARAM)this;
ahk.Open(pszFile);
ahk.Close();
\**************************************************************************************************/
#include <auto_dll.h>
#include <auto_yuv.h>
#include <HBuffer.h>
#include <auto_bitmap_file.h>
#include <StringN.h>
#include "PlayM4.h"
#pragma comment(lib, "\\hss\\R2\\Projects\\Common\\hikmp4\\PlayCtrl.lib")
#pragma comment(linker, "/DelayLoad:PlayCtrl.dll")
#pragma comment(lib, "Delayimp.lib")
typedef int (__stdcall *auto_hikmp4_callback) (LPARAM lParam, DWORD dwTick, LPBITMAPINFOHEADER pbih, LPBYTE pBits);
class auto_hikmp4
{
public:
auto_hikmp4()
{
m_bLibOk = 0;
m_lPort = -1;
m_dwPlayTick = 0;
m_dwFrameCount = 0;
__memzero(param);
}
~auto_hikmp4()
{
Close();
}
struct
{
auto_hikmp4_callback pCallback;
LPARAM lParam;
DWORD bPlayFastest : 1; //2013年4月28日 最高速度播放,不控制帧率
}param;
public:
BOOL Open(LPCTSTR pszFile)
{
Close();
if (!m_bLibOk)
{
auto_lib lib;
//由于对 PlayCtrl.dll 库的调用是延时装载的(DelayLoad)因此即使没有这个库,程序
//也可以正常启动,但是当执行到调用库里面的函数的时候会导致错误。因此这里还要动态装载一下这个库
//这样如果没有这个库,则返回失败不继续执行。如果有这个库,则这里释放动态装载的,下面调用库里面的函数
//的时候 DelayLoad 机制会起作用。
//这种方式即避免了动态装载程序的复杂性,也避免了静态连接库的时候发布也必须带着这个库
//因为在很多工程中共享代码的时候,可能有的工程用不到这个库,但代码互相引用导致还需要包含这个代码
//这样用不到这个库的程序,不用附带发布这个库,也可以正常启动运行。
if (!lib.LoadLibrary("PlayCtrl.dll"))
return FALSE;
lib.Release();
Sleep(10);
m_bLibOk = TRUE;
}
auto_file af;
if (!af.OpenRead(pszFile))
return FALSE;
DWORD mark = 0;
if (!af.Read((LPBYTE)&mark, 4))
return FALSE;
if (mark != *(DWORD*)"4HKH"
&& mark != *(DWORD*)"IMKH"
)
{
return FALSE;
}
af.Close();
Sleep(10);
PlayM4_GetPort(&m_lPort);
if (m_lPort == -1)
return FALSE;
PlayM4_SetDecCallBackM