原文地址:https://www.cnblogs.com/cangyue080180/p/5873351.html

要播放H264裸码流,可以分拆为以下三个工作:

1.解码H264裸码流获取YUV数据

2.将YUV数据转换为RGB数据填充图片

3.将获取的图片进行显示

要完成工作1,我们可以直接使用海思的解码库,由于海思的解码库是C++的动态库,要完成在C#中进行调用可以参考海思h264解码库这篇文章,介绍的很详细。但是对于该博文只介绍了一种帧解码的方法,并没有介绍真正实用的流式解码方法。自己根据解码库的参考文档写了一份C#版的流式解码算法。

             //初始化// 这是解码器输出图像信息hiH264_DEC_FRAME_S _decodeFrame = new hiH264_DEC_FRAME_S(); // 这是解码器属性信息 hiH264_DEC_ATTR_S decAttr = new hiH264_DEC_ATTR_S(); decAttr.uPictureFormat = 0; decAttr.uStreamInType = 0; /* 解码器最大图像宽高, D1图像(1280x720) */ decAttr.uPicWidthInMB = (uint)width / 16; decAttr.uPicHeightInMB = (uint)height / 16; /* 解码器最大参考帧数: 16 */ decAttr.uBufNum = 16; /* bit0 = 1: 标准输出模式; bit0 = 0: 快速输出模式 */ /* bit4 = 1: 启动内部Deinterlace; bit4 = 0: 不启动内部Deinterlace */ decAttr.uWorkMode = 0x10; //创建、初始化解码器句柄 IntPtr _decHandle = H264Dec.Hi264DecCreate(ref decAttr); //解码结束 bool isEnd = false; int bufferLen = 0x8000; //码流段 byte[] buf = new byte[bufferLen]; while (!isEnd) { //获取一段码流,积累一定缓存量再解 if (streamBuf.Count >= bufferLen || isStop == 1) { byte tempByte; int j = 0; for (int i = 0; i < bufferLen; i++) { if (streamBuf.TryDequeue(out tempByte)) buf[j++] = tempByte; else { break; } } IntPtr pData = Marshal.AllocHGlobal(j); Marshal.Copy(buf, 0, pData, j); int result = 0; result = H264Dec.Hi264DecFrame(_decHandle, pData, (UInt32)j, 0, ref _decodeFrame, (uint)isStop); while (HI_H264DEC_NEED_MORE_BITS != result) { if (HI_H264DEC_NO_PICTURE == result) { isEnd = true; break; } if (HI_H264DEC_OK == result)/* 输出一帧图像 */ { //获取yuv UInt32 tempWid = _decodeFrame.uWidth; UInt32 tempHeig = _decodeFrame.uHeight; UInt32 yStride = _decodeFrame.uYStride; UInt32 uvStride = _decodeFrame.uUVStride; byte[] y = new byte[tempHeig * yStride]; byte[] u = new byte[tempHeig * uvStride / 2]; byte[] v = new byte[tempHeig * uvStride / 2]; Marshal.Copy(_decodeFrame.pY, y, 0, y.Length); Marshal.Copy(_decodeFrame.pU, u, 0, u.Length); Marshal.Copy(_decodeFrame.pV, v, 0, v.Length); //转为yv12格式 //byte[] yuvBytes = new byte[y.Length + u.Length + v.Length]; //Array.Copy(y, 0, yuvBytes, 0, y.Length); //Array.Copy(v, 0, yuvBytes, y.Length , v.Length); //Array.Copy(u, 0, yuvBytes, y.Length + v.Length, u.Length); //更新显示 this.d3dSource.Render(_decodeFrame.pY, _decodeFrame.pU, _decodeFrame.pV); } /* 继续解码剩余H.264码流 */ result = H264Dec.Hi264DecFrame(_decHandle, IntPtr.Zero, 0, 0, ref _decodeFrame, (uint)isStop); } } System.Threading.Thread.Sleep(5); } /* 销毁解码器 */ H264Dec.Hi264DecDestroy(_decHandle); 

要完成工作2,有多种方式,一是自己实现转换,二是使用ffmpeg的库进行yuv和rgb的转换,三是使用D3D进行转换,效率最高的是第三种方式,因为它是利用显卡来进行转换的,更详细的内容可以参考WPF下YUV播放的D3D解决方案 。

要完成工作3就非常简单了,弄个ImageView进行显示就好了。

转载于:https://www.cnblogs.com/boonya/p/8249773.html

【转】C#播放H264裸码流相关推荐

  1. 【开源工程】之裸码流提取工具--H264/H265

    序  工程中常常需要分析一些码流,但码流文件过大的话,不利于分析具体的帧数据,由此编写了码流提取软件.  此工具是在业余时间完成,很多功能尚待完善,如果茫茫中,你发现了此工具,也感兴趣研究,希望你将工 ...

  2. 将h.264裸码流推送到RTMP服务器

    h.264裸码流的格式,参考"H.264-AVC-ISO_IEC_14496-10.pdf, page 211.",这个文档的下载地址:https://github.com/win ...

  3. PX2板实现H.264裸码流的解码

    2019独角兽企业重金招聘Python工程师标准>>> 之前已经有人尝试使用了PX2板实现H.264裸码流的解码,并且给了例程,不过楼主尝试时碰到了一点小问题,现在也是解决了,现在楼 ...

  4. H264/H265码流类型

    文章目录 H.264码流 H.264码流格式 Annex B AVCC H.265码流 H.264码流 H264中,NALU类型1-5为视频帧,其余则为非视频帧.在解码过程中,我们只需要取出NALU头 ...

  5. QT5.6 MSVC编译器 实现-海康摄像头,获取H.264裸码流并通过libmp4V2实现MP4写封装生成MP4视频文件

    前言 当前,在国内安防领域,海康摄像头一直是受各个解决方案比较青睐的摄像头选择.本项目主要应用海康摄像头对桥梁道路车辆运行情况进行监控.当桥梁称重系统检测到车辆异常信号后,触发摄像服务程序,采集摄像头 ...

  6. Ubuntu 下ffmpeg安装说明、doc/examples编译运行、264裸码流解码

    1. 安装X264 git clone https://code.videolan.org/videolan/x264.git cd x264 ./configure --enable-shared ...

  7. Python解码H.264(二)——将海思处理器编码的H.264裸码流转换为jpg序列

    上一篇我们历尽千辛万苦完成了PyAV的安装,这一篇我们来小试牛刀. 思路:通过PyAV来把海思Hi3516编码处理器编码的h.264裸码流中的每一帧都转换为一张jpeg编码的图片,然后将这些jpg图像 ...

  8. python小工具------将H264/H265码流文件转为一帧一帧的JPEG文件

    一.功能 输入H264/H265码流路径,此脚本可以将对应的码流转为一帧一帧的JPEG文件,并保存到指定路径. 二.具体实现 import av import sysdef h265ToJpg_dem ...

  9. 【FFmpeg学习】H264 视频码流分析

    1. H264编码分层 NAL层:(Network Abstraction Layer,视频数据网络抽象层): 它的作用是H264只要在网络上传输,在传输的过程每个包以太网是1500字节,而H264的 ...

最新文章

  1. WPF实用指南二:移除窗体的图标
  2. java实现MD5加密
  3. Web安全之文件包含漏洞
  4. (转)js实现继承的5种方式
  5. springmvc @PathVariable注解进行传参操作
  6. 数值比较器实现_电动开窗器、手动开窗器使用介绍
  7. UWP使用AppService向另一个UWP客户端应用程序提供服务
  8. java linux 调用32位so_Linux上TCP的几个内核参数调优
  9. 区块链查比特币_登图区块链课堂——比特币矿机发展史
  10. @开发者 争抢技术红利,百度自研 4 款人脸硬件要和大家见面了!
  11. c++项目 生成dll文件
  12. C语言equivalent用法,C语言相当于'setw'函数
  13. SRE工作手册——基础
  14. 今天不谈技术,分享一个引起业内轩然大波的月饼事件。
  15. 尚硅谷前端框架vue语法(二)
  16. android 强制退出当前应用程序,android 强制退出应用
  17. 适合苹果的降噪耳机有哪些?最适合苹果的降噪蓝牙耳机推荐
  18. 计算机是如何工作的 计算机原理
  19. Nginx:rewrite指令(break,last,redirect,permanent)
  20. c语言表达式用法,C语言 运算符、表达式和条件结构 用法总结

热门文章

  1. 众里寻他千百度-- 轻量级持久化框架
  2. 工作那些事(十六)面试时,面试官喜欢的非技术问题汇总
  3. 正则表达式中grep,sed的用法(包括基本的正则表达式和扩展的正则表达式)
  4. 【android】两个按钮的宽度各占屏幕的一半
  5. JS 监控页面刷新,关闭 事件的方法(转载)
  6. 如何添加显示桌面图标置于快速启动栏
  7. 超过efficientnet
  8. 根据excel中的容填写信息
  9. 总量迈过90万亿元关口 中国经济交出稳健答卷
  10. 在一个gradle 的maven property 里添加多个URL