解码海康摄像机的录像 及 延时装载库

    使用海康的解码库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
时间: 2024-11-08 19:16:14

解码海康摄像机的录像 及 延时装载库的相关文章

海康、大华网络摄像机RTSP URL格式组成及参数配置

经常有开发者咨询大牛直播SDK关于海康.大华网络摄像机RTSP url拼接规则和相关参数配置,虽然很简单,考虑到资料不全,写个博客记录下: 1. 海康摄像机:在IE浏览器输入网络摄像机的IP地址,输入配置的用户名.密码,登陆:视频: 码率类型:主码流和子码流,主码流支持的分辨率比较高: 视频类型:如果是音视频都需要,选择"复合流",如果只需要视频,选择"视频流": 分辨率设置,不再赘述: 码率类型:变码率!!!定码率的话,码率过高: 图像质量:酌情设置: 视频帧率:

海康、大华IPC的rtsp格式

海康: rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream说明:username: 用户名.例如admin.password: 密码.例如12345.ip: 为设备IP.例如 192.0.0.64.port: 端口号默认为554,若为默认可不填写.codec:有h264.MPEG-4.mpeg4这几种.channel: 通道号,起始为1.例如通道1,则为ch1.subtype: 码流类型,主

海康、大华IpCamera RTSP地址和格式

海康: rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream 说明: username: 用户名.例如admin. password: 密码.例如12345. ip: 为设备IP.例如 192.0.0.64. port: 端口号默认为554,若为默认可不填写. codec:有h264.MPEG-4.mpeg4这几种. channel: 通道号,起始为1.例如通道1,则为ch1. subtype

海康/大华 IpCamera RTSP地址和格式

海康:rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream说明:username: 用户名.例如admin.password: 密码.例如12345.ip: 为设备IP.例如 192.0.0.64.port: 端口号默认为554,若为默认可不填写.codec:有h264.MPEG-4.mpeg4这几种.channel: 通道号,起始为1.例如通道1,则为ch1.subtype: 码流类型,主码

海康监控摄像头接入到微信公众号直播流程

注意:1.接入前需要安装工具软件(海康摄像机搜索),安装包在压缩文件中(如已知摄像机IP,不用安装摄像机搜索工具,可直接IE访问摄像机) 2.用于调试的电脑.监控摄像头.嵌入式网关必须在同一局域网中方可进行下面操作 一.设置摄像机参数 设置摄像机固定IP 1.打开HikvisionTools软件,单击设备网络搜索-双击需接入的设备IP-进入WEB设置界面. 2.输入用户名和密码后登录 3.设置-基本配置-TCP/IP---设置成固定IP,然后保存-重启(IP地址根据当前局域网网段设置) 4.重启

(HK1-2)海康相机直接连接电脑不经过路由器设置

解决电脑无法通过网线直连海康摄像机的问题 https://blog.csdn.net/u014552102/article/details/86708371 一.现象:    通过博主的另外一篇博客https://blog.csdn.net/u014552102/article/details/86700057,配置完海康网络摄像机后,摄像机可以通过路由器wifi传输视频声音,并通过手机客户端和电脑客户端播放监控画面了.但是当我们断掉摄像机和电脑的wifi,直接使用网线连接摄像机和电脑后,我们会

Java实现 海康摄像头抓拍图像

先抱怨一下,打死都想不到,海康的摄像头SDK居然是一个Java类,还有必须的两个jar包(jna.jar,examples.jar).鬼能想得到会这么命名. 下面开始吧. 把从官网下载的SDK(和当前系统对应)解压,把库文件整个拷贝到某个目录(我是D:\hik\lib),然后把D:\hik\lib和D:\hik\lib\HCNetSDKCom加入到系统环境变量path中.可以尝试从代码中把这两个文件夹加入path,我没有试成功. 项目引入jna.jar和examples.jar这两个jar包.注

海康网络摄像机调用SDK解码Java版

两个回调函数: FRealDataCallBack 实现预览回调数据 DecCallBack 解码回调函数 在HCNetSDK.java补充相关函数和结构声明 //播放库函数声明,PlayCtrl.dll interface PlayCtrl extends StdCallLibrary { PlayCtrl INSTANCE = (PlayCtrl) Native.loadLibrary("lib\\PlayCtrl", PlayCtrl.class); public static

针对监控摄像机(海康、大华等)进行手动录像的录像文件播放器功能设计

参考上一篇: 针对监控摄像机(海康.大华等)进行手动录像的功能设计 录像后需要自定义一个播放器来播放录像文件. 简单设计界面如下: 打开文件,可暂停,可停止,可以拖动进度条. static int width = 1920, height = 1080; int videoWidth = 639, videoHeight = 479; int YUVWidth = 640, YUVHeight = 480; bool bPause = false; bool bPlayStop = false;