裸码流帧信息,跟IVS侧数据结构IVS_RAW_FRAME_INFO保持一致
コード例 #1
0
ファイル: IvsVideoMonitor.cs プロジェクト: eSDK/esdk_Cgw
        /// <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());
            }
        }