C#中如何使用SDK解码回调函数DecCallbackFUN()
发表于:2024-09-30 作者:千家信息网编辑
千家信息网最后更新 2024年09月30日,这篇文章主要介绍C#中如何使用SDK解码回调函数DecCallbackFUN(),文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!代码1、摄像头操作代码 struct Cam
千家信息网最后更新 2024年09月30日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安全错误
数据库的锁怎样保障安全
软件开发意向协议书范本
服务器核
京东网络技术总监
芒果数据库排序
网络安全应坚持积极利用
乐牌网络技术产品
es代替数据库搜索
宁波小软件开发
云网站属于大数据库
网络安全路由交换技术
网络安全重点系统保障清单
access数据库官网
计算机网络技术男的多吗
监控服务器有什么系统
最好的网络安全新技能
数据库日志分析
哪项不是利用文献数据库辅助选题能实现的
服务器文件管理有哪些功能
SQL提供了哪些系统数据库
hp服务器指示灯说明
iphone 安卓导数据库
ps5登录法环服务器
网络安全手抄报彩色版
在技校学软件开发容易吗
服务器未能检测安全锁
计算机网络技术男的多吗
美食软件开发背景
服务器主机和普通主机
网络安全知识思维导图
电子网络技术都是学啥