ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BAT表、链接描述符、文件内容与CRC32/MPEG-2校验

2021-01-29 10:57:25  阅读:219  来源: 互联网

标签:BAT MPEG 字节 00 TS 寄存器 CRC32


BAT表、链接描述符、文件内容与CRC32/MPEG-2校验

0. 前言

这些笔记是几年前学习TS流解析和解复用的时候写的,现在整理出来记录一下。

当时的目标有如下两个:

  1. 解析接受到的TS流
  2. 从TS流中提取BAT表等数据,并解析具体内容。

1. TS包分析

需要解析TS流,先要解析接受到的每个TS包。

1.1 TS包结构

一个TS包由包头和包数据组成,总长度一般为188字节(也可能是204字节)。

包头一般为4字节左右,包含这个TS包的各种信息,剩余的是TS包数据。在数据中,可能会存在调整字节(非有效负载)。

1.2 TS包头和数据分析

TS包头由4字节组成,结构定义如下(C):

// Transport packet header
typedef struct TS_packet_header
{
    unsigned sync_byte                        : 8;
    unsigned transport_error_indicator        : 1;
    unsigned payload_unit_start_indicator    : 1;
    unsigned transport_priority                : 1;
    unsigned PID                            : 13;
    unsigned transport_scrambling_control    : 2;
    unsigned adaption_field_control            : 2;
    unsigned continuity_counter                : 4;
} TS_packet_header;

解析:

数据长度数据含义
sync_byte8bit同步字节,一般是0x47
transport_error_indicator1bit该位值为1时,表示在相关的传送包中至少有一个不可纠正的错误,只有在错误纠正之后,该位才能被重新置0。
payload_unit_start_indicator1bit该字段用来表示TS包的有效净荷有PES包或者PSI数据的情况。payload_unit_start_indicator为1时,在前4个字节之后会有一个调整字节,它的数值决定了负载内容的具体开始位置。例如:47 40 00 17 00第五个字节是00,说明紧跟着00之后就是具体的负载内容(有效负载)。
transport_priority1bit传输优先级,1为高优先级
PID12bitPacket ID号码,唯一的号码对应不同的包
transport_scrambling_control2bit加密标志(00:未加密;其他表示已加密)
adaptation_field_control2bit表示传送流包首部是否跟随有调整字段。01仅含有效负载,10仅含调整字段,11含有调整字段和有效负载。为00的话解码器不进行处理。
continuity_counter4bit范围0-15,具有相同的PID的TS分组传输时每次加1,到15后清0。不过,有些情况下是不计数的。如下:(1)TS分组无有效负载。(2)复制的TS分组和原分组这个值一样。(3)标志discontinuity_indicator为1时。

参考:

http://www.cnblogs.com/shakin/p/3714848.html
http://www.cnblogs.com/jiangzhaowei/p/3625944.html

TS流调整参考:http://blog.csdn.net/cabbage2008/article/details/49837143
较详细的数据结构:http://blog.csdn.net/a31898534/article/details/4399353

可用以下代码结合上文协同了解(http://blog.csdn.net/a31898534/article/details/4399353 )。

transport_packet() {
	sync_byte                                                                    // 8
	transport_error_indicator                                          //1
	payload_unit_start_indicator                                    //1
	transport_priority                                                       // 1
	PID                                                                             //13
	transport_scrambling_control                                  // 2
	adaptation_field_control                                            //2
	continuity_counter                                                      //4
	if(adaptation_field_control=='10'  || adaptation_field_control=='11') {
		adaptation_field()
	}
	if(adaptation_field_control=='01' || adaptation_field_control=='11') {
		for (i=0; i<N; i++) {
			data_byte                                                                   //8
		}
	}
}

2. BAT表语法解析

2.1 BAT表简介

BAT表的一个片段如下(包含表头,不含TS包的同步字节内容)

PositionHexText
00004a f2 ed 70 11 ff 00 00 f2 e0 47 08 64 61 74 61 63 61J…p…G.dataca
001273 74 4a f5 00 01 00 01 a0 01 80 02 00 90 5f 00 00 00stJ…_…
002400 01 02 00 02 07 00 03 07 00 04 07 00 05 07 00 06 01
003600 07 01 00 08 01 00 09 01 00 0a 01 00 0b 08 00 0c 08
004800 0d 08 00 0e 08 00 0f 03 00 10 00 00 11 00 00 12 00

2.2 BAT表的语法和解析

BAT表语法如下:

语法表中(只说明几个重要的):

语法长度(Bit)解析
table_id8用于确定表类型,0x4A代表bouquet_association_section
section_syntax_indicator1段语法标志,此处必须是1
section_length12段长,单位Byte
bouquet_id16Bouquet表ID,在数据广播中此处为0x7011
version_number5数据版本号,从0起递增,到1f后归零
current_next_indicator1置于‘1’时指示发送的有条件访问表为当前有效的。该比特设置为‘0’时,它指示发送的有条件访问表尚未有效并且下一个有条件访问表将生效
section_number8(分段传输表时的)本段编号,第一段表编号应为0x00
last_section_number8最后一段编号
descriptor-描述符

|CRC32|4|从表头到数据的最后一字节的CRC32校验,算法使用CRC32/MPEG-2

上图中从最后一个reserved_future_use到最后的CRC32前的大括号均未在此出现

按照上述表格解析例子中的BAT表,得出以下结果(descriptor部分在后文进行分析):

2.3 链接描述符linkage_descriptor

在上文给出的例子中,从0xa开始的内容是链接描述符。

链接描述符的语法如下:

其中值得注意的是:

  • descriptor_tag:在这里有两种descriptor_tag。tag = 0x47是表名,不用注意此段数据。tag = 0x4A才是值得注意的数据。
  • linkage_type:链接类型,在这里是0x80。
  • PID:文件信息所在的PID。
  • table_ext_id:实际上就是文件编号
  • last_section_num:该文件编号对应的文件在传输中的总段数

2.4 解析用途

对BAT表的解析主要是为了了解一下信息:

  1. 文件内容所在的PID
  2. 文件总数和每个文件总段数。

3. CRC32/MPEG2校验

3.1 CRC32/MPEG2参数模型

该校验的参数模型如下:

其中各参数定义:

  • NAME:名称

  • WIDTH:宽度,即CRC比特数

  • POLY:生成项的简写。以16进制表示,即是0x04C11DB7。忽略了最高位的"1",即完整的生成项是0x104C11DB7。重要的一点是,这是“未颠倒”的生成项!前面说过,“颠倒的”生成项是0xEDB88320。

  • INIT:这是算法开始时寄存器的初始化预置值,十六进制表示。这个值可以直接赋值给“直驱表法”算法中的寄存器,作为寄存器的初始值!
    而对于“驱动表法”算法及“直接计算法”,寄存器的初始值必须是0!前面几次循环先将待测数据移入到寄存器中,当寄存器装满后,再用这个初始化预置值去XOR寄存器,这样寄存器就被这个值初始化了!
    这点很重要!!如果在“驱动表法”算法开始时,寄存器的初始值不为0,那么寄存器中的值就会相当于是待测数据了,这样算出的CRC结果就不对了!我们的目的是用预置值去初始化寄存器,而不是将预置值作为待测数据去处理!

  • REFIN 这个值是真TRUE或假FALSE。
    如果这个值是FALSE,表示待测数据的每个字节都不用“颠倒”,即BIT7仍是作为最高位,BIT0作为最低位。
    如果这个值是TRUE,表示待测数据的每个字节都要先“颠倒”,即BIT7作为最低位,BIT0作为最高位。

  • REFOUT:这个值是真TRUE或假FALSE。
    如果这个值是FALSE,表示计算结束后,寄存器中的值直接进入XOROUT处理即可。
    如果这个值是TRUE,表示计算结束后,寄存器中的值要先“颠倒”,再进入XOROUT处理。注意,这是将整个寄存器的值颠倒,因为寄存器的各个字节合起来表达了一个值,如果只是对各个字节各自颠倒,那结果值就错误了。

  • XOROUT:这是W位长的16进制数值。
    这个值与经REFOUT后的寄存器的值相XOR,得到的值就是最终正式的CRC值!

参考:http://www.360doc.com/content/14/0513/22/7991404_377367845.shtml

3.2 CRC32/MPEG2校验的Java实现

算法的实现使用CRC32表的方式,整体代码如下:

public class TsCRC32Utils {

    static final long[] CrcTable = {
        0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
        0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
        0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
        0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
        0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
        0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
        0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
        0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
        0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
        0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
        0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
        0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
        0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
        0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
        0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
        0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
        0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
        0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
        0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
        0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
        0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
        0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
        0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
        0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
        0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
        0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
        0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
        0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
        0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
        0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
        0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
        0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
        0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
        0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
        0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
        0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
        0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
        0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
        0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
        0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
        0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
        0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
        0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
    };

    public static int CRC32(byte[] indata) {
        int i;
        int crc = 0xFFFFFFFF;

        for(i = 0; i < indata.length; i++)
            crc = (int) ((crc << 8) ^ CrcTable[(int) (((crc >> 24) ^ indata[i]) & 0xFF)]);
        return crc;
    }
}

4. ABS文件内容的获取

ABS文件内容所在的PID可通过分析BAT表来读取。

此处的PID为0x200。

4.1 语法分析


先放一段例子进行分析:

000005c0h: 90 B6 3E 0E 4F FF 00 00 0F 32 32 38 5F 32 33 34 ; 惗>.O...228_234
000005d0h: 5F 30 30 37 2E 78 6D 6C 00 00 06 21 3C 3F 78 6D ; _007.xml...!<?xm
000005e0h: 6C 20 76 65 72 73 69 6F 6E 3D 22 31 2E 30 22 20 ; l version="1.0" 

table_id:此处必定是0x90。
section_syntax_indicator:必须是1。
section_length:本段长度(Byte)。
table_id_ext:文件编号(和BAT表里的保持一致)
section_number:当前段编号
last_section_number:最后一段编号,和BAT表里的信息一致
file_data_length:文件长度(注意:这里的文件长度是指本段的长度)

4.2 注意事项

  1. 实际使用时必须使用CRC32/MPEG-2校验接收到的数据。
  2. 注意判断文件是否接收完成。
  3. 注意内存的使用情况。

标签:BAT,MPEG,字节,00,TS,寄存器,CRC32
来源: https://blog.csdn.net/u010034969/article/details/113372139

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有