你的位置:首页 > 操作系统

[操作系统]解码海康摄像机的录像 及 延时装载库


    使用海康的解码库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_SetDecCallBackMend(m_lPort, DecCBFun, (long)this);    PlayM4_SetFileEndCallback(m_lPort, FileEndCallback, (void*)this);    if (param.bPlayFastest)    {      PlayM4_SetStreamOpenMode(m_lPort, STREAME_REALTIME);    }    if(!PlayM4_OpenFile(m_lPort, (char*)pszFile))      return FALSE;    m_dwFrameCount = PlayM4_GetFileTotalFrames(m_lPort);    PlayM4_Play(m_lPort, 0);    return TRUE;  }  void CallbackDecode(FRAME_INFO* pfi, LPBYTE pBuffer, int nSize)  {    if (pfi->nType != T_YV12)    //T_RGB32, T_UYVY      return;    DWORD dwTick = GetTickCount();    if (m_dwPlayTick == 0)      m_dwPlayTick = dwTick;    if (!param.bPlayFastest)  //2013年4月28日    {      while (dwTick + 5 < m_dwPlayTick + pfi->nStamp)      {        Sleep(5);        dwTick = GetTickCount();      }    }    int width = pfi->nWidth;    int height = pfi->nHeight;    auto_bitmap_file abf;    LPBYTE pb = abf.GetBitmap(&m_BufBmp, 24, width, height);    if (pb == 0)      return;    m_yuv.i420(pBuffer, pb, width, height);    if (param.pCallback)    {      param.pCallback(param.lParam, dwTick, abf.bih(), abf.bits());    }  }  static void CALLBACK DecCBFun(long nPort, char * pBuf, long nSize, FRAME_INFO * pFrameInfo, long nReserved1, long nReserved2)  {    auto_hikmp4* phm = (auto_hikmp4*)nReserved1;    if (phm == 0)      return;    ASSERT(nPort == phm->m_lPort);    phm->CallbackDecode(pFrameInfo, (LPBYTE)pBuf, nSize);  }  static void CALLBACK FileEndCallback(long nPort, void *pUser)  {    auto_hikmp4* phm = (auto_hikmp4*)pUser;    if (phm == 0)      return;    ASSERT(nPort == phm->m_lPort);    if (phm->param.pCallback)    {      phm->param.pCallback(phm->param.lParam, 0, 0, 0);    }  }  void Close()  {    if (m_lPort != -1)    {      PlayM4_Stop(m_lPort);      PlayM4_CloseFile(m_lPort);      PlayM4_FreePort(m_lPort);      m_lPort = -1;    }    m_dwPlayTick = 0;  }public:  BOOL    m_bLibOk;  LONG    m_lPort;  auto_yuv  m_yuv;  HBuffer    m_BufBmp;  DWORD    m_dwPlayTick;  DWORD    m_dwFrameCount;};#endif