TS视频封装协议详细说明

这篇具有很好参考价值的文章主要介绍了TS视频封装协议详细说明。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

TS封装格式概述

TS(Transport Stream) 是一种常见的视频封装格式, 主要用于数字电视和在线视频传输领域。优缺点如下所示:
优点:
1.容错性强: 传输过程中发生丢包或错误信息丢失的情况, 可以快速恢复, 保障数据的完整性。
2.支持随机访问: TS格式对数据进行了分段, 每段可以单独访问和控制, 实现了视频的随机访问。
3.实时性好: TS 封装格式采用分段传输的方式,每个数据片段的大小相对较小,可以有效降低延迟,实现了实时数据传输。
4.可靠性好: TS 封装格式支持多路复用,能够对多个数据流进行混合,提高数据传输效率和可靠性。

缺点:
1.编解码复杂: TS 封装格式需要将视频数据进行分段和整合,对音视频编码技术的要求较高
2.文件较大: TS分段机制, 引入了一定的数据头信息
3.不支持字幕处理:TS 封装格式不支持对字幕数据进行处理,用户需要手动添加字幕

TS数据包

TS封装格式的数据单元是ts包。 每个包都有自己的pid, 包的大小固定为188字节。
ts包分为三类分别为:pat包、pmt包、pes包:

  • PAT(Program Associate Table)包为第一个包, 也就是ts的入口, 它的pid固定为为0x00; pat包里面有pmt包的pid, 通过pat包能定位到pmt包
  • PMT(Program Map Table) 用于描述一个流的内容信息,包括音频、视频或数据信息。 pmt包里面存的就是数据流包的pid,音频包的PID是0x102, 视频包的PID是0x101
  • PES(Packetized Elementary Stream)包是一种基本的数据单元,用于传输音频、视频等多媒体数据信息。

在TS流中, PAT和PMT包重复实现, 大约0.5秒出现一个,保证实时解码性。PAT表是TS流的基础, 任何一个TS流解析寻找节目都是从PAT表开始查找。

TS数据包的结构

ts包固定大小为188个字节, 对应的结构公式如下所示:
tsPacket = tsheader + adaption field + payload;

tsheader: 为ts数据包的包头, 每个数据包都有, 文件头固定为4个字节
adaptation field: 数据填充字段, 有的数据包存在该字段,有的数据包不存在该字段(用作数据填充)
palyload: 音视频数据字段,用来存储pes数据和音视频的原始数据。

各种类型的数据包的结构如下所示:

TS流: 由一个个188字节的数据包组成                      
  +-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  TS   |  =  |  Packet 1 |  Packet 2 |  Packet 3 |    ...    | Packet n-1|  Packet n |
  +-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  
一个Packet:             4bytes             184bytes         
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Packet | =  |    ts header |       Packet data        |
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

PAT/PMT包结构, 只包含tsheader和PMT/PAT, 不包含adaption和pes
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | ts header |    PAT/PMT    |   Stuffing Bytss  |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

PES包结构,可能包含adaption和pes字段
       4 byte         x byte                    184-x byte
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | ts header |  adaptation field |          payload(pes)       |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

ts header的数据结构

每个TS数据包都包含ts header字段, 并且大小固定为4个字节, 四个字节中各个数据位的含义如下所示:
总共4Byte(32bit)

sync_byte                       (8bit)  同步字节,固定为0x47
transport_error_indicator	    (1bit)  传输错误指示符, 通常都为'0'
payload_unit_start_indicator    (1bit)  负载单元起始标示符,一个完整的数据包开始时标记为 '1'
transport_priority              (1bit)  传输优先级,0为低优先级,1为高优先级,通常取0
pid	                            (13bit) 传输包的PID, pat包固定为0x0000 
transport_scrambling_control	(2bit)  传输加扰控制,00表示未加密
adaptation_field_control        (2bit)  是否包含自适应区(adaption):00保留;01无自适应域,含有效负载;10含自适应域,无有效负载;11为同时带有自适应域和有效负载
continuity_counter              (4bit)  递增计数器,从0-f,起始值不一定取0,但必须是连续的

PAT字段的数据结构

PAT(Program Associate Table)节目关联表的结构如下所示:

table_id	                (8bit)	PAT表固定为0x00
section_syntax_indicator	(1bit)	段语法标志位, 固定为1
zero	                    (1bit)	固定为0
reserved	                (2bit)	保留位,固定为11
section_length	            (12bit)	段长度(后面数据的长度),表示从下一个字段开始到CRC32(包含)之间有用的字节数
transport_stream_id	        (16bit)	传输流ID,固定为0x0001, 区别于一个网络中其它多路复用的流
reserved	                (2bit)	固定为11
version_number	            (5bit)	版本号,固定为00000,如果PAT有变化则版本号加1
current_next_indicator	    (1bit)	固定为1,表示这个PAT表可以用,如果为0则要等待下一个PAT表
section_number	            (8bit)	分段的号码. PAT可能分为多段传输, 第一段为00, 以后每个分段加1, 最多可能有256个分段
last_section_number	        (8bit)	固定为0x00, 最后一个分段的号码

开始循环,按顺序可能包含多个下面结构	 	 
program_number	            (16bit)	节目号为0x0000时表示这是NIT,节目号为0x0001,表示这是PAT
reserved	                (3bbit)	固定为111
PID	                        (13bit)	节目号对应内容的PID值0x1000, 也就是pmt的pid
结束循环	

CRC32	                    (32bit)	前面数据的CRC32校验码

PMT字段的数据结构

PMT(Program Map Table), 节目映射表, 该包的PID可以由PAT表获取。

table_id	                (8bit)	PMT表取值随意, 这里给定0x02
section_syntax_indicator	(1bit)	段语法标志位, 固定为1
zero	                    (1bit)	固定为0
reserved	                (2bit)	保留位,固定为11
section_length	            (12bit)	后面数据的长度, 表示从下一个字段开始到CRC32()之间有用的字节数
program_number	            (16bit)	频道号码,表示当前的PMT关联到的频道, 取值0x0001
reserved	                (2bit)	固定为11
version_number	            (5bit)	PMT版本号码,固定为00000,如果PAT有变化则版本号加1
current_next_indicator	    (1bit)	发送的PMT表是当前有效还是下一个PMT有效, 固定为1
section_number	            (8bit)	固定为0x00, PMT可能分为多段传输,第一段为00, 以后每个分段加1, 最多可能有256个分段
last_section_number	        (8bit)	分段数,固定为0x00
reserved	                (3bit)	保留位, 固定为111
PCR_PID	                    (13bit)	PCR(节目参考时钟)所在TS分组的PID,指定为视频PID
reserved	                (4bit)	固定为1111
program_info_length	        (12bit)	节目描述信息,指定为0x000表示没有,2bit为00, 该域指出跟随其后对节目信息的描述的字节数。

开始循环,按顺序可能包含多个	 	 
stream_type	                (8bit)	流类型,标志是Video还是Audio还是其他数据,h.264编码对应0x1b,aac编码对应0x0f,mp3编码对应0x03
reserved	                (3bit)	固定为111
elementary_PID	            (13bit)	与stream_type对应的PID
reserved	                (4bit)	固定为1111
ES_info_length	            (12bit)	描述信息,指定为0x000表示没有
结束循环

reserved_5                  3bit    保留位, 固定为0x07
reserved_6                  4bit    保留位, 固定为0x0F	 	 

CRC32	                    32bit	前面数据的CRC32校验码

adaptation字段的数据结构信息

adaptation字段用在音视频数据不足的时候的数据填充.

adaptation_field_length                 (8bit)    adaption字段的长度(后面的字段不包括当前字段)
discontinuity_indicator                 (1bit)    指示数据流是否存在不连续的情况
randort7_acce55_indicator               (1bit)    指示数据流中是否存在重要的组或关键帧
elementary_stream_priority_indicator    (1bit)    指示数据流的优先级
PCR_flag                                (1bit)    PCR(Programme Clock Reference)字段是否存在
OPCR_flag                               (1bit)    OPCR字段是否存在
splicing_point_flag                     (1bit)    数据流中是否存在插播点 
transport_private_data_flag             (1bit)    是否存在私有数据
adaptation_field_extension_flag         (1bit)    用于指示是否存在ADAPTATION FIELD EXTENSION

//PCR_flag==1 控制TS数据流同步的42位时间戳
program_clock_reference_base            (33bit)
Reserved                                (6bit)
program_clock_reference_extension       (9bit)

//OPCR_flag==1 ( Optional Program Clock Reference)
//用于同步接收到的多个数据流,其在时间戳方面与 PCR 相似,但只在数据流中的某些节目中使用
original_program_clock_reference_base   33bit
Reserved                                6bit
original_program_clock_reference_extension 9bit

//splicing_point_flag==1
splice_countdown                        (8bit)

//transport_private_data_flag==1
transport_private_data_length           (8bit)
for (1=0,i<transport_private_data_length; i++){
        private data byte               (8bit)
}

//adaptation_field_extension_flag==1
adaptation_field_extension_length       (8bit)
Itw_flag                                (1bit)
piecewise_rate_flag                     (1bit)
seamless_splice_flag                    (1bit)
Reserved                                (5bit)
//Itw_flag==1
ltw_valid_flag                          (1bit)    
ltw_offset                              (15bit)

//piecewise_rate_flag ==1
reserved                                (2bit)
piecewise_rate                          (22bit)

//seamless_splice_flag==1
Splice_type                             (4bit)
DTS_next_AU[32..30]                     (3bit)
marker_bit                              (1bit)
DTS_next_AU[29 ..15]                    (15bit)
marker_bit                              (1bit)
DTS_next_AU[14..0]                      (15bit)
marker_bit                              (1bit)
for (i=0;i<N;i++){
reserved                                (8bit)
}

//last
for(i=0i<N;i++){
stuffing_byte                           (8bit)
}

打包TS流时PAT和PMT表是没有Adaptation 字段的,不够的长度直接补0xff即可。视频流和音频流都需要加adaptation field, 通常加在一个帧的第一个ts包和最后一个ts包里,中间的ts包不加。
打包ts文件的时候需要注意, 需要添加PCR时钟, 否则在VLC播放器中播放会失败。无法获取视频的时长。
这里以java实现为例,介绍一下PCR值生成的方法:

void create_adaption_field(AdaptionField  adption_field, long pts, boolean has_pcr)
{
    int index = 0;
    Arrays.fill(adption_field.adaption_buffer,0,adption_field.adaption_buffer.length, (byte) 0xFF);

    if (has_pcr)
    {
        //包含pcr
        long pcrValue = pts * 300;
        long PCR_BSE = pcrValue / 300;
        long PCR_EXT = pcrValue % 300;
        后续可能会更新,7个字节
        adption_field.adaption_buffer[index++] = 0x07; 
        //取0x50表示包含PCR
        adption_field.adaption_buffer[index++] = 0x50; 
        adption_field.adaption_buffer[index++] = (byte)((byte)0xff & (PCR_BSE >> 25)); //PCR_BASE的前8位
        adption_field.adaption_buffer[index++] = (byte)((byte)0xff & (PCR_BSE >> 17)); //PCR_BASE的紧跟8位
        adption_field.adaption_buffer[index++] = (byte)((byte)0xff & (PCR_BSE >> 9));  //PCR_BASE的紧跟8位
        adption_field.adaption_buffer[index++] = (byte)((byte)0xff & (PCR_BSE >> 1));  //PCR_BASE的紧跟8位
        adption_field.adaption_buffer[index++] = (byte)((PCR_BSE <<  7 |  PCR_EXT >> 8 | 0x7e) & 0xFF);
        adption_field.adaption_buffer[index++] = (byte)(0xff & PCR_EXT);

    }
    else
    {
        //不包含pcr
        adption_field.adaption_buffer[index++] = 0x07; //后续可能会更新, 7个字节
        adption_field.adaption_buffer[index++] = 0x00; //0x00都不包含
    }
    adption_field.adaption_field_size = index;
}

PES字段的数据结构

pes层(ts层中payload)是在每一个视频/音频帧上加入了时间戳等信息, pes包内容很多, 我们只留下最常用的。
长度为14(只包含pts)/18(包含pts和dts) 个字节

pes_start_code	    (24bit)        	开始码,固定为0x000001
stream id	        (8bit)	        音频取值(0xc0~0xdf),通常为0xc0,视频取值(0xe0-0xef),通常为0xe0
pes_packet_length	(16bit)	        后面pes数据的长度,0表示长度不限制,只有视频数据长度会超过0xffff
flag	            (8bit)	        是否加密, 通常取值0x80,表示数据不加密、无优先级、备份的数据
flag	            (8bit)          是否包含pts和dts, 取值0x80表示只含有pts,取值0xc0表示含有pts和dts
pes_data_length	    (8bit)        	后面数据的长度,取值510
pts	                (40bit)	        pts显示时间戳
dts	                (40bit)	        dts解码时间戳

pts是显示时间戳、dts是解码时间戳,视频数据两种时间戳都需要, 音频数据的pts和dts相同,所以只需要pts。
有pts和dts两种时间戳是B帧引起的, I帧和P帧的pts等于dts。如果一个视频没有B帧, 则pts永远和dts相同。从文件中顺序读取视频帧, 取出的帧顺序和dts顺序相同。

TS数据流分包策略

这里以一帧AAC音频数据为例说明一下TS封装格式的分包策略, 通常一个TS数据包无法传输一个完整的帧, 需要将一帧音视频数据拆分成多个数据包, 详细策略如下:
1.首先在流里面添加PAT包和PMT包作为流的开始
2.然后添加第一个PES包作为数据包的开始, 包含Adaption、PES。包中包含此帧的长度, 采样率, pts/dts等信息。
3.中间添加拆分的数据PES包, 包中只包含tsheader和音视频数据
4.最后一个数据包,作为结尾包含ts header、Adaption、音视频数据,但不包含PES字段。

对应的结构如下图所示:文章来源地址https://www.toymoban.com/news/detail-757288.html

  +-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
  |  TS   |  =  |  PAT包  |  PMT包 |  PES1  |    ...    | PES n | 
  +-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
  
第一个PES包:            4Byte       8Byte     14Byte(pts)  162Btte
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Packet | =  |    ts header | Adaption |  PES |       paylod |
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

中间的PES包, 只包含tsheader和payload, 不包含adaption和pes
                       4Byte             184Byte
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Packet | =  |    ts header |       payload        |
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

最后一个PES包 包含tsheader、adaption、payload
       4 byte         x byte                    184-x byte
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | ts header |  adaptation field |          payload        |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

到了这里,关于TS视频封装协议详细说明的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 音视频——封装格式原理

    视频解码基础 一、封裝格式 ​ 我们播放的视频文件一般都是用一种 封装格式 封装起来的,封装格式的作用是什么呢?一般视频文件里不光有视频,还有音频,封装格式的作用就是把视频和音频打包起来。 所以我们先要 解封装格式 ,看有哪些视频流和哪些音频流,此时的

    2024年02月15日
    浏览(48)
  • 音视频 ffmpeg命令转封装

    保持编码格式: 改变编码格式: 修改帧率: 修改视频码率: 修改视频码率: 修改音频码率: 修改音视频码率: 修改视频分辨率: 修改音频采样率: 推荐一个零声学院项目课,个人觉得老师讲得不错,分享给大家: 零声白金学习卡(含基础架构/高性能存储/golang云原生/音

    2024年02月10日
    浏览(53)
  • 音视频 ffmpeg命令参数说明

    主要参数: -i 设定输入流 -f 设定输出格式(format) -ss 开始时间 -t 时间长度 音频参数: -aframes 设置要输出的音频帧数 -b:a 音频码率 -ar 设定采样率 -ac 设定声音的Channel数 -acodec 设定声音编解码器,如果用copy表示原始编解码数据必须被拷贝。 -an 不处理音频 -af 音频过滤器 视频

    2024年02月10日
    浏览(51)
  • 音视频基础概念(5)——音频基础说明

    现实生活中,音频(Audio)主要用在两大场景中,包括语音(Voice)和音乐(Music)。语音主要用于沟通,如打电话等。目前由于语音识别技术的发展,人机语音交互也是语音的一个应用方向,很多大厂推出智能音箱、语音助手等。音乐主要用于欣赏和陶冶情操,如播放音乐。

    2023年04月08日
    浏览(106)
  • FFmpeg入门详解之19:音视频封装原理简介

    什么是数据封装和解封装? 数据封装(baiData Encapsulation) ,笼统地讲,就是把业务数据映射到du某个封装协议zhi的净dao荷中,然后填充对应协议的包头,形成封装协议的数据包,并完成速率适配。 解封装 ,就是封装的逆过程,拆解协议包,处理包头中的信息,取出净荷中的业

    2023年04月09日
    浏览(46)
  • 【音视频 | opus】opus编码的Ogg封装文件详解

    😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭 🤣本文内容🤣:🍭介绍 opus 编码的 Ogg 封装文件🍭 😎金句分享😎:🍭🍭 本文未经允许,不得转发!!! opus和Ogg相关系列文章: 1、RFC3533 :Ogg封装格

    2024年02月03日
    浏览(62)
  • Android音视频之协议介绍

    本文对音视频的协议起源做详细介绍,学习之后可以加深对音视频知识的了解。 这里的音视频不仅针对Android平台,其他平台也通用。 一般是指以某种格式封装了音视频数据的文件 常见的音频格式:mp3、wma、avi、rm、rmvb、flv、mpg、mov、mkv等。 常见的视频格式:rmvb、rm、wmv、

    2023年04月19日
    浏览(54)
  • 【音视频开发】FFmpeg转换与封装 I - MP4格式

    1 FFmpeg转换与封装 1.1 MP4格式转换 1.1.1 MP4格式标准         FFmpeg支持的媒体封装格式具有多样性与全面性,与此, 我们还可以使用FFmpeg来对媒体格式进行转换与封装 。 在互联网常见的格式中,跨平台最好的应该是 MP4 文件,因为 MP4 文件既可以在PC 平台的Flashplayer中播放,

    2024年02月08日
    浏览(78)
  • 蓝牙音视频控制协议(AVCTP)介绍

    本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。 第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的

    2024年02月16日
    浏览(38)
  • 音视频开发 RTMP协议发送H.264编码及AAC编码的音视频(C++实现)

    RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系Flash Player和RtmpServer,如 FMS , Red5 , crtmpserver 等。RTMP协议可用于实现直播、点播应用,通过 FMLE(Flash Media Live Encoder) 推送音

    2023年04月08日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包