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

—本篇由团队成员Fantasy供稿!

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]
",F);
        printf("nRI[%d]
",nRI);
        printf("type[%d]
",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]
",nalu_type);
        printf("r[%d]
",r);
        printf("s[%d]
",s);
        printf("e[%d]
",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]
",rtpVersion);
        printf("reserved[%d]
",reserved);
        printf("externed[%d]
",externed);
        printf("csrcCount[%d]
",csrcCount);
    }
}RTPHead_Byte0;

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

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

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

获取更多信息

邮件:support@easydarwin.org

WEB:www.EasyDarwin.org

Copyright © EasyDarwin.org 2012-2016

EasyDarwin

原文地址:https://www.cnblogs.com/babosa/p/9217935.html