今天看了不少,却感觉收获寥寥。

  1、H264相关知识

  因为RTP协议发过来的数据已经经过了H264编码,所以这边需要解码。补充一下H264的相关知识。

  与以往的视频压缩标准相比,H.264 视频压缩标准(简称H.264)具有更出色的性能,因此H.264 被称为新一代视频压缩标准。H.264 与H.263 或MPEG-4 相比,            主要新增特性如下:
      1、采用更为精细和丰富的帧内编码及帧间预测方式,有效地减少残差数据。
      2、引入新的算术编码方式,使得数据压缩比更高。
      3、 视频数据分层更为合理,引入 NAL 更利于网络传输。
  4、取消传统的帧结构,引入 slice 结构和参数集,提高码流的抗误码能力。
  5、引入灵活的参考帧管理机制,参考帧数目最多可以达到 16 个。

  上述特性使得H.264 在视频信噪比、图像质量以及应用的灵活性上有了质的飞跃,但带来的问题是H.264 在实现上复杂度较高。

  2、一些可能的解决方案(并未实践)

  Intel media SDK,windows media sdk,http://www.ffmpeg-csharp.com/(这个网站上说是最简单的方式使用ffmpeg,我也没有学会怎么使用,等以后再回来学习吧),C#调用ffmpeg开发库。以上这些方式只是搜索到的可能的解决方法,因为太懒了,着急做出东西,所以没有去学习,后来在海康的播放库API中看到H264的相关知识(http://www.cnblogs.com/over140/archive/2009/03/22/1418946.html),以前做海康摄像头调用的时候就经常看他的博客。最后在晚上的时候找到一种解决方式。使用海思提供的H264解码库,有专门的解码库,但也是用C++写的。不过这没有问题,想起以前海康摄像头的时候也是C++的代码,通过C#来调用。方法是通过PInvoke.net转一下就可以了。

  转换之后的代码,将hi_h264dec_w.dll转换为C#中的类(也是参考网上的代码)

class Hi264Dec
{
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); [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); [StructLayout(LayoutKind.Sequential)] public struct hiH264_DEC_ATTR_S { public uint uPictureFormat; public uint uStreamInType; public uint uPicWidthInMB; public uint uPicHeightInMB; public uint uBufNum; public uint uWorkMode; public IntPtr pUserData; public uint uReserved; } [StructLayout(LayoutKind.Sequential)] public struct hiH264_DEC_FRAME_S { public IntPtr pY; public IntPtr pU; public IntPtr pV; public uint uWidth; public uint uHeight; public uint uYStride; public uint uUVStride; public uint uCroppingLeftOffset; public uint uCroppingRightOffset; public uint uCroppingTopOffset; public uint uCroppingBottomOffset; public uint uDpbIdx; public uint uPicFlag; public uint bError; public uint bIntra; public ulong ullPTS; public uint uPictureID; public uint uReserved; public IntPtr pUserData; } [StructLayout(LayoutKind.Sequential)] public struct hiH264_LIBINFO_S { public uint uMajor; public uint uMinor; public uint uRelease; public uint uBuild; [MarshalAs(UnmanagedType.LPStr)] public string sVersion; [MarshalAs(UnmanagedType.LPStr)] public string sCopyRight; public uint uFunctionSet; public uint uPictureFormat; public uint uStreamInType; public uint uPicWidth; public uint uPicHeight; public uint uBufNum; public uint uReserved; } [StructLayout(LayoutKind.Sequential)] public struct hiH264_USERDATA_S { public uint uUserDataType; public uint uUserDataSize; public IntPtr pData; public IntPtr pNext; }
}

     可以在窗体加载的时候加载如下代码

//初始化,可以在 FormLoad 事务里完成

             var decAttr = new Hi264Dec.hiH264_DEC_ATTR_S();

             decAttr.uPictureFormat = 0;

             decAttr.uStreamInType = 0;

             decAttr.uPicWidthInMB = 480 >> 4;

             decAttr.uPicHeightInMB = 640 >> 4;

             decAttr.uBufNum = 8;

             decAttr.uWorkMode = 16;

             IntPtr _decHandle = Hi264Dec.Hi264DecCreate(ref decAttr);

             Hi264Dec.hiH264_DEC_FRAME_S _decodeFrame = new Hi264Dec.hiH264_DEC_FRAME_S();

             //解码

             //pData 为须要解码的 H264 nalu 数据,length 为该数据的长度

             if (Hi264Dec.Hi264DecAU(_decHandle, pData, (uint) 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);
//decodedBytes 为yuv数据,可以将其转换为 RGB 数据后再转换为 BitMap 然后经由过程 PictureBox 控件即可显示
//这类代码网上斗劲常见,我就不贴了
}

    在关闭的时候销毁解码器句柄

  

Hi264Dec.Hi264DecDestroy(_decHandle);

    在上面也说了,传进来的数据转为YUV数据后,还需要转为RGB,再转为图片在控件中进行显示。粗略从网上看了一下,这类算法还是比较多的,所以明天的目标是将视频显示出来。争取让已有的轮子跑起来。

    3、C++学习

    今天上午还看了一小部分C++,看的比较慢,学习了基本的输入输出语句,只看到第28页。

    4、总结

    今天收毕业论文题目了,我还没怎么开始写呢。等把RTP和H264视频解码这一块解决就开始准备毕业论文了。晚上的时候给周兆熊老师发的邮件已经收到回复。对于我自己目前的问题也总结一下:(1)语言的确没什么再纠结的意思了,对我现在来说没有孰优孰劣,我需要的做的是尽量用熟悉的语言去解决现在存在的问题。(2)未来想找工作的话不单单需要专业方面的知识,也需要软实力,想起前几天犯得小错误,对自己的成长还是有帮助。需要继续看书,读过的书也需要做笔记。(3)关于怎么让自己坚持去学习,前几天的烦躁心里真的因为好好做事情减轻了呢。这几天一直尝试着用番茄工作法让自己安定下来,坚持使用第四天,每天大约5个番茄钟(效率好低啊)。看了高效工作后,里面的对拖延症的分析三个原因真的让我印象深刻:(1)其他人强迫你做的事情违背你的意愿(好像的确如此哈哈);(2)你给自己压力要有完美的表现;(3)害怕犯错误受批评。三个原因真的是非常准确。不愉快也因为忙碌起来而渐渐消失了。

    5、现在所学的很多东西真的是流于表面,即使我把这个视频解码做出来已经能播放了,但我还是觉得自己的提升好少。但我还是要继续这样做,时间紧迫。不知道我写的东西对您有没有帮助,希望各位懂这方面的我们多多交流。对于我的建议给在评论中提出,谢谢您对我的提议。每天记录一点点,就能进步一点点。

H264解码学习-2015.04.16的更多相关文章

  1. RTP、RTCP协议学习-2015.04.15

    最近做视频编解码部分,传输采用RTP协议.对学习做个记录 1.简介 实时传输协议(Real-time Transport Protocol或简写RTP)是一个网络传输协议,它是由IETF的多媒体传输工 ...

  2. 2015.04.16,外语,读书笔记-《Word Power Made Easy》 11 “如何辱骂敌人” SESSION 28

    TEASER PREVIEW (Teaser 片头,预告片,玩笑 Teaser trailer:预告片) 如何称呼这些人: 完全盲目的服从(obedience [әu'bi:diәns] n. 服从, ...

  3. 【FFMPEG】各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    目录(?)[-] 编解码学习笔记二codec类型 编解码学习笔记三Mpeg系列Mpeg 1和Mpeg 2 编解码学习笔记四Mpeg系列Mpeg 4 编解码学习笔记五Mpeg系列AAC音频 编解码学习笔 ...

  4. 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放 license收费等 ...

  5. Ubuntu LTS 系统学习使用体会和实用工具软件汇总 6.04 8.04 10.04 12.04 14.04 16.04

    Ubuntu LTS 系统学习体会和工具软件汇总 6.04 8.04 10.04 12.04 14.04 16.04 ubuntu入门必备pdf:http://download.csdn.net/de ...

  6. 集显也能硬件编码:Intel SDK && 各种音视频编解码学习详解

    http://blog.sina.com.cn/s/blog_4155bb1d0100soq9.html INTEL MEDIA SDK是INTEL推出的基于其内建显示核心的编解码技术,我们在播放高清 ...

  7. 我的Android进阶之旅------>Android中编解码学习笔记

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

  8. 【miscellaneous】各种音视频编解码学习详解

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

  9. Contest2073 - 湖南多校对抗赛(2015.04.06)

    Contest2073 - 湖南多校对抗赛(2015.04.06) Problem A: (More) Multiplication Time Limit: 1 Sec  Memory Limit:  ...

随机推荐

  1. 开启MySQL日志

    找到my.ini(Linux下是my.cnf)文件,在文件里加入下面两行: log="F:/mysqllog/mysql.log" log-bin="F:/mysqllo ...

  2. Delphi QC 记录

    各网友提交的 QC: 官方网址 说明 备注 https://quality.embarcadero.com/browse/RSP-12985 iOS device cannot use indy id ...

  3. mysql命令行基本操作

    开启:打开电脑的“开始”菜单栏,找到“运行”,在运行框中直接输入:net start mysql.再 登录:Mysql  -P 端口号  -h  mysql主机名\ip -u root (用户)  - ...

  4. Gym 101102J---Divisible Numbers(反推技巧题)

    题目链接 http://codeforces.com/gym/101102/problem/J Description standard input/output You are given an a ...

  5. 设置placeholder字体颜色

    /*设置placeholder字体颜色*/::-webkit-input-placeholder{ color: #FFF;}:-ms-input-placeholder{ color: #FFF;} ...

  6. linux 如何改变文件属性与权限

    我们知道档案权限对于一个系统的安全重要性,也知道档案的权限对于使用者与群组的相关性, 那如何修改一个档案的属性与权限呢? 我们这里介绍几个常用于群组.拥有者.各种身份的权限的指令.如下所示: chgr ...

  7. SQL语句操作数据-------开启旅程路线喽!

    岁月,是一首诗,一首蕴含丰富哲理的诗,岁月是一峰骆驼,驮着无数人的梦想. 一.SQL的简介 SQL的全称是“结构化查询语言”(Structure Query Language),SQL语言是针对数据库 ...

  8. js异步编程

    前言 以一个煮饭的例子开始,例如有三件事,A是买菜.B是买肉.C是洗米,最终的结果是为了煮一餐饭.为了最后一餐饭,可以三件事一起做,也可以轮流做,也可能C需要最后做(等A.B做完),这三件事是相关的, ...

  9. kindeditor-在线编辑器

    写在前面的话: 今天是第一次写博客,很值得纪念,希望能够和大神们一起交流技术,一起进步...来自<一只有梦想的前端小白> 最近项目中需要实现图文混排的效果,所以研究了下在线编辑器-- ki ...

  10. 兼容Android的水波纹效果

    Android的水波纹效果只有高版本才有,我们希望自己的应用在低版本用低版本的阴影,高版本用水波纹,这怎么做呢?其实,只要分drawable和drawablev21两个文件夹就好了. 普通情况下的se ...