/// <summary> /// 码流回调函数, /// 1、根据预览句柄handle从videoHandleCameraDic中获取摄像头编号, /// 2、根据摄像头编号,获取mic状态 /// 3、判断码流是否是音频,如果是音频,根据mic状态判断是否需要转发 /// </summary> /// <param name="handle">播放句柄</param> /// <param name="pRawFrameInfo">实况参数</param> /// <param name="pBuf">码流</param> /// <param name="uiBufSize">大小</param> /// <param name="cameraNo">摄像头编号</param> private void IvsRealPlayCallBackRaw(int handle, IvsRawFrameInfo pRawFrameInfo, byte[] pBuf, UInt32 uiBufSize, string pUserData) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); //logEx.Trace("Enter:IvsRealPlayCallBackRaw(),{0}", pUserData); MediaDataSender mediaDataSender = null; try { if (this.handelOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (!this.videoHandleCameraDic.ContainsKey(handle)) { logEx.Error("The video data handle is not found.Handle:{0}", handle); return; } mediaDataSender = this.videoHandleCameraDic[handle]; } finally { this.handelOperateLock.ExitReadLock(); } } if (mediaDataSender == null) { return; } StreamType streamType = StreamType.VIDEO_H264; //判断码流类型,因为码流回调访问频频非常高,不单独抽成一个方法,减少方法访问开销 //对于支持的码流类型,用break退出switch,对于不支持的码流类型直接舍弃,用return返回 switch (pRawFrameInfo.StreamType) { //对于音频只接收G711A和G711U,其他舍弃 case (int)IvsStreamType.PAY_LOAD_TYPE_PCMU: streamType = StreamType.AUDIO_G711U; break; case (int)IvsStreamType.PAY_LOAD_TYPE_PCMA: streamType = StreamType.AUDIO_G711A; break; //只接收H264的视频码流 case (int)IvsStreamType.PAY_LOAD_TYPE_H264: //H264的标准视频流,作为视频流处理 streamType = StreamType.VIDEO_H264; break; default: //不支持的类型,直接舍弃,返回 //logEx.Warn("This stream type is not support. Chuck the data.StreamType:{0};Camera no:{1}", // Enum.GetName(typeof(IvsStreamType), pRawFrameInfo.StreamType), // cameraNo); return; } if (streamType == StreamType.AUDIO_G711A || streamType == StreamType.AUDIO_G711U) { //如果是音频流,需要判断mic的状态,开启时才发送音频流 if (this.micOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraMicStatusDic.ContainsKey(mediaDataSender.CameraNo)) { //如果mic为非开启状态,则不发送音频码流, if (!this.cameraMicStatusDic[mediaDataSender.CameraNo]) { //logEx.Warn("This data is audio,but the mic is off.Chuck the data.Camera no:{0}", mediaDataSender.CameraNo); return; } } else { //默认为关闭状态,因此如果cameraMicStatusDic不包含该摄像头,则认为处于关闭状态,舍弃音频码流 //logEx.Warn("This data is audio,but the mic is off.Chuck the data.Camera no:{0}", mediaDataSender.CameraNo); return; } } finally { this.micOperateLock.ExitReadLock(); } } } MediaData mediaData = new MediaData(); mediaData.Data = pBuf; //IVS 目前为裸码流 mediaData.DataType = MediaDataType.FRAME_DATA; mediaData.StreamType = streamType; mediaData.Size = uiBufSize; //将Ivs帧类型转换成各融合网关统一的帧类型 string name = Enum.GetName(typeof(IvsH264NaluType), pRawFrameInfo.FrameType); //帧类型判断,偶现IVS返回的帧类型,在融合网关中未记录,返回值为null if (string.IsNullOrEmpty(name)) { logEx.Warn("IvsRealPlayCallBackRaw FrameType Is Not Defined ,FrameType:{0}", pRawFrameInfo.FrameType); mediaData.FrameType = FrameDataType.H264_NALU_TYPE_UNDEFINED; } else { if (Enum.IsDefined(typeof(FrameDataType), name)) { FrameDataType frameDataType = (FrameDataType)Enum.Parse(typeof(FrameDataType), name); mediaData.FrameType = frameDataType; } else { mediaData.FrameType = FrameDataType.H264_NALU_TYPE_UNDEFINED; } } //向回调函数转发码流 //this.videoDataCallBack(cameraNo, mediaData, this.sender); //logEx.Debug("FrameDataCallBackFun.mediaData.DataType={0},FrameType = {1},StreamType = {2},Size = {3}", Enum.GetName(typeof(MediaDataType), mediaData.DataType), // Enum.GetName(typeof(FrameDataType), mediaData.FrameType), Enum.GetName(typeof(StreamType), mediaData.StreamType), mediaData.Size); mediaDataSender.SendData(mediaData, this.sender); } catch (Exception e) { logEx.Error("Send the media data failed.Execption message:{0}", e.ToString()); } }
/// <summary> /// rtp码流回调处理 /// </summary> /// <param name="pBuf">帧数据字节数组</param> /// <param name="pFrameData">帧数据类型</param> /// <param name="uiChannel">通道</param> /// <param name="uiBufSize">帧数据字节数组长度</param> private void FrameDataCallBackFun(IntPtr pBuf, uint uiBufSize, ref ST_FRAME_DATA pFrameData, uint uiChannel) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); ST_FRAME_DATA frameData = pFrameData; MediaDataSender mediaDataSender = null; if (this.handelOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.videoChannelDataSenderDic.ContainsKey(uiChannel)) { mediaDataSender = this.videoChannelDataSenderDic[uiChannel]; } } finally { this.handelOperateLock.ExitReadLock(); } } if (mediaDataSender == null) { logEx.Warn("FrameDataCallBackFun mediaDataSender = NULL"); return; } StreamType streamType = StreamType.VIDEO_H264; //对于支持的码流类型,用break退出switch,对于不支持的码流类型直接舍弃,用return返回 switch (frameData.iStreamType) { //对于音频只接收G711A和G711U,其他舍弃 case (int)IvsStreamType.PAY_LOAD_TYPE_PCMU: streamType = StreamType.AUDIO_G711U; break; case (int)IvsStreamType.PAY_LOAD_TYPE_PCMA: streamType = StreamType.AUDIO_G711A; break; //只接收H264的视频码流 case (int)IvsStreamType.PAY_LOAD_TYPE_H264: //H264的标准视频流,作为视频流处理 streamType = StreamType.VIDEO_H264; break; default: //不支持的类型,直接舍弃,返回 return; } if (streamType == StreamType.AUDIO_G711A || streamType == StreamType.AUDIO_G711U) { //如果是音频流,需要判断mic的状态,开启时才发送音频流 if (this.micOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraMicStatusDic.ContainsKey(mediaDataSender.CameraNo)) { //如果mic为非开启状态,则不发送音频码流, if (!this.cameraMicStatusDic[mediaDataSender.CameraNo]) { logEx.Warn("This data is audio,but the mic is off.Chuck the data.Camera no:{0}", mediaDataSender.CameraNo); return; } } else { //默认为关闭状态,因此如果cameraMicStatusDic不包含该摄像头,则认为处于关闭状态,舍弃音频码流 logEx.Warn("This data is audio,but the mic is off.Chuck the data.Camera no:{0}", mediaDataSender.CameraNo); return; } } finally { this.micOperateLock.ExitReadLock(); } } } try { MediaData mediaData = new MediaData(); //获取非托管的数据 byte[] datagram = new byte[uiBufSize]; if (!(streamType == StreamType.AUDIO_G711A || streamType == StreamType.AUDIO_G711U)) { Marshal.Copy(pBuf, datagram, 0, (int)uiBufSize); //视频帧数据头部增加四个四节的开始表实0x000001 byte[] newDatagram = new byte[uiBufSize + 4]; datagram.CopyTo(newDatagram, 4); newDatagram[3] = 1; mediaData.Data = newDatagram; mediaData.Size = (uint)(uiBufSize + 4); } else { mediaData.Data = datagram; mediaData.Size = (uiBufSize); } //裸码流 mediaData.DataType = MediaDataType.FRAME_DATA; mediaData.StreamType = streamType; //将帧类型转换成各融合网关统一的帧类型 string name = Enum.GetName(typeof(IvsH264NaluType), frameData.iFrameDataType); if (Enum.IsDefined(typeof(FrameDataType), name)) { FrameDataType frameDataType = (FrameDataType)Enum.Parse(typeof(FrameDataType), name); mediaData.FrameType = frameDataType; } else { mediaData.FrameType = FrameDataType.H264_NALU_TYPE_UNDEFINED; } //向回调函数转发码流 mediaDataSender.SendData(mediaData, this.sender); } catch (System.Exception ex) { logEx.Error("FrameDataCallBackFun failed.Execption message:{0}", ex.Message); } }