Files
Ayay/SHH.CameraSdk/Drivers/HikVision/HikPlayMethods.cs

358 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace SHH.CameraSdk;
/// <summary>
/// 海康播放库 PlayCtrl.dll 的封装
/// 完全参考官方 WinPlayCtrl.cs 定义,提供解码、播放、端口管理等核心能力
/// </summary>
public static class HikPlayMethods
{
#region --- (Basic Configuration) ---
/// <summary>
/// PlayCtrl.dll 动态库路径
/// 注意:请确保项目中该路径与实际文件位置一致,否则会导致 DllImport 失败
/// </summary>
private const string DllName = @"Drivers\\Hikvision\\PlayCtrl.dll";
#endregion
#region --- (Constants) ---
/// <summary> 最大支持的通道数 </summary>
public const int PLAYM4_MAX_SUPPORTS = 500;
// 流模式常量
public const int STREAME_REALTIME = 0; // 实时流模式
public const int STREAME_FILE = 1; // 文件流模式
// 帧类型常量(音频/视频)
public const int T_AUDIO16 = 101; // 16位音频帧
public const int T_AUDIO8 = 100; // 8位音频帧
public const int T_UYVY = 1; // UYVY格式视频帧
public const int T_YV12 = 3; // YV12格式视频帧常用
public const int T_RGB32 = 7; // RGB32格式视频帧
// 显示缓冲区大小常量
public const int MAX_DIS_FRAMES = 50; // 最大显示缓冲帧数
public const int MIN_DIS_FRAMES = 1; // 最小显示缓冲帧数
// 源缓冲区大小常量(单位:字节)
public const int SOURCE_BUF_MAX = 1024 * 100000; // 最大源缓冲区100MB
public const int SOURCE_BUF_MIN = 1024 * 50; // 最小源缓冲区50KB
// 错误码常量PlayCtrl.dll 返回错误标识)
public const int PLAYM4_NOERROR = 0; // 无错误
public const int PLAYM4_PARA_OVER = 1; // 参数超出范围
public const int PLAYM4_ORDER_ERROR = 2; // 函数调用顺序错误
public const int PLAYM4_TIMER_ERROR = 3; // 定时器初始化错误
public const int PLAYM4_DEC_VIDEO_ERROR = 4; // 视频解码错误
public const int PLAYM4_DEC_AUDIO_ERROR = 5; // 音频解码错误
public const int PLAYM4_ALLOC_MEMORY_ERROR = 6; // 内存分配错误
public const int PLAYM4_OPEN_FILE_ERROR = 7; // 打开文件错误
public const int PLAYM4_CREATE_OBJ_ERROR = 8; // 创建对象错误
public const int PLAYM4_CREATE_DDRAW_ERROR = 9; // 创建DirectDraw错误
public const int PLAYM4_CREATE_OFFSCREEN_ERROR = 10;// 创建离屏表面错误
public const int PLAYM4_BUF_OVER = 11; // 缓冲区溢出
public const int PLAYM4_CREATE_SOUND_ERROR = 12; // 创建音频设备错误
public const int PLAYM4_SET_VOLUME_ERROR = 13; // 设置音量错误
public const int PLAYM4_SUPPORT_FILE_ONLY = 14; // 仅支持文件流
public const int PLAYM4_SUPPORT_STREAM_ONLY = 15; // 仅支持实时流
public const int PLAYM4_SYS_NOT_SUPPORT = 16; // 系统不支持该功能
public const int PLAYM4_FILEHEADER_UNKNOWN = 17; // 文件头格式未知
public const int PLAYM4_VERSION_INCORRECT = 18; // 版本不匹配
public const int PLAYM4_INIT_DECODER_ERROR = 19; // 解码器初始化错误
public const int PLAYM4_CHECK_FILE_ERROR = 20; // 校验文件错误
public const int PLAYM4_INIT_TIMER_ERROR = 21; // 初始化定时器错误
public const int PLAYM4_BLT_ERROR = 22; // 图像绘制错误
public const int PLAYM4_UPDATE_ERROR = 23; // 更新显示错误
// PTZ控制命令常量保留自定义逻辑官方示例未包含
public const uint ZOOM_IN = 11; // 焦距变大(拉近)
public const uint ZOOM_OUT = 12; // 焦距变小(拉远)
public const uint FOCUS_NEAR = 13; // 焦点前调
public const uint FOCUS_FAR = 14; // 焦点后调
public const uint IRIS_OPEN = 15; // 光圈扩大
public const uint IRIS_CLOSE = 16; // 光圈缩小
public const uint TILT_UP = 21; // 云台上仰
public const uint TILT_DOWN = 22; // 云台下俯
public const uint PAN_LEFT = 23; // 云台左转
public const uint PAN_RIGHT = 24; // 云台右转
public const uint UP_LEFT = 25; // 上左移动
public const uint UP_RIGHT = 26; // 上右移动
public const uint DOWN_LEFT = 27; // 下左移动
public const uint DOWN_RIGHT = 28; // 下右移动
public const uint PAN_AUTO = 29; // 云台自动扫描
#endregion
#region --- (Structs) ---
/// <summary>
/// 帧信息结构体:存储解码后帧的宽高、帧率、序号等关键信息
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct FRAME_INFO
{
public int nWidth; // 帧宽度(像素)
public int nHeight; // 帧高度(像素)
public int nStamp; // 时间戳
public int nType; // 帧类型(对应 T_XXX 常量)
public int nFrameRate; // 帧率fps
public uint dwFrameNum; // 帧序号
}
/// <summary>
/// 帧位置结构体:存储文件流中帧的位置、时间等信息
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct FRAME_POS
{
public int nFilePos; // 文件中的位置偏移
public int nFrameNum; // 帧序号
public int nFrameTime; // 帧时间(毫秒)
public int nErrorFrameNum; // 错误帧数
public IntPtr pErrorTime; // 错误时间数组指针
public int nErrorLostFrameNum; // 丢失的错误帧数
public int nErrorFrameSize; // 错误帧大小
}
/// <summary>
/// 帧类型结构体:存储帧数据缓冲区、大小等信息
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct FRAME_TYPE
{
[MarshalAs(UnmanagedType.LPStr)]
public string pDataBuf; // 帧数据缓冲区指针
public int nSize; // 缓冲区大小(字节)
public int nFrameNum; // 帧序号
public bool bIsAudio; // 是否为音频帧
public int nReserved; // 保留字段置0
}
#endregion
#region --- (Delegates) ---
/// <summary>
/// 解码回调委托 (对应官方 DECCBFUN)
/// 功能:解码完成后触发,返回解码后的帧数据
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <param name="pBuf">解码后数据缓冲区指针</param>
/// <param name="nSize">缓冲区大小(字节)</param>
/// <param name="pFrameInfo">帧信息结构体(引用传递)</param>
/// <param name="nReserved1">保留字段1置0</param>
/// <param name="nReserved2">保留字段2置0</param>
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void DECCBFUN(
int nPort,
IntPtr pBuf,
int nSize,
ref FRAME_INFO pFrameInfo,
int nReserved1,
int nReserved2
);
/// <summary>
/// 显示回调委托 (对应官方 DISPLAYCBFUN)
/// 功能:帧数据准备显示时触发,用于自定义渲染逻辑
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <param name="pBuf">显示数据缓冲区指针</param>
/// <param name="nSize">缓冲区大小(字节)</param>
/// <param name="nWidth">显示宽度(像素)</param>
/// <param name="nHeight">显示高度(像素)</param>
/// <param name="nStamp">时间戳</param>
/// <param name="nType">数据类型(对应 T_XXX 常量)</param>
/// <param name="nReserved">保留字段置0</param>
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void DISPLAYCBFUN(
int nPort,
IntPtr pBuf,
int nSize,
int nWidth,
int nHeight,
int nStamp,
int nType,
int nReserved
);
/// <summary>
/// 文件结束回调委托
/// 功能:文件流播放完成时触发
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <param name="pUser">用户自定义数据指针</param>
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void FILEENDCALLBACK(int nPort, IntPtr pUser);
#endregion
#region --- API (Dll Imports) ---
/// <summary>
/// 获取闲置的播放端口。
/// <para>[警告] 此函数非线程安全且端口资源有限最多500个。</para>
/// <para>高并发场景下必须加全局锁,防止端口分配冲突。</para>
/// </summary>
/// <param name="nPort">输出参数:获取到的闲置端口号(输出-1表示失败</param>
/// <returns>获取成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_GetPort(ref int nPort);
/// <summary>
/// 释放播放端口
/// 功能:不再使用端口时调用,避免端口资源泄漏
/// </summary>
/// <param name="nPort">要释放的端口号</param>
/// <returns>释放成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_FreePort(int nPort);
/// <summary>
/// 打开流
/// 功能:初始化端口的流缓冲区,准备接收流数据
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <param name="pFileHeadBuf">文件头数据缓冲区指针(实时流可为空)</param>
/// <param name="nSize">缓冲区大小(字节)</param>
/// <param name="nBufPoolSize">流缓冲区池大小(字节)</param>
/// <returns>打开成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_OpenStream(int nPort, IntPtr pFileHeadBuf, uint nSize, uint nBufPoolSize);
/// <summary>
/// 关闭流
/// 功能:停止接收流数据,释放流缓冲区资源
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <returns>关闭成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_CloseStream(int nPort);
/// <summary>
/// 开始播放
/// 功能:启动解码和显示流程,绑定到指定窗口句柄
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <param name="hWnd">显示窗口句柄IntPtr.Zero 表示不绑定窗口)</param>
/// <returns>启动成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_Play(int nPort, IntPtr hWnd);
/// <summary>
/// 停止播放
/// 功能:停止解码和显示,释放播放相关资源
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <returns>停止成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_Stop(int nPort);
/// <summary>
/// 输入流数据
/// 功能:向播放端口推送原始流数据,供解码使用
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <param name="pBuf">流数据缓冲区指针</param>
/// <param name="nSize">数据大小(字节)</param>
/// <returns>输入成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_InputData(int nPort, IntPtr pBuf, uint nSize);
/// <summary>
/// 设置解码回调 (Ex版本)
/// 功能:绑定解码完成后的回调函数,用于获取解码后的帧数据
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <param name="DecCBFun">解码回调函数委托</param>
/// <param name="pDest">目标缓冲区指针(可为空)</param>
/// <param name="nDestSize">目标缓冲区大小(字节)</param>
/// <returns>设置成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_SetDecCallBackEx(int nPort, DECCBFUN DecCBFun, IntPtr pDest, int nDestSize);
/// <summary>
/// 设置流打开模式
/// 功能:指定端口接收的流类型(实时流/文件流)
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <param name="nMode">流模式(对应 STREAME_XXX 常量)</param>
/// <returns>设置成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_SetStreamOpenMode(int nPort, uint nMode);
/// <summary>
/// 设置显示缓冲区数量
/// 功能:调整显示缓冲帧数,平衡流畅度与延迟
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <param name="nNum">缓冲帧数范围MIN_DIS_FRAMES ~ MAX_DIS_FRAMES</param>
/// <returns>设置成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_SetDisplayBuf(int nPort, uint nNum);
/// <summary>
/// 设置叠加模式
/// 功能:配置图像叠加方式及透明色
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <param name="bOverlay">是否启用叠加1=启用0=禁用)</param>
/// <param name="colorKey">透明色键值</param>
/// <returns>设置成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_SetOverlayMode(int nPort, int bOverlay, uint colorKey);
/// <summary>
/// 获取最后一次错误码
/// 功能API 调用失败后,获取具体错误原因(对应 PLAYM4_XXX 错误常量)
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <returns>错误码0 表示无错误)</returns>
[DllImport(DllName)]
public static extern uint PlayM4_GetLastError(int nPort);
/// <summary>
/// 设置视频解码模式
/// 功能:切换硬解码/软解码模式(补充:用于硬件加速优化)
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <param name="nMode">解码模式0=软解码1=硬解码,具体值参考官方文档)</param>
/// <returns>设置成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_SetDecVideoMode(int nPort, int nMode);
/// <summary>
/// 获取源缓冲区剩余空间
/// 功能:查询端口流缓冲区的剩余可用空间(字节)
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <returns>剩余空间大小(字节)</returns>
[DllImport(DllName)]
public static extern uint PlayM4_GetSourceBufferRemain(int nPort);
/// <summary>
/// 重置源缓冲区
/// 功能:清空端口流缓冲区中的未解码数据
/// </summary>
/// <param name="nPort">播放端口号</param>
/// <returns>重置成功返回 true失败返回 false</returns>
[DllImport(DllName)]
public static extern bool PlayM4_ResetSourceBuffer(int nPort);
// =========================================================================
// 🚀 [修正] 适配 V6.1.9+ 新版 SDK 的硬解码 API
// =========================================================================
/// <summary>
/// 设置解码引擎 (扩展版)
/// 对应 C++: BOOL PlayM4_SetDecodeEngineEx(LONG nPort, DWORD dwEngine);
/// </summary>
/// <param name="nPort">通道号</param>
/// <param name="dwEngine">0:软解, 1:显卡硬解(D3D9), 2:显卡硬解(D3D11), 3:Intel核显</param>
/// <returns></returns>
[DllImport("PlayCtrl.dll")]
public static extern bool PlayM4_SetDecodeEngineEx(int nPort, uint dwEngine);
#endregion
}