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

347 lines
15 KiB
C#
Raw Normal View History

using System;
using System.Runtime.InteropServices;
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);
#endregion
}