Android流媒体处理流程分析

1. WiFiDisplay简介

WiFiDisplay是一系列协议栈的组合,运行在基于WiFi-P2P协议建立起来的IP网络上,Source端与Sink端设备都分配到一个IP,IP网段为192.168.49.xx,在这个网段内,Source设备与Sink设备通过一系列应用层协议,如RTSP、RTP以及RTCP等建立流媒体传输通道,完成Source设备镜像传输。
在这里插入图片描述
WiFiDisplay协议栈

2.RTSP协议流程分析

RTSP过程属于媒体能力协商过程,主要包括以下内容协商
1.音视频参数
2.媒体端口协商
– M1 : Source 端发送 RTSP Options 请求
Source端想知道Sink端支持那些Options方法
在这里插入图片描述
– M2 : Sink 响应 RTSP Options
Sink端回复Source端自己支持Options方法,并回复200OK状态码
在这里插入图片描述
– M3 : Source 发送 RTSP Get Parameter 消息
用于向Sink端描述自己想要请求获取的显示能力
在这里插入图片描述
wfd_content_protection //内容保护,和HDCP有关
wfd_video_formats //支持的视频分辨率
wfd_audio_codecs //支持的音频编码
wfd_client_rtp_ports //rtp 端口
– M3 : Sink 响应Source端 的RTSP Get Parameter 请求
响应支持的能力参数,不支持的能力参数不响应
在这里插入图片描述

– M4 : Source端决定选择那些参数用于会话,发送RTSP Set Parameter给Sink 初始化
在这里插入图片描述
– M4 : Sink 回复Source 200Ok状态码
在这里插入图片描述
在这里插入图片描述

– M5 : Source 发送 RTSP Set Parameter 请求,并携带“setup”出发器
在这里插入图片描述

– M5 : Sink 响应 RTSP Set Parameter 200OK状态码
在这里插入图片描述
– M6 : Sink 发送 RTSP Setup 请求 用于建立RTP端口
在这里插入图片描述

– M6 : Source 响应 RTSP Setup 端口信息以及结果状态码
在这里插入图片描述

– M7 : Sink 发送 RTSP Play请求到 Source
告诉Source端,我已经准备好接收RTP流了
在这里插入图片描述
– M7 : Source 响应 RTSP Play ,包括200Ok状态码,timeout,Range:流开始时间
•
到此,协商完成,Source开始向Sink端指定端口传流。

在传输中Source端通过RTSP get Parameter 消息用于保活的, 该消息中不带任何参数。
在这里插入图片描述

3. 流媒体协议简介

在协议栈图中和媒体相关的协议包括RTSP、RTP、MPEG2TS、HDCP,其中HDCP协议与数字版权有关,在HDMI高清认证中有这一项认证。在WIFIDisplay协议中,HDCP协议属于可选实现,就是说不实现也可以传输镜像,RTSP协议属于流媒体控制协议,RTP用于传输音视频流,通常使用UDP协议传输,也可以使用TCP传输,RTP的payload是mpeg2ts流,这是一种流媒体封装格式,mpeg2ts包大小是固定,每个包长188byte, mpeg2ts的payload是真正的H264裸流或者AAC音频流。

下图中展示了 WiFiDisplay传输的流媒体格式
WFD流媒体传输格式
WFD Source设备通过MPEG2TS封装格式来封装AV信息,然后依次包装进RTP、UDP、IP协议中,然后传输给WFD Sink设备

– WFD Source将音频和/或视频流通过多路复用技术打包进单个MPEG2传输流中
– WFD Source可以选择性的将音视频流放到单独的MPEG2流中处理,允许耦合接收操作

4. RTP、RTCP协议简介

4.1 RTP协议

RTP全名是Real-time Transport Protocol(实时传输协议)。定义在RFC3550不仅定义了RTP,与其配套的相关协议RTCP(Real-time Transport Control Protocol,即实时传输控制协议)。RTP用来为IP网上的语音、图像、传真等多种需要实时传输的多媒体数据提供端到端的实时传输服务。RTP为Internet上端到端的实时传输提供时间信息和流同步,但并不保证服务质量,服务质量由RTCP来提供。

  1. RTP使用场景
    RTP用于在单播或多播网络中传送实时数据,具体场景包括:
    1.简单的多播音频会议。
    2.翻译器和混合器。
    3.音频和视频会议。
  2. 流媒体概念

流媒体是指Internet上使用流式传输技术的连续时基媒体。当前在Internet上传输音频和视频等信息主要有两种方式:下载和流式传输两种方式。
下载情况下,用户需要先下载整个媒体文件到本地,然后才能播放媒体文件。
流式传输是实现流媒体的关键技术。使用流式传输可以边下载边观看流媒体节目。由于Internet是基于分组传输的,所以接收端收到的数据包往往有延迟和乱序(流式传输构建在UDP上)。要实现流式传输,就是要从降低延迟和恢复数据包时序入手。在发送端,为降低延迟,往往对传输数据进行预处理(降低质量和高效压缩)。在接收端为了恢复时序,采用了接收缓冲;而为了实现媒体的流畅播放,则采用了播放缓冲。
使用接收缓冲,可以将接收到的数据包缓存起来,然后根据数据包的封装信息(如包序号和时戳等),将乱序的包重新排序,最后将重新排序了的数据包放入播放缓冲播放。

到目前为止,Internet 上使用较多的流式视频格式主要有以下三种:RealNetworks 公司的RealMedia, Apple 公司的QuickTime 以及Microsoft 公司的Advanced Streaming Format (ASF) 。这些流式媒体格式只是编解码有不同,但对于RTP来说,它们都是待封装传输的流媒体数据而没有什么不同。

RTP所处的网络体系层次位于TCP、UDP之上,被划分在传输层,它建立在UDP上。同UDP协议一样,为了实现其实时传输功能,RTP也有固定的封装形式。RTP用来为端到端的实时传输提供时间信息和流同步,但并不保证服务质量。服务质量由RTCP来提供。
在这里插入图片描述

RTP协议格式

RTP协议头信息
版本号(V):2 bits,用来标志使用的RTP版本。

填充位(P):1 bits,如果该位置位,则该RTP包的尾部就包含附加的填充字节。

扩展位(X):1 bits,如果该位置位的话,RTP固定头部后面就跟有一个扩展头部。

CSRC计数器(CC):4 bits,含有固定头部后面跟着的CSRC的数目。

标记位(M):1 bit,该位的解释由配置文档(Profile)来承担.

载荷类型(PT):7 bits,标识了RTP载荷的类型, 用于说明RTP报文中有效载荷的类型,如GSM音频、JPEM图像等,在流媒体中大部分是用来区分音频流和视频流的,这样便于客户端进行解析。

序列号(SN):16 bits,发送方在每发送完一个RTP包后就将该域的值增加1,接收方可以由该域检测包的丢失及恢复包序列。序列号的初始值是随机的。

时间戳:32 bits,记录了该包中数据的第一个字节的采样时刻。在一次会话开始时,时间戳初始化成一个初始值。即使在没有信号发送时,时间戳的数值也要随时间而不断地增加(时间在流逝嘛)。时间戳是去除抖动和实现同步不可缺少的。

同步源标识符(SSRC):32 bits,同步源就是指RTP包流的来源。在同一个RTP会话中不能有两个相同的SSRC值。该标识符是随机选取的 RFC1889推荐了MD5随机算法。

贡献源列表(CSRC List):0~15项,每项32 bits,用来标志对一个RTP混合器产生的新包有贡献的所有RTP包的源。由混合器将这些有贡献的SSRC标识符插入表中。SSRC标识符都被列出来,以便接收端能正确指出交谈双方的身份。

相关头信息的详细解释参考

RTP协议分析和详解
RTP与RTCP解释.含同步时间戳 相关章节

分包大小限制

分包大小:<= 1500-20(IP头)-8(UDP)-12(rtp) 1460

4.1 RTP载荷H264码流

参考 RTP协议全解析(H264码流和PS流)RTP荷载H264码流 章节中的相关描述。

4.2 RTP载荷PS码流

参考 RTP协议全解析(H264码流和PS流)RTP荷载PS流 章节中的相关描述。

4.2 RTP载荷MPEG2TS码流

4.2.1 基本概念

1.ES–Elementary Streams(原始流)是直接从编码器出来的数据流,ES经过PES打包器之后,转换成PES包。

ES仅是包含一种数据内容的数据流,如h.264视频或者aac音频数据。打包之后的PES也是只包含一种的ES,如只含视频ES的PES或者只含音频ES的PES。每个ES都由若干个存取单元(AU)组成,每个视频AU或者音频AU都由头部和编码数据两部分组成,一个AU相当于编码的一幅视频图像或一个音频帧。

2.PES–Packetized Elementary Streams(分组的ES),ES形成的分组成为PES分组,是用来传递ES的一种数据结构。
在PES打包器打包ES的过程中完成了将ES流分组,打包,加入包头信息等操作(是对ES流的第一次打包操作)。PES流的基本单位是PES包。PES包由包头和payload组成。

3.TS–Transport Streams(传输流)由定长的TS包组成(188字节),而TS包是对PES的一种重新封装(到这里,ES经过了两层封装)。PES包的包头信息依然存在于TS包中。

参考:https://blog.csdn.net/rootusers/article/details/42772657

WFD流媒体传输格式 图的描述中,每n个MPEG-TS Packet打包为一个RTP,然后每个RTP再打包为一个UDP。其中打包RTP的方法就是在MPEG-TS数据前面加上RTP Header,而打包RTP的方法就是在RTP数据前面加上UDP Header。

TS包打包流程
TS包打包流程如下:

1.A/D转换后,通过MPEG-2压缩编码得到ES基本流。该流数据量很大,并且只是I P B帧的取样信息。

2.通过PES打包器,打包并在每个帧中插入PTS/DTS标识,编程PES。原来是流的格式,现在成了数据包的分割形式。

3.PES根据需要打包成PS或者TS包进行存储。

4.2.2 PES相关

PES是打包过的ES,已经插入PTS和DTS,一般一个PES是一帧图像。

PES包结构说明
PES经过打包成TS或PS流,往往一个PES会分存到多个TS包中。

1.PES包的包起始码:包起始码前缀是一个固定的码字结构,它的值是0x000001,用于收发两端对PES包进行同步。
2.PES包的长度:PES包的长度是可变的,PES包长度域有两个字节,共16比特,因此PES包的最大长度是65535字节
3.PES包头:PES包头的功能根据特定的应用场合有所不同,包括加扰控制,优先级,ES流速率和CRC等,其中有两个重要的工作:PTS和DTS。
原文链接:https://blog.csdn.net/rootusers/article/details/42772657

4.2.2 TS相关
  1. 包结构说明
    TS头部信息

1.sync_byte 8bits 同步字节, 值为0x47

2.transport_error_indicator 1bit 错误指示信息
值为1时,表示相关的传送包中至少有一个不可纠正的错误位,只有错误位纠正后,该位才能置0;

3.payload_unit_start_indicator 1bit 负载单元开始标志
当TS包带有PES包数据时,payload_unit_start_indicator值为1时,表示TS包的负载以PES包的第一个字节开始,值为0,表示TS包开始的不是PES包。

当TS包带有PSI数据时,payload_unit_start_indicator值为1时,表示TS包带有PSI部分的第一个字节,即第一个字节带有指针pointer_field;置为0,表示TS包不带有一个PSI部分的第一个字节,即在有效净荷中没有指针的pointer_field.
空包payload_unit_start_indicator应置为0.

4.transport_priority 1bit 传输优先级标志
置1表示相关的包比其他具有相同PID但transport_priority为0的包有更高的优先级;

5.PID 13bit packet ID号码,唯一的号码对应不同的包
表示净荷的数据类型。具体的取值对应关系如下
在这里插入图片描述
在这里插入图片描述

6.transport_scrambling_control 2bit 加密标志, 指示TS包有效净荷的加扰方式,如果首部包括调整字段,则不应该被加扰,对于空包,值要置“00”;
在这里插入图片描述

7.adaptation_field_control 2bit 附加区域控制也就是MPEG-2 TS包调整字段

在ts中,为了传送打包后的长度不足188B的不完整TS,或者为了在系统层插入节目时钟参考PCR字段,需要在TS包中插入可变长字节的调整字段。调整字段是一个可变长的域,它是由存在于TS包头中的调整字段控制值来标识的。
在这里插入图片描述
adaption_field_control为“调整字段控制”,表示TS分组首部后面是否跟随有调整字段和有效负载。01仅含有效负载,10仅含调整字段,11含有调整字段和有效负载。为00解码器不进行处理。空分组没有调整字段。如果有调整字段就是包数据的第一位(除去包头)指定调整字段长度。
因为00和10都没有有效负载所以不进行处理,为1表示只有有效负载,数据从第5个字节(数组下标为4)开始;如果为11则从调整字段后一位(第6个字节,数组下标5)加上调整字段长度为包有效数据开始位置。
8.continuity_counter 4bit 包递增计数器
随着具有相同PID TS包的增加而增加,当达到最大时,又恢复为0,如果调整字段控制值adaptation_field_control为“00”或“10”,则该连续计数器不增加;在TS中,当复用的包可能被作为两个连续的具有相同PID的TS包传送出去时,则复用的传送包与原传送包具有相同的continuity_counter,而adaptation_field_control字段值应为“01”或者"10"。在复用的包中,除了节目参考时钟PCR有效字段的值被重新编码外,原包中每个字节将被复制。

在特定的TS中具有相同PID包的continuity_counter是连续的,或与前一个具有相同PID的包相差1,但是遇到adaptation_field_control为“00”或“10”等不增加条件,或在调整字段中discontinuity_indicator为“1”时,continuity_counter将不连续。
对于 adaption_field_control 字段域详细的描述参考TS Stream 详解 中关于 自适应调整字段 章节的描述。

  1. 包类型说明
    一个TS包的载荷中,可以包含PAT包、PMT包、多个音频包、多个视频包、多个PCR包、以及其他信息包。
    TS包中负载传送的信息主要有4种类型:
    1.视频和音频的PES包以及辅助数据。
    2.描述单路节目的节目映射表(PMT)与描述多路节目复用信息的节目关联表(PAT)以及对CA系统所要求的条件访问表(CAT)。
    3.各种业务信息表。
    4.DVB数据广播信息,包括数据管道,异步数据报,同步,被同步数据流,多协议封装,循环数据,循环对象。

TS包负载部分可以分成两种类型:
1、视频、音频的PES包以及辅助数据。其中音视频的ES需要被打包成为PES,而辅助数据不需要被打包成PES
2、节目专用信息PSI,包括下面几种:
PAT:节目关联表。提供了节目好和对应PMT表格的PID的对应关系
PMT:节目映射表。定义了与特定节目相关的PID信息,例如:音频包的pid,视频包的pid、pcr的pid
CAT:条件接收表。用于流加扰情况下配置参数。
NIT:网络信息表。可选的,标准未详细定义
TSDT:传输流描述表。可选的。

————————————————
原文链接:https://blog.csdn.net/rootusers/article/details/42970859

  1. 获取TS包中的音视频数据
    如果给定一个TS文件,怎么去寻找解码音视频解码数据呢?每个TS包的前4个字节的包头里都有一个PID

      1、首先,一个个遍历TS包,我们找到PID为0的TS包,这个包叫PAT,这个PAT包里包含了PMT的PID   号
      2、遍历TS包又可以找到名为PMT的TS包,PMT里有什么呢?PMT里包含了video TS包的PID和它的codec,audio TS包的PID和它的codec 。有了codec我们知道要选择什么解码器,有PID我们就可以获得解码数据。
      3、我们先来说说video数据和audio数据是怎么分散在TS包里的。video和audio其实都是以一种叫PES(Packetized Elementary Stream)的形式组织的。一帧视频就是一个PES包。我们都知道一个TS包只有188个字节,除掉包头还剩184个字节,这是不可能放下一帧的。
      4、实际上一个PES包是分配在连续的几个TS包中,所以如果我们要获得一帧数据,那么我们需要把连续的几个TS包里的数据全部取出来才能组合成一个PES。
      5、那我们怎么知道一个PES的开始和结尾呢?那我们还是一个个遍历每一个TS包,寻找包头里payload_unit_start_indicator为1包,这个标志位代表着是一个PES的开始,那么我从这开始,一直到下一个payload_unit_start_indicator为1,这中间的TS包组成起来就是一个PES。
    
  2. 解析TS流数据的流程

     1、查找PID为0x0的包,解析PAT,PAT包中的program_map_PID表示PMT的PID;
     2、查找PMT,PMT包中的elementary_PID表示音视频包的PID,PMT包中的PCR_PID表示PCR的PID,
     3、有的时候PCR的PID跟音频或者视频的PID相同,说明PCR会融进音视频的包
     4、有的时候PCR是自己单独的包;
     5、CAT、NIT、SDT、EIT的PID分别为: 0x01、0x10、0x11、0x12。
    
4.2.3 编码相关

MPEG2的三类帧
I帧:是帧内编码帧,其编码不依赖BP两帧,同时他是BP帧编解码的参考图像
P帧:前向预测编码图像,像素的预测值取为前面与其相邻的I帧或P帧中对应像素的值,即采用帧间运动补偿前值预测。
B帧:双向预测编码图像,像素的预测值取为前后与其距离最近的I帧或P帧相应像素的加权平均,即采用帧间运动补偿前后平均,需要指出,B帧不能作为其他B帧或P帧的编码参考图像。
编码顺序:
传输流中编码图像的顺序按照IPB的顺序

显示顺序:
在解码输出端重建图像的顺序,按照IBP的顺序。

一个视频图像,是由图像组(Grop)组成的。每个图像组由一个I帧和3个P帧8个B帧组成的。
图像的显示顺序为:1I,2B,3B,4B, 5B,6B,7P,8B,9B,10P,11B,12B,13I
图像的编码顺序为:1I,4P, 2B,3B, 7P,5B,6B,10P,8B,9B,13I,11B,12B
————————————————
原文链接:https://blog.csdn.net/rootusers/article/details/42970859

注意事项:

在MPEG2-TS相关开发的时候注意两点:
1、对于RTP协议头,由于大小端对结构体的位域也有影响,定义的时候要考虑大小端问题。
2、对于每次发送UDP包中TS包的个数。
考虑到以太网数据帧的最大长度为1500,所以一般规定,每7个TS数据包封装在一起进行发送。
另外我在测试的过程中通过ffmpeg进行ts数据包推流,每次socket接受到的UDP数据包大小为1328byte,也就是7*188+12,这里12为rtp协议头大小。
UDP_RTP+MPEG2-TS浅析:https://blog.csdn.net/h514434485/article/details/52120625

参考
视音频数据处理入门:UDP-RTP协议解析
https://blog.csdn.net/leixiaohua1020/article/details/50535230

RTP 协议
https://www.cnblogs.com/qingquan/archive/2011/07/28/2120440.html

4.2 RTCP协议

RTCP的主要功能是:服务质量的监视与反馈、媒体间的同步,以及多播组中成员的标识。在RTP会话期 间,各参与者周期性地传送RTCP包。RTCP包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料,因此,各参与者可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。RTP和RTCP配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,因而特别适合传送网上的实时数据。

RTCP也是用UDP来传送的,但RTCP封装的仅仅是一些控制信息,因而分组很短,所以可以将多个RTCP分组封装在一个UDP包中。RTCP有如下五种分组类型。

RTCP的5种分组类型
发送端报告分组SR(Sender Report)用来使发送端以多播方式向所有接收端报告发送情况。SR分组的主要内容有:相应的RTP流的SSRC,RTP流中最新产生的RTP分组的时间戳和NTP,RTP流包含的分组数,RTP流包含的字节数。SR包的封装如下图所示。
RTCP头部格式
版本(V):2 bits 同RTP包头域。

填充(P):1bits 同RTP包头域。

接收报告计数器(RC):5bits,该SR包中的接收报告块的数目,可以为零。

包类型(PT):8 bits,SR包是200。

长度域(Length):16 bits,其中存放的是该SR包以32 bits为单位的总长度减一。

同步源(SSRC):SR包发送者的同步源标识符。与对应RTP包中的SSRC一样。

NTP Timestamp(Network time protocol):32 bits, SR包发送时的绝对时间值。NTP的作用是同步不同的RTP媒体流。

RTP Timestamp:32 bits, 与NTP时间戳对应,与RTP数据包中的RTP时间戳具有相同的单位和随机初始值。

Sender’s packet count:32 bits, 从开始发送包到产生这个SR包这段时间里,发送者发送的RTP数据包的总数. SSRC改变时,这个域清零。

Sender`s octet count:32 bits, 从开始发送包到产生这个SR包这段时间里,发送者发送的净荷数据的总byte数(不包括头部和填充)。发送者改变其SSRC时,这个域要清零。

同步源n的SSRC标识符:32 bits, 该报告块中包含的是从该源接收到的包的统计信息。

丢失率(Fraction Lost):8 bits, 表明从上一个SR或RR包发出以来从同步源n(SSRC_n)来的RTP数据包的丢失率。

累计的包丢失数目:24bits, 从开始接收到SSRC_n的包到发送SR,从SSRC_n传过来的RTP数据包的丢失总数。

收到的扩展最大序列号:32 bits, 从SSRC_n收到的RTP数据包中最大的序列号,

接收抖动(Interarrival jitter):32 bits, RTP数据包接受时间的统计方差估计

上次SR时间戳(Last SR,LSR):32 bits, 取最近从SSRC_n收到的SR包中的NTP时间戳的中间32比特。如果目前还没收到SR包,则该域清零。

上次SR以来的延时(Delay since last SR,DLSR):32 bits, 上次从SSRC_n收到SR包到发送本报告的延时。

4.3 RTP会话过程

当应用程序建立一个RTP会话时,应用程序将确定一对目的传输地址。目的传输地址由一个网络地址和一对端口组成,有两个端口:一个给RTP包,一个给RTCP包,使得RTP/RTCP数据能够正确发送。RTP数据发向偶数的UDP端口,而对应的控制信号RTCP数据发向相邻的奇数UDP端口(偶数的UDP端口+1),这样就构成一个UDP端口对。 RTP的发送过程如下,接收过程则相反。

  1. RTP协议从上层接收流媒体信息码流(如H.264),封装成RTP数据包;RTCP从上层接收控制信息,封装成RTCP控制包。
  2. RTP将RTP 数据包发往UDP端口对中偶数端口;RTCP将RTCP控制包发往UDP端口对中的接收端口。

4.4 常见问题以及解决方案

  1. 怎样重组乱序的数据包
    可以根据RTP包的序列号来排序。

  2. 怎样获得数据包的时序
    可以根据RTP包的时间戳来获得数据包的时序。

  3. 声音和图像怎么同步
    根据声音流和图像流的相对时间(即RTP包的时间戳),以及它们的绝对时间(即对应的RTCP包中的RTCP),可以实现声音和图像的同步。

  4. 接收缓冲和播放缓冲的作用
    如1.3.1所述,接收缓冲用来排序乱序了的数据包;播放缓冲用来消除播放的抖动,实现等时播放。

5. 参考

[RTP协议分析]
https://blog.csdn.net/u011006622/article/details/80675054
[RTP协议全解析(H264码流和PS流)]
https://blog.csdn.net/chen495810242/article/details/39207305

6. 测试资源

rtsp在线资源
https://blog.csdn.net/pkueecser/article/details/8677022
rtmp在线资源
https://blog.csdn.net/language_zcx/article/details/96011836

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Calvin880828

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值