EasyDarwin

面向企业级的流媒体平台框架

EasyDarwin开始于2013年,遵循 Apple开源License APSL,为了敏捷流媒体服务器开发和简化企业流媒体应用开发而诞生的。

详细 >>

EasyPusher RTSP直播之RTP数据包格式解析


h264的功能分为两层,视频编码层(VCL)和网络提取层(NAL)。H.264 的编码视频序列包括一系列的NAL 单元,每个NAL 单元包含一个RBSP。...
RTP包头格式

1、码流总体结构

h264的功能分为两层,视频编码层(VCL)和网络提取层(NAL)。H.264 的编码视频序列包括一系列的NAL 单元,每个NAL 单元包含一个RBSP。一个原始的H.264 NALU 单元常由 [StartCode] [NALU Header] [NALU Payload] 三部分组成,其中 Start Code 用于标示这是一个NALU 单元的开始,必须是”00 00 00 01” 或”00 00 01”。

其中RBPS有分为几种类型:

NAL的解码单元的流程如下:

1、NAL Header

占一个字节,由三部分组成forbidden_bit(1bit),nal_reference_bit(2bits)(优先级),nal_unit_type(5bits)(类型)。

forbidden_bit:禁止位。

nal_reference_bit:当前NAL的优先级,值越大,该NAL越重要。

nal_unit_type :NAL类型。参见下表

RTP头没有CSRC为12字节。

EasyPusher分包方式

FUA占2字节 FU Indicator和FU header

FU indicator有以下格式:

+—————+ 
|0|1|2|3|4|5|6|7| 
+-+-+-+-+-+-+-+-+ 
|F|NRI| Type | 
+—————+ 
FU indicator有以下格式: 
+—————+ 
|0|1|2|3|4|5|6|7| 
+-+-+-+-+-+-+-+-+ 
|F|NRI| Type | 
+—————+
问题点

直播时,如果用户加入会话组的时候上行推送用户推送的不是I帧,则用户需要等待一段时间才能看到画面。等待的时间会随着GOP的增大而随机性的增大,因为用户加入的时间点不同。

案例介绍:映客直播,刚进入房间就能很快看到画面,几乎是1s内,可以明显看到,来了画面之后,有一段类似快进的现象,这是怎么回事呢?因为后台缓存了大半个gop然后一次推送下来了,很多张画面在短时间内播放出来,就是快进的效果。

注意点:注意带宽容量,下行用户频繁的加入和退出会话组将会带来巨大的带宽压力,请综合估量,可以考虑加入配置,标注有多少用户能享受这等福利,当超过人数的时候只能不给予享受这个福利了。
附上解析代码(仅供参考)
typedef struct FU_Indicator_tag
{
    unsigned char F:1;
    unsigned char nRI:2;
    unsigned char type:5;//
    void DUMP()
   {
        printf("F[%d]\n",F);
        printf("nRI[%d]\n",nRI);
        printf("type[%d]\n",type);
    }   
}FUA_Indicator;

typedef struct FU_Head_tag
{
    unsigned char nalu_type:5;/ ttle 5 bit
    unsigned char r:1; 
    unsigned char e:1;    
    unsigned char s:1;//high bit    
     void DUMP()
    {
        printf("nalu_type[%d]\n",nalu_type);
        printf("r[%d]\n",r);
        printf("s[%d]\n",s);
        printf("e[%d]\n",e);
    }     
}FU_Head;

typedef struct RTPHead_Byte0_tag
{
    unsigned char csrcCount:4;
    unsigned char externed:1;
    unsigned char reserved:1;
    unsigned char rtpVersion:2;
    void DUMP()
    {       
        printf("rtpVersion[%d]\n",rtpVersion);
        printf("reserved[%d]\n",reserved);
        printf("externed[%d]\n",externed);
        printf("csrcCount[%d]\n",csrcCount);
    }
}RTPHead_Byte0;

typedef struct RTPHead_Byte1_tag
{
    unsigned char mark:1;
    unsigned char ptype:7;

    void DUMP()
    {   
        printf("ptype[%d]\n",ptype);
        printf("mark[%d]\n",mark);
    }
}RTPHead_Byte1;

typedef struct RTPHead_Byte34_tag
{
    unsigned short sequence;
    void DUMP()
    {
        printf("sequence[%d]\n",ntohs(sequence));
    }
}RTPHead_Byte34;


------------------------------ 分割线 ------------------------------
本站文章除注明转载外,均为本站原创或编辑,欢迎大家转载,但请务必注明出处,尊重他人成果,谢谢。
转载请注明:EasyDarwin;非本站文章均来自互联网,转载目的在于传递更多信息,并不代表本站赞同其观点和对其真实性负责。
文章中如果有错误可联系:johnson@easydarwin.org
推荐文章
安防和移动互联网行业比较火热的移动端手机......>
有人问到像美拍、秒拍这些短视频拍摄是怎么......>
最近更新
Easydarwin中大量使用gettimeofday来获取系......>
最近很多EasyDarwin爱好者提出了手机移动端......>
第一个到达的音频RTP包就将作为音频的关键帧......>
打开手机直播立即就能显示出主播视频,其实就......>
h264的功能分为两层,视频编码层(VCL)和网......>
友情链接 | 申请链接
EasyDarwin官方微信!