Esempio n. 1
0
        /// <summary>
        /// 发起视频回传成功后,在状态变化事件中处理视频接收、P2Pvideocall_IND_STATUS_ANSWERED时开始接收视频数据
        /// </summary>
        /// <param name="structResStaIndi"></param>
        private void P2pStatusDelegateFun(ref strP2pvideocallStatusIndicator structP2pvideocallStaIndi)
        {
            NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log);
            logEx.Info("Enter: P2pStatusDelegateFun.strP2pvideocallStatusIndicator.Status = {0},Callee = {1}", Enum.GetName(typeof(P2pvideocall_Status_t),
                         structP2pvideocallStaIndi.Status), structP2pvideocallStaIndi.Callee);

            //P2Pvideocall_IND_STATUS_ANSWERED,表示视频回传请求被成功处理处理
            //视频网关需要提取其中的RTP port和对端IP,并负责与摄像头建立RTP连接和读取RTP中的H.264的视频流,然后再调用上层的视频管理系统或视频监控系统中的API
            //视频从摄像头回传,通过视频网关传入到上层的视频管理系统或视频监控系统
            if (structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_ANSWERED)
            {
                //摄像机编码
                int cameraNo = structP2pvideocallStaIndi.Callee;
                //源端发送码流IP;
                string pRemoteSendStreamIp = ip;
                //源端发送视频码流RTP端口号
                uint uiRemoteSendStreamVideoPort = (uint)structP2pvideocallStaIndi.RemoteVideoPort;
                //源端发送音频端口号
                uint uiRemoteSendStreamAudioPort = (uint)structP2pvideocallStaIndi.RemoteAudioPort;

                //本地视频、音频端口
                uint uiLocalAudioPort = (uint)structP2pvideocallStaIndi.CalAudioPort;
                uint uiLocalVideoPort = (uint)structP2pvideocallStaIndi.LocalVideoPort;

                //发起视频回传,建立成功
                logEx.Trace("P2pStatusDelegateFun.Camera = {0},pRemoteSendStreamIp ={1},uiRemoteSendStreamVideoPort = {2},uiRemoteSendStreamAudioPort ={3},uiLocalAudioPort ={4} ,uiLocalVideoPort ={5} P2Pvideocall_IND_STATUS_ANSWERED OK!",
                             cameraNo, pRemoteSendStreamIp, uiRemoteSendStreamVideoPort, uiRemoteSendStreamAudioPort, uiLocalAudioPort, uiLocalVideoPort);

                if (uiRemoteSendStreamVideoPort == 0)
                {
                    logEx.Warn("P2pvideocallStatus uiRemoteSendStreamVideoPort is NULL");
                    return;
                }

                //打开通道,开始接收实况RTP数据流
                UInt32 channel = StartRecvStream(cameraNo.ToString(), pRemoteSendStreamIp, uiRemoteSendStreamVideoPort, uiRemoteSendStreamAudioPort == 0 ?
                                                 uiRemoteSendStreamVideoPort : uiRemoteSendStreamAudioPort, uiLocalVideoPort,
                                                 uiLocalAudioPort == 0 ? uiLocalVideoPort : uiLocalAudioPort);

                //如果为0,表示预览失败
                if (channel == CgwConst.T28181_ERROR_HANDLE)
                {
                    logEx.Error("Start Receive camera video data failed.Camera No:{0}.", cameraNo);
                    return;
                }
                else
                {
                    logEx.Info("Start Receive camera video data success.Camera No:{0}", cameraNo);
                }
                if (this.videoAutOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME))
                {
                    try
                    {
                        if (videoAutoEvents.ContainsKey(cameraNo.ToString()))
                        {
                            videoAutoEvents[cameraNo.ToString()].VideoSuccess = true;
                            videoAutoEvents[cameraNo.ToString()].eLTEVideoEvent.Set();
                            logEx.Trace("P2pStatusDelegateFun AutoResetEvent State Set,StartVideo Success");
                        }
                    }
                    finally
                    {
                        this.videoAutOperateLock.ExitWriteLock();
                    }
                }

                //设置rtp解析回调函数
                rtpAdapter.ESDK_RTP_OpenESChannel(frameDataCallBack, channel);

                if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME))
                {
                    try
                    {
                        this.cameraVideoChannelDic.Add(cameraNo.ToString(), channel);
                        MediaDataSender mediaDataSender = new MediaDataSender(cameraNo.ToString(), this.dataCallBack);
                        this.videoChannelDataSenderDic.Add(channel, mediaDataSender);
                    }
                    finally
                    {
                        this.handelOperateLock.ExitWriteLock();
                    }
                }
            }
            else if (P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_HANGUPED == structP2pvideocallStaIndi.Status
            || P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_RELEASED == structP2pvideocallStaIndi.Status
            || P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_CANCELLED == structP2pvideocallStaIndi.Status)
            {
                //2015/3/6 设置信号量不阻塞
                if (videoAutOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME))
                {
                    try
                    {
                        int cameraNo = structP2pvideocallStaIndi.Callee;
                        if (videoAutoEvents.ContainsKey(cameraNo.ToString()))
                        {
                            videoAutoEvents[cameraNo.ToString()].VideoSuccess = true;
                            videoAutoEvents[cameraNo.ToString()].eLTEVideoEvent.Set();

                            logEx.Trace("P2pStatusDelegateFun AutoResetEvent State Set,StartVideo End");
                        }
                    }
                    finally
                    {
                        this.videoAutOperateLock.ExitWriteLock();
                    }
                }

                //收到呼叫被结束事件、需要停止RTP传输并关闭RTP连接
                StopReceiveVideo(structP2pvideocallStaIndi.Callee.ToString());
            }
            //2015/2/5 设备播放失败的错误码状态
            else if (structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_REMOTE_NOTCONNECTED ||
                     structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_REMOTE_NOTSUPPORTED ||
                     structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_REMOTE_NOANSWER ||
                     structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_REMOTE_NOTFOUND ||
                     structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_RELEASED_BUSY )
            {
                if (this.videoAutOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME))
                {
                    try
                    {
                        //摄像机编码
                        int cameraNo = structP2pvideocallStaIndi.Callee;
                        if (videoAutoEvents.ContainsKey(cameraNo.ToString()))
                        {
                            videoAutoEvents[cameraNo.ToString()].VideoSuccess = false;
                            videoAutoEvents[cameraNo.ToString()].eLTEVideoEvent.Set();

                            logEx.Trace("P2pStatusDelegateFun AutoResetEvent State Set,StartVideo Remote Failed");
                        }
                    }
                    finally
                    {
                        this.videoAutOperateLock.ExitWriteLock();
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// 启动摄像头预览
        /// </summary>
        /// <param name="cameraNo">摄像头编号</param>
        /// <returns></returns>
        public SmcErr StartReceiveVideo(string cameraNo)
        {
            NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log);
            logEx.Trace("Enter: IvsVideoMonitor.StartReceiveVideo({0}).", cameraNo);
            SmcErr err = new CgwError();
            int handle;
            logEx.Trace("Call ivsSdkClient.StartRealPlayCBRaw({0}).", cameraNo);
            int result = this.ivsSdkClient.StartRealPlayCBRaw(cameraNo, out handle);

            //如果不为0,表示预览失败
            if (result != CgwConst.IVS_SDK_SUCCESS_TAG)
            {
                err.SetErrorNo(CgwError.START_RECEIVE_VIDEO_FAILED);
                logEx.Error("Start Receive camera video data failed.Camera No:{0}.Ivs sdk error code:{1}", cameraNo, result);
                return err;
            }
            else
            {
                logEx.Info("Start Receive camera video data success.Camera No:{0},Handle:{1}.", cameraNo, handle);
            }

            //预览成功,需要停止原来的预览,并将预览句柄添加到缓存
            //需要停止的预览句柄
            int needToStopHandel = CgwConst.START_RECEIVE_VIDEO_DATA_FAILED;
            if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME))
            {
                try
                {
                    //如果预览句柄已经存在,删除掉原来的句柄,用新的句柄替换
                    if (this.cameraVideoHandeDic.ContainsKey(cameraNo))
                    {
                        needToStopHandel = this.cameraVideoHandeDic[cameraNo];
                        this.videoHandleCameraDic.Remove(needToStopHandel);
                        this.cameraVideoHandeDic.Remove(cameraNo);
                    }
                    this.cameraVideoHandeDic.Add(cameraNo, handle);
                    MediaDataSender mediaDataSender = new MediaDataSender(cameraNo, this.dataCallBack);
                    this.videoHandleCameraDic.Add(handle, mediaDataSender);
                }
                finally
                {
                    this.handelOperateLock.ExitWriteLock();
                }
            }

            //重新预览后,更新了预览句柄,需要将原来的预览停止,放在handelOperateLock外面,防止长时间占用锁
            if (needToStopHandel != CgwConst.START_RECEIVE_VIDEO_DATA_FAILED)
            {
                result = this.ivsSdkClient.StopRealPlay(needToStopHandel);
                //如果不为0,表示停止原来的预览失败,只记录日志,不返回错误,不设置错误码
                if (result != CgwConst.IVS_SDK_SUCCESS_TAG)
                {
                    logEx.Error("Get a new preview success. But stop old preview failed.CameraNo:{0},Ivs sdk error code:{0}", cameraNo, result);
                    return err;
                }
            }

            return err;
        }
Esempio n. 3
0
        /// <summary>
        /// 启动摄像头预览
        /// </summary>
        /// <param name="cameraNo">摄像头编号</param>
        /// <returns></returns>
        public SmcErr StartReceiveVideo(string cameraNo)
        {
            NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log);
            logEx.Trace("Enter: T28181VideoMonitor.StartReceiveVideo({0}).", cameraNo);
            SmcErr err = new CgwError();

            //打开通道,开始接收实况RTP数据流
            UInt32 channel = sipStack.StartRecvStream(cameraNo, domain, sipPort, localPort);

            //如果为0,表示预览失败
            if (channel == CgwConst.T28181_ERROR_HANDLE)
            {
                err.SetErrorNo(CgwError.START_RECEIVE_VIDEO_FAILED);
                logEx.Error("Start Receive camera video data failed.Camera No:{0}.Handle:{1}.", cameraNo, channel);
                return err;
            }
            else
            {
                logEx.Info("Start Receive camera video data success.Camera No:{0},Handle:{1}.", cameraNo, channel);
            }

            //设置rtp解析回调函数
            rtpAdapter.ESDK_RTP_OpenChannel(frameDataCallBack, channel);

            //预览成功,需要停止原来的预览,并将预览句柄添加到缓存
            //需要停止的预览句柄
            UInt32 needToStopChannel = CgwConst.T28181_ERROR_HANDLE;
            if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME))
            {
                try
                {
                    //如果预览句柄已经存在,删除掉原来的句柄,用新的句柄替换
                    if (this.cameraVideoChannelDic.ContainsKey(cameraNo))
                    {
                        needToStopChannel = this.cameraVideoChannelDic[cameraNo];
                        this.videoChannelDataSenderDic.Remove(needToStopChannel);
                        this.cameraVideoChannelDic.Remove(cameraNo);

                        //用户参数,4字节整数
                        IntPtr pUser = Marshal.AllocHGlobal(4);
                        NetSourcedInterface.IVS_NETSOURCE_SetDataCallBack(needToStopChannel, null, pUser);

                        //释放NETSOURCE通道资源
                        IVS_NETSOURCE_RESULT iNet = NetSourcedInterface.IVS_NETSOURCE_CloseNetStream(needToStopChannel);
                        if (iNet != IVS_NETSOURCE_RESULT.SUCCESS)
                        {
                            logEx.Error("IVS_NETSOURCE_CloseNetStream failed channel={0}", needToStopChannel);
                            err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED);
                        }

                        //关闭rtp回调
                        rtpAdapter.ESDK_RTP_CloseChannel(needToStopChannel);
                    }
                    this.cameraVideoChannelDic.Add(cameraNo, channel);
                    MediaDataSender mediaDataSender = new MediaDataSender(cameraNo, this.dataCallBack);
                    this.videoChannelDataSenderDic.Add(channel, mediaDataSender);
                }
                finally
                {
                    this.handelOperateLock.ExitWriteLock();
                }
            }

            //重新预览后,更新了预览句柄,需要将原来的预览停止,放在handelOperateLock外面,防止长时间占用锁
            if (needToStopChannel != CgwConst.T28181_ERROR_HANDLE)
            {
                EM_SIP_RESULT iRet = sipStack.StopRecvStream(needToStopChannel);
                //如果不为0,表示停止原来的预览失败,只记录日志,不返回错误,不设置错误码
                if (iRet != EM_SIP_RESULT.RET_SUCCESS)
                {
                    err.SetErrorNo(CgwError.START_RECEIVE_VIDEO_FAILED);
                    logEx.Error("Get a new preview success. But stop old preview failed.CameraNo:{0},Ivs sdk error code:{0}", cameraNo, iRet);
                    return err;
                }
            }
            return err;
        }