• 国标码流总结


    1、NALU结构介绍与I帧判断

    在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。因此我们平时的每帧数据就是一个NAL单元(SPS与PPS除外)。在实际的H264数据帧中,往往帧前面带有00 00 00 01分隔符,一般来说编码器编出的首帧数据为PPS与SPS,接着为I帧……

    H264 NALU固定以 0x00 00 00 01为起始,NALU_data部分不会出现这个起始码;在找到下一个起始码之前,当前NALU数据长度不知;

    H264 NALU: 00 00 00 01(4字节) | NALU type(1字节)| NALU_data (N字节)|0x00 00 00 01 | …
    起始码(4字节) 类型 数据 下一个NALU

    NALU_type 1字节,定义为:

    1比特禁止位 2比特 重要性指示位 5比特 类型
    固定为0 11 1-12 由h264使用
    常用Nalu_type:
    0x67 (0 11 00111) SPS 非常重要 type = 7
    0x68 (0 11 01000) PPS 非常重要 type = 8
    0x65 (0 11 00101) IDR帧 关键帧 非常重要 type = 5
    0x61 (0 11 00001) I帧 重要 type=1 非IDR的I帧 不大常见
    0x41 (0 10 00001) P帧 重要 type = 1
    0x01 (0 00 00001) B帧 不重要 type = 1
    0x06 (0 00 00110) SEI 不重要 type = 6

    所以判断是否为I帧的算法为: (NALU类型 & 0001 1111) = 5 即 NALU类型 & 31 = 5,比如0x65 & 31 = 5

    2、RTP荷载PS流

    首先,我们来看看I帧的PS流格式,这里需要注意的是SPS、PPS之前要加上PES头部。如下图所示,其中绿色部分就是我们拿到的H.264裸流数据,须将它拆分成三段并在前面加上PES头部。

    在这里插入图片描述
    针对H264 做如下PS 封装:每个IDR NALU 前一般都会包含SPS、PPS 等NALU,因此将SPS、PPS、IDR 的NALU 封装为一个PS 包,包括ps 头,然后加上PS system header,PS system map,PES header+h264 raw data。所以一个IDR NALU PS 包由外到内顺序是:PSheader| PS system header | PS system Map | PES header | h264 raw data。对于其它非关键帧的PS 包,就简单多了,直接加上PS头和PES 头就可以了。顺序为:PS header | PES header | h264raw data。以上是对只有视频video 的情况,如果要把音频Audio也打包进PS 封装,也可以。当有音频数据时,将数据加上PES header 放到视频PES 后就可以了。顺序如下:PS 包=PS头|PES(video)|PES(audio),再用RTP 封装发送就可以了。

    3、RTP荷载H264码流

    一般情况下IDR帧很大,超过了RTP的负载长度限制(1400字节),所以上面这一个I帧要拆分成若干包RTP分多次发送。第一包的结构如上图所示,第二包以后RTP的结构就简单多了,它是这样的:
    在这里插入图片描述

    上面提到的是I帧的情况,相比它,P/B帧的帧格式真是太简单了,因为它既没有SYS、PSM,也没有SPS、PPS:
    在这里插入图片描述

    P/B帧大小一般不超过1400字节,如果超过1400字节,也需分成多包RTP数据进行传输,超出1400部分的第二包RTP结构:
    在这里插入图片描述

    4、RTMP包头

    RTMP协议封包 由一个包头和一个包体组成,包头可以是4种长度的任意一种:12, 8, 4, 1 byte(s).完整的RTMP包头应该是12bytes,包含了时间戳,Head_Type,AMFSize,AMFType,StreamID信息, 8字节的包头只纪录了时间戳,Head_Type,AMFSize,AMFType, 4个字节的包头记录了时间戳,Head_Type。1个字节的包头只记录了Head_Type 。包体最大长度默认为128字节,通过chunkSize可改变包体最大长度,通常当一段AFM数据超过128字节后,超过128的部分就放到了其他的RTMP封包中,包头为一个字节.
    完整的RTMP包头有12字节,由下面5个部分组成:
    1、Head_Type - 包头类型、TiMMER - 时间戳、AMFSize - 数据大小、AMFType - 数据类型、StreamID - 流ID
    2、封包分析
    例如有一个RTMP封包的数据0300 00 00 00 01 02 1400 00 00 00 0200 07 63 6F 6E 6E 65 63 74 003F F0 00 00 00 00 00 00 08 ,,,
    数据依次解析的含义
    03表示12字节头,channelid=3
    000000表示时间戳 Timer=0
    000102表示AMFSize=18
    14表示AMFType=Invoke 方法调用
    00 00 00 00 表示StreamID = 0
    //到此,12字节RTMP头结束下面的是AMF数据分析,具体的AMF0数据格式请参考 RTMP协议 二、AMF数据
    02表示String
    0007表示String长度7
    63 6F 6E 6E 65 63 74 是String的Ascall值"connect"
    00表示Double
    3F F0 00 00 00 00 00 00 表示double的0.0
    08表示Map数据开始

    5、HLS

    HLS(HTTP Live Streaming)是苹果公司提出的基于HTTP的流媒体网络传输协议。HLS把整个流分成一个个小的基于 HTTP 的文件来下载,每次只下载一些。HLS 协议由三部分组成:HTTP、M3U8、TS。这三部分中,HTTP 是传输协议,M3U8 是索引文件,TS 是音视频的媒体信息。类似于MPEG-DASH,但是HLS更加简洁,它的基本原理也是服务端把文件或媒体流按照不同的码率切分成一个个小片段进行传输,客户端在播放码流时,可以根据自身的带宽及性能限制,在同一视频内容的不同码率的备用源中,选择合适码率的码流进行下载播放。在传输会话开始时,客户端首先需要下载描述不同码流元数据的M3U8索引文件(类似于DASH中的MPD文件)。
    优点:与基于UDP的RTP协议不同,HLS请求仅使用HTTP传输,因此可以穿过任何允许HTTP数据通过的防火墙或代理服务器。这也便于使用传统的HTTP服务器作为源,并广泛使用基于HTTP的内容分发网络来传输媒体流。HLS相对于RTMP来讲使用了标准的 HTTP 协议来传输数据,可以避免在一些特殊的网络环境下被屏蔽。HLS相比RTMP在服务器端做负载均衡要简单得多。因为HLS是基于无状态协议HTTP实现的,客户端只需要按照顺序使用下载存储在服务器的普通ts文件进行播放就可以。而RTMP是一种有状态协议,很难对视频服务器进行平滑扩展,因为需要为每一个播放视频流的客户端维护状态。HLS 协议本身实现了码率自适应,在不同带宽情况下,设备可以自动切换到最适合自己码率的视频播放。
    缺点:虽然HLS有上述优势,但也同时存在延迟过大的劣势。采用HLS直播的视频流延时一般在10秒以上,使用推荐配置时延迟大概在30s,而RTMP直播的延迟最低可达到3、4秒,因此,在对实时性要求较高的场合,如互动直播,就要慎用HLS了。
    HLS的格式可简单归结如下:
    网络协议: HTTP;
    封装格式: MEPG-2 TS;
    编码格式: 视频编码格式为H.264,音频编码格式为MP3、AAC、AC-3或EC-3;
    索引文件: M3U8。每一个.m3u8文件,分别对应若干个ts文件,这些ts文件才是真正存放视频的数据,m3u8文件只是存放了一些ts文件的配置信息和相关路径,当视频播放时,.m3u8是动态改变的,video标签会解析这个文件,并找到对应的ts文件来播放,所以一般为了加快速度,.m3u8 放在web服务器上,ts文件放在cdn 上。.m3u8 文件,其实就是以utf-8编码的m3u文件,这个文件本身不能播放,只是存放了播放信息的文本文件。

  • 相关阅读:
    熬了五年,马同学第一本书出版了!
    springboot源码理解五、SpringApplication初始化
    C++ STL中的Multimap概述
    上海电力大学新增081200计算机科学与技术,一起来看看吧
    【Azure】构建安全架构的 Azure 云:深入了解零信任体系结构
    OSPF的原理与配置
    【智慧零售】门店管理设备解决方案,为企业数字化运营升级赋能
    前端学习笔记(4) Vue3 全局属性 app.config.globalProperties 使用案例
    Ubuntu 14.04:PaddleOCR基于PaddleServing的在线服务化部署(失败)
    bodipy荧光染料BDP 558/568 NHS ester/琥珀酰亚胺活化酯,CAS:150173-73-2
  • 原文地址:https://blog.csdn.net/qq_46615150/article/details/126454189