中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#中如何使用SDK解碼回調函數DecCallbackFUN()

發布時間:2021-10-18 11:37:19 來源:億速云 閱讀:221 作者:小新 欄目:編程語言

這篇文章主要介紹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()”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

sdk
AI

招远市| 淮滨县| 富平县| 平安县| 阳新县| 郴州市| 湛江市| 东至县| 文成县| 彭阳县| 清流县| 长泰县| 雷波县| 曲麻莱县| 荆州市| 青河县| 交口县| 邹平县| 孟村| 叶城县| 利辛县| 锡林郭勒盟| 马尔康县| 达日县| 吴堡县| 靖州| 水富县| 桃源县| 保康县| 陵川县| 额敏县| 驻马店市| 开原市| 盘锦市| 喀什市| 西吉县| 东山县| 阿城市| 同德县| 肇东市| 饶平县|