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

  • 相关阅读:
    音频、摄像机操作
    调用系统相机及摄像机
    图片的放大缩小
    haxm intelx86加速模拟器的安装
    mac eclipse 下安装subclipse
    文件多线程下载实现
    windows与linux之间传输文件
    ZeroMQ接口函数之 :zmq_setsockopt –设置ZMQ socket的属性
    使用C语言在windows下一口气打开一批网页
    Net-SNMP是线程安全的吗
  • 原文地址:https://www.cnblogs.com/babosa/p/9217935.html
Copyright © 2011-2022 走看看