zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    [转]SVN服务器搭建和使用(二)
    [转]SVN服务器搭建和使用(一)
    BZOJ 2049 Sdoi2008 Cave 洞穴勘测
    BZOJ 1589 Usaco2008 Dec Trick or Treat on the Farm 采集糖果
    BZOJ 2796 POI2012 Fibonacci Representation
    BZOJ 2115 Wc2011 Xor
    BZOJ 3105 CQOI2013 新Nim游戏
    BZOJ 2460 Beijing2011 元素
    BZOJ 3687 简单题
    BZOJ 1068 SCOI2008 压缩
  • 原文地址:https://www.cnblogs.com/babosa/p/9217935.html
Copyright © 2011-2022 走看看