VOD学习之TS详解

1,有关机顶盒音视频性能的影响因素?

分层,1流媒体传输层,2流媒体编解码层,3解码器工作层。

流媒体传输层主要因素有:丢包,抖动。

丢包:会造成停顿,马赛克。抖动过大:会引起设备缓存上下溢,上溢会引起丢包,下溢使解码器停顿,因此在解码器开始解码之前需要设置好上下溢的百分比。其他因素有,当流媒体编码的速率抖动过大,视频服务器输出的码流抖动过大,网络传输丢包或抖动过大等等,都会使机顶盒收到的码流速率与消耗的码流速率不匹配也会引起上下溢。

2流媒体传输层做哪些工作能避免以上不利因素?

如上所说,设置上下溢百分比,类似TCP的滑动窗口。终端控制服务器发送速率,即流量控制来达到缓存区调整,建立流连接时,将自己的缓存大小通知服务器,服务器根据缓存大小在开始时以高于正常码流速率的速度发到机顶盒,即开始播放时码流快发,也有重传时快发机制。

同时,在下溢时也会采用快发机制,定位播放时,机顶盒将清空缓存,也会快发。

引入丢包恢复机制,组播采用FEC前向纠错等,单播采用ARQ,自动重传等。

从哪里可以看出ARQ机制:机顶盒向流媒体发送的DESCRIBE消息字段X-Returans :是否支持UDP丢包重传能力,X-Burst :是否支持流量控制。

3,流媒体编解码层详解

在直播时,通常传输的是MPEG-TS流,即实时传送的节目,要求从视频流的任意一个片段开始都可以独立解码。TS流是由一个或多个PES组合而来的,他们可以具有相同的时间基准,也可以不同。其基本的复用思想是,对具有相同时间基准的多个PES现进行节目复用,然后再对相互有独立时间基准的各个PS进行传输复用,最终产生出TS。包按功能分为链接头,适配域,净荷。

链接头的长度固定,4个字节,主要负责TS包的同步、各种ES流的表示、TS包传输差错的检测和条件接收等功能。

包同步是包中的第一个字节,TS包以固定的8bit的同步字节开始,所有的TS传送包,同步字都是唯一的OX47,用于建立发送端和接收端包的同步。

如何同步呢?MPEG-2解码器接收到MPEG-2TS流时,首先检测包结构,在TS流中查找同步字节总是OX47,总位于TS包开始位置,固定间隔为188字节。同时满足这两个条件,可以确定同步。1,如果出现一个字节为47hex(OX47),解码器将检测这个字节前后n188字节的位置是否也是同步字节,2,如果是,则当前字节为同步字节;3否则,当前字节只是码流中偶尔出现的47hex,不是同步字节。一般在接收端收到5TS包之后开始同步,而丢包3个之后解码器即失步。

传输误码指示符,是指有不能消除误码时,采用误码校正解码器可表示1bit的误码,但无法校正,从解码器向分接器指示传输误码。若这个比特被设置,表示此TS包中所携带的净荷信息有错误,无法使用。

净荷单元起始指示是指:表示该数据包是否存在确定的起始信息,可以标志PES包头以及包含节目特定信息的表(PMTPAT)的头是否出现在该包中,在失步后的重新同步中起着重要的作用。

传送优先级,用于表示包中含有重要数据,应予以优先传送

加扰控制,传送信息通过加入扰码来加密,各个基本码流可以独立进行加扰。加扰控制字段说明TS包中的净荷数据是否加扰。如果加扰,标志出解扰的密匙。但包头和自适应区永远不加扰。

标识符PIDPID是识别TS包的重要参数,用来识别TS包所承载的数据。在TS码流生成时,每一类业务(视频,音频,数据)的基本码流均被赋予一个不同的识别号PID,解码器借助于PID判断某一个TS包属于哪一类业务的基本码流。PID = 0x0000,表示此TS包的内容为PSI信息表格的PAT表格数据PID值是由用户确定的,解码器根据PIDTS上从不同ES来的TS包区别出来,建立不同的ES队列,这样就能把复用的ES流区分出来,以重建原来的ES

自适应区控制,用2 bit表示有否自适应区,即(01)表示有有用信息无自适应区,(10)表示无有用信息有自适应区,(11)表示有有用信息有自适应区,(00)无定义;在4字节的TS包头之后的第一个字节的Point_field = 0x00, 表示偏移量为0,自适应区长度为0,即紧随其后的即为PAT的数据信息。

循环计数器用于对传输误码进行检测。在发送端对所有的包都做0-15的循环计数,在接收终端,如发现循环计数器的值有中断,表明数据在传输中有丢失。

显然,包头对TS包具有同步、识别、检错及加密功能。

TS包头定义:

typedef struct TS_packet_header
{
unsignedsync_byte : 8; //
同步字节,固定为0x47,表示后面的是一个TS分组
unsignedtransport_error_indicator : 1; //传输误码指示符
unsigned payload_unit_start_indicator : 1;//有效荷载单元起始指示符

unsigned transport_priority : 1; //
传输优先, 1表示高优先级,传输机制可能用到,解码用不着
unsignedPID : 13; //PID
unsigned transport_scrambling_control : 2;//
传输加扰控制
unsignedadaption_field_control : 2; //
自适应控制 01仅含有效负载,10仅含调整字段,11含有调整字段和有效负载。为00解码器不进行处理
unsignedcontinuity_counter : 4; //连续计数器一个4bit的计数器,范围0-15
} TS_packet_header;

 

适配域的长度从0字节到184字节可变,可以没有,也可以扩展到整个TS包。它在TS包中是否存在,由适配域控制标识决定。

TS包自适应区由自适应区长、各种标志指示符、与插入标志有关的信息和填充数据4部分组成。自适应区功能:1、同步和定时2、随机进入压缩的码流3、当地节目插入。

其中标志部分由间断指示符、随机存取指示符、ES优化指示符、PCR标志、接点标志、传输专用数据标志、原始PCR标志、自适应区扩展标志8个部分组成。

重要的是标志部分的PCR字段,可给编解码器的27MHz时钟提供同步资料,进行同步。其过程是,通过PLL,用解码时本地PCR相位与输入的瞬时PCR相位锁相比较,确定解码过程是否同步,若不同步,则用这个瞬时PCR调整时钟频率。

因为,数字图像采用了复杂而不同的压缩编码算法,造成每幅图像的数据各不相同,使直接从压缩编码图像数据的开始部分获取时钟信息成为不可能。

为此,选择了某些(而非全部)TS包的自适应区来传送定时信息。于是,被选中的TS包的自适应区,可用于测定包信息的控制bit和重要的控制信息。自适应区无须伴随每个包都发送,发送多少主要由选中的TS包的传输专用时标参数决定。每隔一定的传送时间,在TS包适配域中传送系统时钟27MHz的一个采样值给接收机,作为解码器的时钟基准信号,称为节目时钟基准(PCR)。PCR通常每隔100ms至少传送一次。

随机进入压缩的码流:在视频码流中存在I帧,B帧,P帧三种编码帧类型,只有I帧编码数据可以独立进行解码。在节目调谐或节目更换时需要随时进入音频或视频,随机进入应该是I帧,在I帧前面的视频序列的头部应该有一个随机进入点,随机进入指标就是表明随机进入点的位置。

在电视广播中,常需要进行本地节目和广告的插入,在MPEG-2传送系统中,使用TS包适配域中的一些标志来支持。插入节目的PCR值与插入前节目的PCR值是不同的,因此通知解码器,要尽快与插入节目建立同步关系。

自适应区中的填充数据是由于PES包长不可能正好转为TS包的整数倍,最后的TS包保留一小部分有用容量,通过填充字节加以填补,这样可以防止缓存器下溢,保持总码率恒定不变。

TS包中净荷所承载的信息包括以下3种:

• 1、视频/音频的PES包以及辅助数据

• 2、描述单路节目复用信息的节目映射表(PMT

• 3、描述单路节目复用信息的节目关联表(PAT

那么什么是PSI

传统上一个物理的频道只能给出包含多路节目的一路传输流。要观看其中的某一路节目,还必须从该传输流中提取出该路节目的压缩包,然后再进行解码。所以怎样从众多的传输流中,选中一路节目播放,就变得很复杂。在mpeg-2的传输流(Transport Stream)中,节目专用信息PSIProgram Specific Information),就是规定不同节目和节目中的不同成分如何复用成一个统一的码流。

PSI信息主要包括以下的表:

PATProgram AssociationTable):节目群丛表,该表的PID是固定的0x0000,它的主要作用是指出该传输流ID,以及该路传输流中所对应的几路节目流的 MAP 表和网络信息表的PID

PMTProgram Map Table):节目映射表,该表的PID是由PAT提供给出的。通过该表可以得到一路节目中包含的信息,例如,该路节目由哪些流构成和这些流的类型(视频,音频,数据),指定节目中各流对应的PID,以及该节目的PCR所对应的PID

NITNetwork InformationTable):网络信息表,该表的PID是由PAT提供给出的。NIT的作用主要是对多路传输流的识别,NIT提供多路传输流,物理网络网络传输的相关的一些信息,如用于调谐的频率信息以及编码方式。调制方式等参数方面的信息。

CATConditional AccessTable):条件访问表,PID 0x0001

除了上述的几种表外,mpeg-2还提供了私有字段,用于实现对MPEG-2的扩充。

因此,MPEG-TS 可以从其视频流的任意一段开始独立解码。解析时,先接收一个负载为PAT的包,在整个数据包找到一个PMT包的ID,然后再接收一个有PMT的包的找到这个ID

 

1,  系统复用时,对视频和音频的ES流进行打包,形成视频和音频的PES流,辅助数据不需要打成PES包。视频和音频的PES包以一帧编码图像为单位,音频PES包恒定长度,视频PES包长度可变。PES包的长度通常都是远大于TS包的长度一个PES包必须由整数个TS包来传送TS包没装满的填充字节。TS包长度固定,188字节,有效净荷184字节。

2,  节目关联表(PAT

PAT包含了与多路节目复用有关的控制信息。

• PAT描述了系统级复用中传送每路节目PMT的码流的PID

• PAT作为一个独立的码流,装载在TS包的净荷中传送,分配唯一的PID。传送PAT的码流的PID值定义为固定的数值“0”

若复用时遇到有不同码流的PID值相同,则在进行系统复用时进行修改,修改必须同时记录在PATPMT中。

每个TS流一个,每隔0.5秒重复。

描述TS流中有多少个节目。

包含该表的TS包的PID0,便于识别。

PATpayload中传送特殊PID的列表,每个PID对应一个节目。

这些PID是描述每个独立节目详细信息的指针。

PID指向PMT表。

 

typedef struct TS_PAT_Program
{
unsigned program_number :16; //
节目号
unsigned program_map_PID :13; //节目映射表的PID,节目号大于0时对应的PID,每个节目对应一个,指向PMT表。
}TS_PAT_Program;

 

//PAT表结构体

typedef structTS_PAT
{
unsigned table_id : 8; //
固定为0x00,标志是该表是PAT
unsigned section_syntax_indicator : 1; //
段语法标志位,固定为1
unsigned zero : 1; //0
unsigned reserved_1 : 2; //
保留位
unsigned section_length : 12; //表示这个字节后面有用的字节数,包括CRC32
unsigned transport_stream_id : 16; //
该传输流的ID,区别于一个网络中其它多路复用的流
unsigned reserved_2 : 2;// 保留位
unsigned version_number : 5; //范围0-31,表示PAT的版本号
unsigned current_next_indicator : 1; //发送的PAT是当前有效还是下一个PAT有效
unsigned section_number : 8; //分段的号码。PAT可能分为多段传输,第一段为00,以后每个分段加1,最多可能有256个分段
unsigned last_section_number : 8; //最后一个分段的号码

std::vector<TS_PAT_Program> program;
unsigned reserved_3 : 3; //
保留位
unsigned network_PID : 13; //网络信息表(NIT)的PID,节目号为0时对应的PIDnetwork_PID

unsigned CRC_32 :32; //CRC32校验码
} TS_PAT;

 

3节目映射表(PMT):

PMT表包含了与单路节目复用有关的节目信息,典型的构成包括1路视频ES流,2-5路音频ES流,1路或多路辅助数据。进行TS流复用时,各路ES流被分配了唯一的PID,ES流域被分配的PID值间的关系构成了一张表,称为节目映射表PMTPMT完整描述了一路节目由哪些ES流组成,例如某个直播频道的传送流是由哪些ES流组成的。他们的PID分别是什么。MPEG-2传送层中,传送PMT表的码流称为控制码流,和其他ES流一样,在TS包的净荷中传送,分配唯一的PID

typedef struct TS_PMT_Stream
{
unsigned stream_type : 8; //
指示特定PID的节目元素包的类型。该处PIDelementary PID指定
unsigned elementary_PID : 13; //该域指示TS包的PID值。这些TS包含有相关的节目元素
unsigned ES_info_length : 12; //前两位bit00。该域指示跟随其后的描述相关节目元素的byte
unsigned descriptor;
}TS_PMT_Stream;

//PMT 表结构体
typedef struct TS_PMT
{
unsigned table_id : 8; //
固定为0x02,表示PMT
unsigned section_syntax_indicator : 1; //固定为0x01
unsigned zero : 1; //0x01
unsigned reserved_1 : 2; //0x03
unsigned section_length : 12;//
首先两位bit置为00,它指示段的byte数,由段长度域开始,包含CRC
unsigned program_number : 16;//指出该节目对应于可应用的Program map PID
unsigned reserved_2 : 2; //0x03
unsigned version_number : 5; //
指出TS流中Program map section的版本号
unsigned current_next_indicator : 1; //当该位置1时,当前传送的Programmap section可用;
//当该位置0时,指示当前传送的Program map section不可用,下一个TS流的Program map section有效。
unsigned section_number : 8; //固定为0x00
unsigned last_section_number : 8; //
固定为0x00
unsigned reserved_3 : 3; //0x07
unsigned PCR_PID : 13; //
指明TS包的PID值,该TS包含有PCR域,
//PCR值对应于由节目号指定的对应节目。
//如果对于私有数据流的节目定义与PCR无关,这个域的值将为0x1FFF
unsigned reserved_4 : 4; //预留为0x0F
unsigned program_info_length : 12; //
前两位bit00。该域指出跟随其后对节目信息的描述的byte数。
std::vector<TS_PMT_Stream> PMT_Stream; //每个元素包含8,指示特定PID的节目元素包的类型。该处PIDelementary PID指定
unsigned reserved_5 : 3; //0x07
unsigned reserved_6 : 4; //0x0F
unsigned CRC_32 : 32;
} TS_PMT;

工作流程:

一个节目可能有多个视频和音频流,解码器必须选择2PID,一个视频流的PID100hex),一个音频流的PID200hex)。此后解码器只收集这些TS包,解复用,重新组成PES包,这些PES包再送到视频或音频解码器。传输过程中TS流的结构也可能发生改变。解码端机顶盒,必须连续检测TS流瞬时结构,读出PATPMT,做自适应调整。PATPMT读出以后,用户确定出一个节目的两个PID:待解码视频信号的PID(如100hex),待解码音频信号的PID(如200hex)。

解码器只处理这两个PIDTS包:解复用过程中,PID100hex的所有TS包集合成视频PES包,送到视频解码器。同样,PID200hex的所有TS包重新集合成音频PES包,送到音频解码器。如果ES流没有加扰,这时可以直接解码。对付费电视或许可证和地域限制等情况,ES流利用电子码进行传输保护。ES流利用各种方法进行混扰,接收端必须配有附加硬件并授权。

4解码器工作中注意哪些?

目前的机顶盒主要采用arm+dsp dsp用来解码。linux音频驱动包含两个基本的音频设备:1mixer(混音器),作用是叠加多个信号,对应设备文件:/dev/mixer.其大部分操作是通过ioctl()完成的。2DSP也称编码器,对应的设备文件是/dev/dsp,向该设备写数据意味着播放。而向该设备读数据则意味着录音。读到的数据从内核缓冲区复制到应用缓冲区,这个中间就有一个谁快谁慢的问题。当应用缓冲区慢了则会阻塞,多余的数据会被丢弃。应用读取过快,则会被驱动程序阻塞掉直到新的数据到来为止。同样,播放时也有一个缓冲区,也有写入速度快慢的问题,过慢的话,会产生声音暂停或者停顿的现象。,写入过快的话,会被内核驱动阻塞掉,直到硬件有能力处理新的数据。使用ioctl可以对缓冲区大小设置。设置单声道,立体声等。

 

5,前面讲到将video ,audio分别送到其对应解码器中,那是如何做到音视频同步呢?

音频和视频流都有一些关于以多快速度什么时间来播放它们的信息在里面。音频流有采样率,视频流有每秒的帧率。然而,如果我们只是简单的通过数帧和乘以帧率的方式来同步视频,那么就很有可能会失去同步。于是作为一种补充,在流中的包有种叫做DTS(解码时间戳)和PTS(显示时间戳)的机制。

音视频同步方法:选择一个参考时钟,参考时钟上的时间是线性递增的,生成数据流时依据参考时钟上的时间给每个数据块都打上时间戳(一般包括开始时间和结束时间)。在播放时,读取数据块上的时间戳,同时参考当前参考时钟上的时间来安排播放。数据流不会发生参考关系。

可以看到PTS/DTS是打在PES包里面的,这两个参数是解决视音频同步显示,防止解码器输入缓存上溢或下溢的关键。当我们调用av_read_frame()得到一个包的时候,PTSDTS的信息也会保存在包中。

但是我们真正想要的PTS是我们刚刚解码出来的原始帧的PTS,这样我们才能知道什么时候来显示它。

DTS表示将存取单元全部字节从STDES解码缓存器移走的时刻PTS表示显示单元出现在系统目标解码器(STD: systemtarget decoder)的时间,。

DTSDecode Time StampDTS主要是标识读入内存中的bit流在什么时候开始送入解码器中进行解码。

PTSPresentation Time StampPTS主要用于度量解码后的视频帧什么时候被显示出来。

每个IPB帧的包头都有一个PTSDTSPTSDTSB帧都是一样的,无须标出B帧的DTSB frame: 双向预测内插编码帧又称bi-directional interpolated prediction frame,既考虑与源图像序列前面已编码帧,也顾及源图像序列后面已编码帧之间的时间冗余信息来压缩传输数据量的编码图像,也叫双向预测帧。对I帧和P帧,显示前一定要存储于视频解码器的重新排序缓存器中,经过延迟(重新排序)后再显示,一定要分别标明PTSDTS。在没有B帧存在的情况下DTS的顺序和PTS的顺序应该是一样的。IPB帧的不同: I frame:自身可以通过视频解压算法解压成一张单独的完整的图片。 P frame:需要参考其前面的一个I frame或者B frame来生成一张完整的图片。

除了PTSDTS的配合工作外,还有一个重要的参数是SCR(system clock reference)。在编码的时候,PTSDTSSCR都是由STC(systemtime clock)生成的,在解码时,STC会再生,并通过锁相环路(PLLphase lock loop),用本地SCR相位与输入的瞬时SCR相位锁相比较,以确定解码过程是否同步,若不同步,则用这个瞬时SCR调整27MHz的本地时钟频率。最后,PTSDTSSCR一起配合,解决视音频同步播放的问题。

所以对于一个电影,帧是这样来显示的:I B B P。现在我们需要在显示B帧之前知道P帧中的信息。因此,帧可能会按照这样的方式来存储:IPBB。这就是为什么我们会有一个解码时间戳和一个显示时间戳的原因。解码时间戳告诉我们什么时候需要解码,显示时间戳告诉我们什么时候需要显示。所以,在这种情况下,我们的流可以是这样的:

PTS: 1 4 2 3
DTS: 1 2 3 4
Stream: I P B B
通常PTSDTS只有在流中有B帧的时候会不同。

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值