首页 > 学院 > 开发设计 > 正文

对最近的RTP和H264学习进行总结整理-04.20

2019-11-17 02:26:08
字体:
来源:转载
供稿:网友

对最近的RTP和H264学习进行总结整理-04.20

  虽然还是没有搞出来,但总感觉快了哈哈(哪来的自信)

  1、RTP协议接受数据

#region 1-RTP协议变量声明        RTPsession session;        RTPReceiver receiver;        RTPParticipant participant;        private Dictionary<uint, List<RTPPacket>> Clients;#endregion  #region 对RTP进行初始化,并接收数据,调用之后就可以接收数据了            session = new RTPSession();            receiver = new RTPReceiver();            IPEndPoint rtpEp = new IPEndPoint(IPAddress.Parse("192.168.1.109"), 5000);            participant = new RTPParticipant(rtpEp);            receiver.AddParticipant(participant);            session.NewRTPPacket = new RTPSession.NewRTPPacket_Callback(NewRTPPacket);            session.AddReceiver(receiver);            Clients = new Dictionary<uint, List<RTPPacket>>();#endregion

  其中NewRTPPackt是

public delegate bool NewRTPPacket_Callback(    RTPPacket packet)

类型的委托。packet为接收到的RTP包,我们就对这些包进行处理得到想要的帧,然后再把帧进行解码,得到想要的图像(我是这样理解的)

  2、H.264进行解码

  我从网络上搜索到了一个海思的DLL,可以对H.264进行解码

  

#region 解码器相关变量声明        /// <summary>        /// 数据的句柄        /// </summary>        IntPtr pData;        /// <summary>        /// 这是解码器属性信息        /// </summary>        public H264Dec.hiH264_DEC_ATTR_S decAttr;        /// <summary>        /// 这是解码器输出图像信息        /// </summary>        public H264Dec.hiH264_DEC_FRAME_S _decodeFrame = new H264Dec.hiH264_DEC_FRAME_S();        /// <summary>        /// 解码器句柄        /// </summary>        public IntPtr _decHandle; #endregion #region 解码器相关初始化,一般在窗口load中进行初始化            decAttr = new H264Dec.hiH264_DEC_ATTR_S();            decAttr.uPictureFormat = 0;            decAttr.uStreamInType = 0;            decAttr.uPicWidthInMB = 480 >> 4;            decAttr.uPicHeightInMB = 640 >> 4;            decAttr.uBufNum = 8;            decAttr.uWorkMode = 16;            //创建、初始化解码器句柄            _decHandle = H264Dec.Hi264DecCreate(ref decAttr);            //_decodeFrame = new H264Dec.hiH264_DEC_FRAME_S();#endregion//这一写代码就是h264解码的代码,其中未声明的函数和变量会在下面进行声明给出,主要是讲YUV转为RGB,在保存为Bitmap文件if (H264Dec.Hi264DecAU(_decHandle, pData, (uint)newData.Length, 0, ref _decodeFrame, 0) == 0)                {                    if (_decodeFrame.bError == 0)                    {                        //策画 y u v 的长度                        var yLength = _decodeFrame.uHeight * _decodeFrame.uYStride;                        var uLength = _decodeFrame.uHeight * _decodeFrame.uUVStride / 2;                        var vLength = uLength;                        var yBytes = new byte[yLength];                        var uBytes = new byte[uLength];                        var vBytes = new byte[vLength];                        var decodedBytes = new byte[yLength + uLength + vLength];                        //_decodeFrame 是解码后的数据对象,里面包含 YUV 数据、宽度、高度等信息                        Marshal.Copy(_decodeFrame.pY, yBytes, 0, (int)yLength);                        Marshal.Copy(_decodeFrame.pU, uBytes, 0, (int)uLength);                        Marshal.Copy(_decodeFrame.pV, vBytes, 0, (int)vLength);                        //将从 _decodeFrame 中取出的 YUV 数据放入 decodedBytes 中                        Array.Copy(yBytes, decodedBytes, yLength);                        Array.Copy(uBytes, 0, decodedBytes, yLength, uLength);                        Array.Copy(vBytes, 0, decodedBytes, yLength + uLength, vLength);                        ConvertYUV2RGB(yuv, rgb, width, height);                        ConvertYUV2RGB(decodedBytes, rgb, width, height);                        // 写 BMP 文件。                        WriteBMP(rgb, width, height, string.Format("E://test//yuv2bmp_{0}.bmp", index++));                    }                }

  其中pData为需要的一帧数据,因为pData为Intptr类型,而一帧数据是byte[]类型,所以我从网上查了查怎么转换,下面是代码,newData是byte【】,pData是intptr类型。

 GCHandle hObject = GCHandle.Alloc(newData, GCHandleType.Pinned); pData = hObject.AddrOfPinnedObject();

  H264解码类

public class H264Dec    {        public const int HI_SUCCESS = 0;        public const int HI_FAILURE = -1;        public const int HI_LITTLE_ENDIAN = 1234;        public const int HI_BIG_ENDIAN = 4321;        public const int HI_DECODER_SLEEP_TIME = 60000;        public const int HI_H264DEC_OK = 0;        public const int HI_H264DEC_NEED_MORE_BITS = -1;        public const int HI_H264DEC_NO_PICTURE = -2;        public const int HI_H264DEC_ERR_HANDLE = -3;        [DllImport("hi_h264dec_w.dll", EntryPoint = "Hi264DecImageEnhance", CallingConvention = CallingConvention.Cdecl)]        public static extern int Hi264DecImageEnhance(IntPtr hDec, ref hiH264_DEC_FRAME_S pDecFrame, uint uEnhanceCoeff);        [DllImport("hi_h264dec_w.dll", EntryPoint = "Hi264DecCreate", CallingConvention = CallingConvention.Cdecl)]        public static extern IntPtr Hi264DecCreate(ref hiH264_DEC_ATTR_S pDecAttr);        [DllImport("hi_h264dec_w.dll", EntryPoint = "Hi264DecDestroy", CallingConvention = CallingConvention.Cdecl)]        public static extern void Hi264DecDestroy(IntPtr hDec);        [DllImport("hi_h264dec_w.dll", EntryPoint = "Hi264DecGetInfo", CallingConvention = CallingConvention.Cdecl)]        public static extern int Hi264DecGetInfo(ref hiH264_LIBINFO_S pLibInfo);        /// <summary>        /// 对输入的一段码流进行解码并按帧输出图像        /// </summary>        /// <param name="hDec">解码器句柄</param>        /// <param name="pStream">码流起始地址</param>        /// <param name="iStreamLen">码流长度</param>        /// <param name="ullPTS">时间戳信息</param>        /// <param name="pDecFrame">图像信息</param>        /// <param name="uFlags">解码模式 0:正常解码;1、解码完毕并要求解码器输出残留图像</param>        /// <returns></returns>        [DllImport("hi_h264dec_w.dll", EntryPoint = "Hi264DecFrame", CallingConvention = CallingConvention.Cdecl)]        public static extern int Hi264DecFrame(IntPtr hDec, IntPtr pStream, uint iStreamLen, ulong ullPTS, ref hiH264_DEC_FRAME_S pDecFrame, uint uFlags);        [DllImport("hi_h264dec_w.dll", EntryPoint = "Hi264DecAU", CallingConvention = CallingConvention.Cdecl)]        public static extern int Hi264DecAU(IntPtr hDec, IntPtr pStream, uint iStreamLen, ulong ullPTS, ref hiH264_DEC_FRAME_S pDecFrame, uint uFlags);        /// <summary>        /// 解码器属性信息。        /// </summary>        [StructLayout(LayoutKind.Sequential)]        public struct hiH264_DEC_ATTR_S        {            /// <summary>            /// 解码器输出图像格式,目前解码库只支持YUV420图像格式            /// </summary>            public uint uPictureFormat;            /// <summary>            /// 输入码流格式 0x00: 目前解码库只支持以“00 00 01”为nalu分割符的流式H.264码流             /// </summary>            public uint uStreamInType;            /// <summary>            /// 图像宽度            /// </summary>            public uint uPicWidthInMB;            /// <summary>            /// 图像高度            /// </summary>            public uint uPicHeightInMB;            /// <summary>            /// 参考帧数目            /// </summary>            public uint uBufNum;            /// <summary>            /// 解码器工作模式            /// </summary>            public uint uWorkMode;            /// <summary>            /// 用户私有数据            /// </summary>            public IntPtr pUserData;            /// <summary>            /// 保留字            /// </summary>            public uint uReserved;        }        /// <summary>        /// 解码器输出图像信息数据结构        /// </summary>        [StructLayout(LayoutKind.Sequential)]        public struct hiH264_DEC_FRAME_S        {            /// <summary>            /// Y分量地址            /// <
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表