C#中如何使用SDK解码回调函数DecCallbackFUN()
发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,这篇文章主要介绍C#中如何使用SDK解码回调函数DecCallbackFUN(),文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!代码1、摄像头操作代码 struct Cam
千家信息网最后更新 2025年01月18日C#中如何使用SDK解码回调函数DecCallbackFUN()
这篇文章主要介绍C#中如何使用SDK解码回调函数DecCallbackFUN(),文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
代码
1、摄像头操作代码
struct CameraInfo { public string strIP; public short nPort; public string strUserName; public string strPassword; } class IDeviceCamera { public Image m_img = null; public virtual bool InitCamera( CameraInfo stInfo ) { return true; } } class DeviceCamera : IDeviceCamera { private CameraInfo m_stCameraInfo; private bool m_bInitSDK = false; private Int32 m_lUserID = -1; private Int32 m_lRealHandle = -1; private Int32 m_lPort = -1; CHCNetSDK.REALDATACALLBACK RealData = null; //必须得定义为成员变量 public override bool InitCamera( CameraInfo stInfo ) { m_stCameraInfo = stInfo; m_bInitSDK = CHCNetSDK.NET_DVR_Init(); if ( !m_bInitSDK ) { uint nError = CHCNetSDK.NET_DVR_GetLastError(); } CHCNetSDK.NET_DVR_SetConnectTime( 5000, 1 ); CHCNetSDK.NET_DVR_SetReconnect( 10000, 1 ); if ( m_bInitSDK == false ) { MessageBox.Show( "NET_DVR_Init error!" ); return false; } else { //保存SDK日志 To save the SDK log CHCNetSDK.NET_DVR_SetLogToFile( 3, "C:\\SdkLog\\", true ); } string DVRIPAddress = stInfo.strIP; //设备IP地址或者域名 Device IP Int16 DVRPortNumber = stInfo.nPort; //设备服务端口号 Device Port string DVRUserName = stInfo.strUserName;//设备登录用户名 User name to login string DVRPassword = stInfo.strPassword;//设备登录密码 Password to login CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30(); m_lUserID = CHCNetSDK.NET_DVR_Login_V30( DVRIPAddress, DVRPortNumber, DVRUserName, DVRPassword, ref DeviceInfo ); if ( m_lUserID < 0 ) { MessageBox.Show( "登录失败!" ); CHCNetSDK.NET_DVR_Cleanup(); return false; } // CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO(); lpPreviewInfo.hPlayWnd = (IntPtr)null; lpPreviewInfo.lChannel = 1; lpPreviewInfo.dwStreamType = 0; //码流类型:0-主码流,1-子码流,2-码流3,3-码流4,以此类推 lpPreviewInfo.dwLinkMode = 0; //连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP lpPreviewInfo.bBlocked = true; //0- 非阻塞取流,1- 阻塞取流 lpPreviewInfo.dwDisplayBufNum = 15; //播放库播放缓冲区最大缓冲帧数 //使用回调函数取摄像头数据 RealData = new CHCNetSDK.REALDATACALLBACK( RealDataCallBack );//预览实时流回调函数 IntPtr pUser = new IntPtr();//用户数据 m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40( m_lUserID, ref lpPreviewInfo, RealData, pUser ); CHCNetSDK.NET_DVR_RigisterDrawFun( m_lRealHandle, new CHCNetSDK.DRAWFUN( cbDrawFun ), 0 );//回调函数:绘制图标 return true; } private uint nLastErr = 0; private static PlayCtrl.DECCBFUN m_fDisplayFun = null; private IntPtr m_ptrRealHandle; public void RealDataCallBack( Int32 lRealHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser ) { //下面数据处理建议使用委托的方式 switch ( dwDataType ) { case CHCNetSDK.NET_DVR_SYSHEAD: // sys head if ( dwBufSize > 0 ) { if ( m_lPort >= 0 ) return; //同一路码流不需要多次调用开流接口 //获取播放句柄 Get the port to play if ( !PlayCtrl.PlayM4_GetPort( ref m_lPort ) ) { nLastErr = PlayCtrl.PlayM4_GetLastError( m_lPort ); break; } //设置流播放模式 Set the stream mode: real-time stream mode if ( !PlayCtrl.PlayM4_SetStreamOpenMode( m_lPort, PlayCtrl.STREAME_REALTIME ) ) { nLastErr = PlayCtrl.PlayM4_GetLastError( m_lPort ); //str = "Set STREAME_REALTIME mode failed, error code= " + nLastErr; //this.BeginInvoke( AlarmInfo, str ); } //打开码流,送入头数据 Open stream if ( !PlayCtrl.PlayM4_OpenStream( m_lPort, pBuffer, dwBufSize, 2 * 1024 * 1024 ) ) { nLastErr = PlayCtrl.PlayM4_GetLastError( m_lPort ); //str = "PlayM4_OpenStream failed, error code= " + nLastErr; //this.BeginInvoke( AlarmInfo, str ); break; } //设置显示缓冲区个数 Set the display buffer number if ( !PlayCtrl.PlayM4_SetDisplayBuf( m_lPort, 15 ) ) { nLastErr = PlayCtrl.PlayM4_GetLastError( m_lPort ); //str = "PlayM4_SetDisplayBuf failed, error code= " + nLastErr; //this.BeginInvoke( AlarmInfo, str ); } //设置显示模式 Set the display mode //if ( !PlayCtrl.PlayM4_SetOverlayMode( m_lPort, 0, 0) ) //play off screen //{ // nLastErr = PlayCtrl.PlayM4_GetLastError( m_lPort ); // //str = "PlayM4_SetOverlayMode failed, error code= " + nLastErr; // //this.BeginInvoke( AlarmInfo, str ); //} //设置解码回调函数,获取解码后音视频原始数据 Set callback function of decoded data m_fDisplayFun = new PlayCtrl.DECCBFUN( DecCallbackFUN ); if ( !PlayCtrl.PlayM4_SetDecCallBackEx( m_lPort, m_fDisplayFun, IntPtr.Zero, 0 ) ) { //this.BeginInvoke( AlarmInfo, "PlayM4_SetDisplayCallBack fail" ); } //开始解码 Start to play if ( !PlayCtrl.PlayM4_Play( m_lPort, m_ptrRealHandle ) ) { nLastErr = PlayCtrl.PlayM4_GetLastError( m_lPort ); //str = "PlayM4_Play failed, error code= " + nLastErr; //this.BeginInvoke( AlarmInfo, str ); break; } } break; case CHCNetSDK.NET_DVR_STREAMDATA: // video stream data default: //the other data if ( dwBufSize > 0 && m_lPort != -1 ) { for ( int i = 0; i < 999; i++ ) { //送入码流数据进行解码 Input the stream data to decode if ( !PlayCtrl.PlayM4_InputData( m_lPort, pBuffer, dwBufSize ) ) { nLastErr = PlayCtrl.PlayM4_GetLastError( m_lPort ); //str = "PlayM4_InputData failed, error code= " + nLastErr; Thread.Sleep( 2 ); } else break; } } break; } } //解码回调函数 private void DecCallbackFUN( int nPort, IntPtr pBuf, int nSize, ref PlayCtrl.FRAME_INFO pFrameInfo, int nReserved1, int nReserved2 ) { if ( pFrameInfo.nType == 3 ) //#define T_YV12 3 { byte[] byteBuffYV12 = new byte[ nSize ]; Marshal.Copy( pBuf, byteBuffYV12, 0, nSize ); long lRGBSize = (long)pFrameInfo.nWidth * pFrameInfo.nHeight * 4; byte[] bufferRGB32 = new byte[ lRGBSize ]; CommonFun.YV12_to_RGB32( byteBuffYV12, bufferRGB32, pFrameInfo.nWidth, pFrameInfo.nHeight ); byteBuffYV12 = null; Bitmap bmpFromGRB32 = CommonFun.RGB32_to_Image( bufferRGB32, pFrameInfo.nWidth, pFrameInfo.nHeight ); bufferRGB32 = null; if ( null == bmpFromGRB32 ) return; m_img = bmpFromGRB32; } } }
注:得到的m_img用于PictureBox进行显示。
2、YV12转换为RGB32、RGB32转换为Image代码
class CommonFun { public static bool YV12_to_RGB32( byte[] buffYV12, byte[] bufferRGB32, int nWidth, int nHeight ) { if( buffYV12.Length < 0 || bufferRGB32.Length < 0 ) return false; long nYLen = (long)nWidth * nHeight; int nHfWidth = ( nWidth >> 1 ); if ( nYLen < 1 || nHfWidth < 1 ) return false; byte[] byteYData = buffYV12.Skip( 0 ).Take( nWidth*nHeight ).ToArray(); byte[] byteUData = buffYV12.Skip( nWidth*nHeight ).Take( (nHeight/2)*(nWidth/2) ).ToArray(); byte[] byteVData = buffYV12.Skip( nWidth*nHeight + (nHeight/2)*(nWidth/2) ).Take( (nHeight/2)*(nWidth/2) ).ToArray(); if ( byteYData.Length < 0 || byteVData.Length < 0 || byteUData.Length < 0 ) return false; int[] nRgb = new int[4]; for( int nRow = 0; nRow < nHeight; nRow++ ) { for( int nCol = 0; nCol < nWidth; nCol++ ) { int Y = byteYData[nRow*nWidth + nCol]; int U = byteUData[(nRow / 2)*(nWidth / 2) + (nCol / 2)]; int V = byteVData[(nRow / 2)*(nWidth / 2) + (nCol / 2)]; int R = Y + (U - 128) + (((U - 128) * 103) >> 8); int G = Y - (((V - 128) * 88) >> 8) - (((U - 128) * 183) >> 8); int B = Y + (V - 128) + (((V - 128) * 198) >> 8); // r分量值 R = R<0 ? 0 : R; nRgb[2] = R > 255 ? 255 : R; // g分量值 G = G<0 ? 0 : G; nRgb[1] = G > 255 ? 255 : G; // b分量值 B = B<0 ? 0 : B; nRgb[0] = B > 255 ? 255 : B; //A分量值 nRgb[ 3 ] = 255; //Out RGB Buffer bufferRGB32[4 * (nRow*nWidth + nCol) + 0] = (byte)nRgb[0]; bufferRGB32[4 * (nRow*nWidth + nCol) + 1] = (byte)nRgb[1]; bufferRGB32[4 * (nRow*nWidth + nCol) + 2] = (byte)nRgb[2]; bufferRGB32[4 * (nRow*nWidth + nCol) + 3] = (byte)nRgb[3]; } } return true; } public static Bitmap RGB32_to_Image( byte[] byteBuff, int nWidth, int nHeight ) { if ( byteBuff.Length <= 0 || byteBuff.Length < nWidth*nHeight ) return null; Bitmap bmp = new Bitmap( nWidth, nHeight, PixelFormat.Format32bppArgb ); //锁定内存数据 BitmapData bmpData = bmp.LockBits( new Rectangle( 0, 0, nWidth, nHeight ), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb ); //输入颜色数据 System.Runtime.InteropServices.Marshal.Copy( byteBuff, 0, bmpData.Scan0, byteBuff.Length ); //解锁 bmp.UnlockBits( bmpData ); return bmp; } }
以上是"C#中如何使用SDK解码回调函数DecCallbackFUN()"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!
数据
函数
设备
量值
代码
C#
内容
模式
篇文章
登录
原始
个数
价值
兴趣
内存
变量
口号
句柄
地址
域名
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
计算机网络技术应用的影响
hp服务器bmc
三级网络技术高教PDF
苹果怎样登陆安卓数据库
中国联通智网工程师考试网络安全
网络安全四个补充
易语言用数据库保存信息吗
原著阅读软件开发
互联网和软件开发的区别
网络安全相关证书有哪些
网络技术密钥名词解释
浙江分布式服务器方案虚拟主机
淄川软件开发咨询
哪位老师有网络安全的答案
浙江筱满互联网科技
以下不属于软件开发模型的是
主题数据库ipv6
网络安全形势的危时代
自然资源统一确权数据库标准
hp 服务器默认密码
现在店面要装网络安全
黄姓霸气的男孩取名数据库连
数据库最近五年的新技术
奋达科技软件开发
服务器与数据库关系图
最专业的网络安全培训
高密度无线网络技术是5G
网络安全微信推文
互联网科技中国领先全世界
国产服务器操作系统最好用