namespace SHH.CameraSdk;
///
/// 海康播放库 PlayCtrl.dll 的封装
/// 完全参考官方 WinPlayCtrl.cs 定义,提供解码、播放、端口管理等核心能力
///
public static class HikPlayMethods
{
#region --- 基础配置 (Basic Configuration) ---
///
/// PlayCtrl.dll 动态库路径
/// 注意:请确保项目中该路径与实际文件位置一致,否则会导致 DllImport 失败
///
private const string DllName = @"Drivers\\Hikvision\\PlayCtrl.dll";
#endregion
#region --- 常量定义 (Constants) ---
/// 最大支持的通道数
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) ---
///
/// 帧信息结构体:存储解码后帧的宽高、帧率、序号等关键信息
///
[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; // 帧序号
}
///
/// 帧位置结构体:存储文件流中帧的位置、时间等信息
///
[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; // 错误帧大小
}
///
/// 帧类型结构体:存储帧数据缓冲区、大小等信息
///
[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) ---
///
/// 解码回调委托 (对应官方 DECCBFUN)
/// 功能:解码完成后触发,返回解码后的帧数据
///
/// 播放端口号
/// 解码后数据缓冲区指针
/// 缓冲区大小(字节)
/// 帧信息结构体(引用传递)
/// 保留字段1(置0)
/// 保留字段2(置0)
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void DECCBFUN(
int nPort,
IntPtr pBuf,
int nSize,
ref FRAME_INFO pFrameInfo,
int nReserved1,
int nReserved2
);
///
/// 显示回调委托 (对应官方 DISPLAYCBFUN)
/// 功能:帧数据准备显示时触发,用于自定义渲染逻辑
///
/// 播放端口号
/// 显示数据缓冲区指针
/// 缓冲区大小(字节)
/// 显示宽度(像素)
/// 显示高度(像素)
/// 时间戳
/// 数据类型(对应 T_XXX 常量)
/// 保留字段(置0)
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void DISPLAYCBFUN(
int nPort,
IntPtr pBuf,
int nSize,
int nWidth,
int nHeight,
int nStamp,
int nType,
int nReserved
);
///
/// 文件结束回调委托
/// 功能:文件流播放完成时触发
///
/// 播放端口号
/// 用户自定义数据指针
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void FILEENDCALLBACK(int nPort, IntPtr pUser);
#endregion
#region --- API 导入 (Dll Imports) ---
///
/// 获取闲置的播放端口。
/// [警告] 此函数非线程安全,且端口资源有限(最多500个)。
/// 高并发场景下必须加全局锁,防止端口分配冲突。
///
/// 输出参数:获取到的闲置端口号(输出-1表示失败)
/// 获取成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_GetPort(ref int nPort);
///
/// 释放播放端口
/// 功能:不再使用端口时调用,避免端口资源泄漏
///
/// 要释放的端口号
/// 释放成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_FreePort(int nPort);
///
/// 打开流
/// 功能:初始化端口的流缓冲区,准备接收流数据
///
/// 播放端口号
/// 文件头数据缓冲区指针(实时流可为空)
/// 缓冲区大小(字节)
/// 流缓冲区池大小(字节)
/// 打开成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_OpenStream(int nPort, IntPtr pFileHeadBuf, uint nSize, uint nBufPoolSize);
///
/// 关闭流
/// 功能:停止接收流数据,释放流缓冲区资源
///
/// 播放端口号
/// 关闭成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_CloseStream(int nPort);
///
/// 开始播放
/// 功能:启动解码和显示流程,绑定到指定窗口句柄
///
/// 播放端口号
/// 显示窗口句柄(IntPtr.Zero 表示不绑定窗口)
/// 启动成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_Play(int nPort, IntPtr hWnd);
///
/// 停止播放
/// 功能:停止解码和显示,释放播放相关资源
///
/// 播放端口号
/// 停止成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_Stop(int nPort);
///
/// 输入流数据
/// 功能:向播放端口推送原始流数据,供解码使用
///
/// 播放端口号
/// 流数据缓冲区指针
/// 数据大小(字节)
/// 输入成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_InputData(int nPort, IntPtr pBuf, uint nSize);
///
/// 设置解码回调 (Ex版本)
/// 功能:绑定解码完成后的回调函数,用于获取解码后的帧数据
///
/// 播放端口号
/// 解码回调函数委托
/// 目标缓冲区指针(可为空)
/// 目标缓冲区大小(字节)
/// 设置成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_SetDecCallBackEx(int nPort, DECCBFUN DecCBFun, IntPtr pDest, int nDestSize);
///
/// 设置流打开模式
/// 功能:指定端口接收的流类型(实时流/文件流)
///
/// 播放端口号
/// 流模式(对应 STREAME_XXX 常量)
/// 设置成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_SetStreamOpenMode(int nPort, uint nMode);
///
/// 设置显示缓冲区数量
/// 功能:调整显示缓冲帧数,平衡流畅度与延迟
///
/// 播放端口号
/// 缓冲帧数(范围:MIN_DIS_FRAMES ~ MAX_DIS_FRAMES)
/// 设置成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_SetDisplayBuf(int nPort, uint nNum);
///
/// 设置叠加模式
/// 功能:配置图像叠加方式及透明色
///
/// 播放端口号
/// 是否启用叠加(1=启用,0=禁用)
/// 透明色键值
/// 设置成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_SetOverlayMode(int nPort, int bOverlay, uint colorKey);
///
/// 获取最后一次错误码
/// 功能:API 调用失败后,获取具体错误原因(对应 PLAYM4_XXX 错误常量)
///
/// 播放端口号
/// 错误码(0 表示无错误)
[DllImport(DllName)]
public static extern uint PlayM4_GetLastError(int nPort);
///
/// 设置视频解码模式
/// 功能:切换硬解码/软解码模式(补充:用于硬件加速优化)
///
/// 播放端口号
/// 解码模式(0=软解码,1=硬解码,具体值参考官方文档)
/// 设置成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_SetDecVideoMode(int nPort, int nMode);
///
/// 获取源缓冲区剩余空间
/// 功能:查询端口流缓冲区的剩余可用空间(字节)
///
/// 播放端口号
/// 剩余空间大小(字节)
[DllImport(DllName)]
public static extern uint PlayM4_GetSourceBufferRemain(int nPort);
///
/// 重置源缓冲区
/// 功能:清空端口流缓冲区中的未解码数据
///
/// 播放端口号
/// 重置成功返回 true,失败返回 false
[DllImport(DllName)]
public static extern bool PlayM4_ResetSourceBuffer(int nPort);
// =========================================================================
// 🚀 [修正] 适配 V6.1.9+ 新版 SDK 的硬解码 API
// =========================================================================
///
/// 设置解码引擎 (扩展版)
/// 对应 C++: BOOL PlayM4_SetDecodeEngineEx(LONG nPort, DWORD dwEngine);
///
/// 通道号
/// 0:软解, 1:显卡硬解(D3D9), 2:显卡硬解(D3D11), 3:Intel核显
///
[DllImport("PlayCtrl.dll")]
public static extern bool PlayM4_SetDecodeEngineEx(int nPort, uint dwEngine);
#endregion
}