zoukankan      html  css  js  c++  java
  • 从零开始写一个发送h264的rtsp服务器(下)

    转自:http://blog.csdn.net/jychen105/article/details/47012099

    一、H264是如何通过rtsp发送的

    简单来说,H264就是通过打包到rtp协议的数据部分发送出去的。

    H264打包成rtp数据包有三种方式

    • 单一封包模式
    • 组合封包模式
    • 分片模式

      要想弄明白这三种打包方式,必须先弄清楚h264的组成结构,或者叫组成单元。

    二、H264结构单元

    H264数据流最基本的结构单元叫nalu单元。

    H264的nalu单元组成:

    [start code] + [nalu header] + [nalu paload]
    • start code: 可以为 001 或者 0001, 也就是点3个字节或者4个字节

    • nalu header: 占一个字节

    • nalu paload: 长度不定

    每一帧画面拥有一个或多个nalu单元,每个nalu单元以start code进行分离

    nalu header

    nalu header占一个字节,它又分了三个部分:F,NRI,TYPE

    7 6-5 4-0
    F NRI TYPE
    • F:一般为0
    • NRI:指示nalu单元的重要性,不同编码器编出来的H264数据不同
    • TYPE:nalu类型

    TYPE类型:

    类型定义
    0 未定义
    1-23 NAL单元
    24 STAP-A 单一时间组合包
    25 STAP-B 单一时间组合包
    26 MTAP-16 多个时间组合包
    27 MTAP-24 多个时间组合包
    28 FU-A 分片
    29 FU-B 分片
    30-31 未定义

    特别注意的是7这SPS,8为PPS,发送SDP协议包时需进行base64编码 
    25,26,27,29这四种类型基本不会出现

    三、H264的RTP打包

    前面说过有三种打包方式:单一封包模式,组合封包模式,分片模式

    打包原则

    单一封包模式: nalu单元长度小于MTU长度(通常是1500,live555定义的是2400)用此种方式封包 
    组合封包模式: nalu单元实在太小,多个nalu长度和都小于MTU长度 
    分片模式:nalu单元长度大于MTU长度

    以上封包模式是按nalu长度来分的,同时也完全符合nalu单元中TYPE类型来分。 
    TYPE1-23 单一封包,24组合封包, 28分片封包

    打包细则

    单一封包:

    [RTP header] + [nalu header] + [nalu payload]

    组合封包:

    [RTP header]+[STAP-A头(1字节,低5位为24)] +
    [第1个nalu长度(2字节)] + [第1个nalu header] + [第1个nalu payload]+
    [第2个nalu长度(2字节)] + [第2个nalu header] + [第2个nalu payload]+
    [第N个nalu长度(2字节)] + [第N个nalu header] + [第N个nalu payload]

    分片模式封包:

    此时要切分成多个RTP包

    [RTP header]+[FU Indicator(1字节)]+[FU header(1字节)]+[部分nalu payload]

    FU Indicator

    7 6-5 4-0
    F NRI TYPE

    F, NRI为nalu中的F,NRI 
    TYPE:固定为28

    FU header

    7 6 5 4-0
    S E R TYPE

    S:开始标志(start)

    E:结束标志(end)

    R:保留(reserve)

    TYPE: nalu中的TYPE

    标志SER
    分片开始 1 0 0
    分片中间 0 0 0
    分片结束 0 1 0

    RTP包头的填充

    typedef struct 
    {
        /* byte 0 */
        unsigned char csrc_len:4;  /* CC expect 0 */
        unsigned char extension:1; /* X  expect 1, see RTP_OP below */
        unsigned char padding:1;   /* P  expect 0 */
        unsigned char version:2;   /* V  expect 2 */
    
        /* byte 1 */
        unsigned char payload:7;   /* PT  RTP_PAYLOAD_RTSP */
        unsigned char marker:1;    /* M   expect 1 */
    
        /* byte 2,3 */
        unsigned short seq_no;     /*sequence number*/
    
        /* byte 4-7 */
        unsigned  long timestamp;  /*time stamp*/
    
        /* byte 8-11 */
        unsigned long ssrc;        /* stream number is used here. */
    } RTPHeader;/*12 bytes*/

    各项值填充:

    符号位数定义数值
    V 2bit 版本号 2
    P 1bit 填充位 0
    X 1bit 扩展位 0
    CC 4bit CSRC数目 0
    M 1bit 标志位 单一封包为1; 分片封包最后一个包为1,其余为0;
    PT 7bit 载荷类型 96(h264为96)
    SeqNum 16bit 序列号 每发一个包加1
    Timestamp 32bit 时间戳 单一封包 +采样率,h264为3600; 分片封包第一个加采样率,后续不变
    SSRC 32bit 同步源标识 任意指定,标准是一个MD5算法值,未明
    CSRC 0bit 贡献源列表 CC为0,所以此项没有

    组合模式的M跟Timestamp未调查清楚,但是可以讨巧,打包的时候不采用组合模式,采用单一模式。

    版权声明:本文为博主原创文章,转载请注明出处 http://blog.csdn.net/jychen105/article/details/47012099
  • 相关阅读:
    MobileIMSDK连接后频繁掉线重连,提示会话超时失效,对方非正常退出或网络故障
    Android+SpringBoot+Vue+高德地图实现后台查看车辆实时位置功能
    Vue中集成高德地图API实现定位与自定义样式信息窗体
    Java中对接钉钉API获取数据流程
    Java中集成极光推送实现给Android提送消息通知(附代码下载)
    Android中集成极光推送实现推送消息通知与根据别名指定推送附示例代码下载
    PostGresSQL简介与Windows上的安装教程
    信息系统项目管理师-知识产权、项目收尾、标准规范核心知识点思维脑图
    信息系统项目管理师-项目成熟度模型、量化项目管理核心知识点思维脑图
    信息系统项目管理师-招投标法、政府采购法核心知识点思维脑图
  • 原文地址:https://www.cnblogs.com/x_wukong/p/8603491.html
Copyright © 2011-2022 走看看