zoukankan      html  css  js  c++  java
  • 从RTSP协议传输的H264视频流中取出每一个帧属于I、P、B中的哪一种帧

    本文地址:http://www.cnblogs.com/herbix/p/4270035.html

    RTSP是一个控制协议,其中的数据是用RTP传输的。
    RTP使用了UDP,每个UDP包的内容区(没有UDP头)都包含以下的几个部分:

    RTP_FIXED_HEADER
    0                   1                   2                   3 
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
    |V=2|P|X|  CC   |M|     PT      |       sequence number         | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
    |                           timestamp                           | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
    |           synchronization source (SSRC) identifier            | 
    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 
    |            contributing source (CSRC) identifiers             | 
    |                             ....                              | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    V: 版本
    P: 填充标志,占1位,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。
    X:扩展标志,占1位,如果X=1,则在RTP报头后跟有一个扩展报头。
    CC: CSRC的个数
    M: 对于H264视频帧,表示这是最后一个分片
    PT: 载荷类型,H264是96(0x60)
    SSRC: 会话标识
    CSRC: 忘记了

    紧随其后的是NALU_HEADER

    NALU_HEADER 
    +---------------+ 
    |0|1|2|3|4|5|6|7| 
    +-+-+-+-+-+-+-+-+ 
    |F|NRI|  Type   | 
    +---------------+ 

    F: 始终为0
    NRI: 重要性
    Type: 类型

    Type	Packet		Type name                       
    ----------------------------------------------------
    0		undefined                                 
    1					不分区,非IDR图像的片(I, P, B帧)
    2					片分区A
    3					片分区B
    4					片分区C
    5					IDR图像中的片(I帧)
    6					补充增强信息单元(SEI)
    7					序列参数集(SPS)
    8					图像参数集(PPS)
    9					分界符
    10					序列结束
    11					码流结束
    12					填充
    13-23	reserved
    24		STAP-A		Single-time aggregation packet    
    25		STAP-B		Single-time aggregation packet    
    26		MTAP16		Multi-time aggregation packet     
    27		MTAP24		Multi-time aggregation packet     
    28		FU-A		Fragmentation unit                
    29		FU-B		Fragmentation unit                 
    30-31	undefined                 
    

      

    如果H264的Slice过大,无法装入一个UDP包中,一般来说这里就要分包。分包时,NALU_HEADER中Type字段为FU-A(28),下一字节为FU_HEADER。

    FU_HEADER
    +---------------+
    |0|1|2|3|4|5|6|7|
    +-+-+-+-+-+-+-+-+
    |S|E|R|  Type   |
    +---------------+

    S: 开始的片
    E: 结束的片
    R: 始终为0
    Type: 类型,和NALU_HEADER的类型一致

    后面的部分就是H264的内容了。H264是按照Slice传输的,每个Slice有一个Slice头,据说Slide头使用了指数哥伦布编码(k=0),需要先进行解码。
    指数哥伦布编码(k=0):

    数据	数据+1		写作二进制(n位)	前加n-1个0(编码结果)
    0		1			1					1
    1		2			10					010
    2		3			11					011
    3		4			100					00100
    4		5			101					00101
    5		6			110					00110
    6		7			111					00111
    7		8			1000				0001000
    ...		...			...					...

    解码就反过来,先数0的个数,然后再取相应位数的数据出来。
    011110100001101 -> 011 1 1 010 0001101 -> 11 1 1 10 1101 -> 3 1 1 2 13 -> 2 0 0 1 12

    Slide头的第二个参数为slice_type,也就是解出来的第二个数,表示IPB帧:

    slice_type	Name of slice_type
    0			P (P slice)
    1			B (B slice)
    2			I (I slice)
    3			SP (SP slice)
    4			SI (SI slice)
    5			P (P slice)
    6			B (B slice)
    7			I (I slice)
    8			SP (SP slice)
    9			SI (SI slice)
    

      

    参考:
    [1] http://blog.csdn.net/jefry_xdz/article/details/8461343
    [2] http://www.cnweblog.com/fly2700/archive/2012/02/23/319718.html
    [3] http://blog.csdn.net/wangjiannuaa/article/details/6966505
    [4] http://blog.sina.com.cn/s/blog_4171e65d0100o4pt.html
    [5] http://baike.baidu.com/view/1268656.htm?fromtitle=RTP&fromid=8974125&type=syn

  • 相关阅读:
    JDK源码之Thread 类分析
    java中符号类型和无符号类型的问题分析
    国内高速Maven仓库
    Idea Live Templates代码模板
    正则表达式
    java内存泄漏
    MySQL查看 InnoDB表中每个索引的高度
    ThreadLocalMap里Entry为何声明为WeakReference?
    Java JDBC中,MySQL字段类型到JAVA类型的转换
    MyBatis查询两个字段,返回Map,一个字段作为key,一个字段作为value的实现
  • 原文地址:https://www.cnblogs.com/herbix/p/4270035.html
Copyright © 2011-2022 走看看