1、JPEG编码器的基本结构
JPEG编码器(本文只讨论baseline JPEG)的硬件设计主要由7个模块组成:
1)YUV Process主要实现YUV亚采样、8x8 block重排列等功能,是JPEG编码的预处理模块;
2)2D-DCT即二维离散余弦变换,完成空间域到频域的转换;
3)QT&ZigZag是量化和数据重排列,量化精度决定了压缩率,也是图像质量损耗的主要因素;
4)RLE是游程编码,以无损的方式压缩量化产生的大量0;
5)Huffman编码也是无损的,它的主要目的是将高频出现的数据用短码表示,而将低频出现的数据用长码表示,从而在整体上实现数据压缩的效果;
6)JFIF Header是给压缩后的JPEG数据加上包头,从而输出完整的JPEG码流;
7)Register Bank是寄存器控制单元,一般通过控制总线(如AXI lite、APB)连接到系统主控(如CPU)。
2、YUV Process
原始图像需要转换到YUV域并进行sub sample,这里以YUV420举例。JPEG处理一幅图像是按照MCU(Minimum Coded Unit)为滑窗单元,MCU的大小并不固定,跟YUV sub-sample以及算法选择都有关系。
这里以16x16 MCU举例,在进入JPEG encoding之前,还需要把MCU拆分成6个8x8的block,它们的顺序是Y/Y/Y/Y/U/V。
3、2D-DCT
二维离散余弦变换的硬件实现有很多快速算法,这里只是介绍一种比较通用好理解的实现方法,PPA并非最优。
二维离散余弦变换的公式如下图示。为了减少运算次数、节省硬件资源,可以将二维的离散余弦变换拆分成两次一维的离散余弦变换。可以看到,拆分后的两次一维变换具有完全相同的形式和参数。在具体实现中,还可以利用变换的对称性,提取相同系数,从而减少乘法的次数。
2D-DCT以8x8 block作为基本处理单元,第一次DCT先对行进行处理,输出也是8x8的矩阵;第二次DCT再对列进行处理,输出最终结果的8x8矩阵。
4、QT&Zig-Zag
所谓量化,就是拿2D-DCT的结果去除以一个系数。一个8x8 block内的每一个元素要除的系数都不相同,所以这些系数也组成了一张8x8的矩阵(量化表,即QT)。此外,Y和UV的量化策略是不同的,所以一共有两张QT表。下图是标准QT表。
对QT表进行调整即可改变压缩率,那么QT表如何调整呢?答案是下面的公式:
Q0(u,v)即标准QT表中的值,QF(Quality Factor)是质量因子,代表图像质量的好坏,QF越大,Q(u,v)越小,数据被量化后保留的细节也就越多,图像质量越高。当QF=100时,Q(u,v) = 1,理论上就是无损量化。
在硬件实现中,乘法比除法消耗更少的资源,所以实际使用的是QT的倒数表(取倒数后左移取整),量化计算就变成乘法了。
2D-DCT得到的是8x8 block的频率信息,从左上到右下,频率逐渐升高,其中左上第一个数值是该block的DC分量。量化后高频区域会产生大量的0,如果还按照Z字形扫描,就不利于把这些0集中在一起,后面RLE模块就不能发挥最大价值。所以我们按照频率递增的方向将量化后的数据进行Zig-Zag重排,从而将尽可能多的0集中在一起。
5、RLE
RLE(Run Length Encoding)即游程编码,其原理很简单,就是把连续的0用NUM标记,从而压缩数据体积。
下面解释一下RLE的具体规则:
1)block的第一个数据为DC,其余63个数据是AC;
2)DC采用的是差值编码,即ΔDn = Dn – Dn-1,注意,Y/U/V有他们各自的ΔDn,不能混在一起;
3)AC采用游程编码,分为两部分(NUM, VALUE),NUM表示当前非零值到前一个非零值之间共有几个0,VALUE即当前的非零值;
4)如果两个非零值之间有超过16个0,则用ZRL(15,0)来标记连续16个0,但是要注意,EOB之前的ZRL是无效的,必须删除;
5)如果block的最后一个数据是0,那么从这个0开始一直到前一个非零值之间的所有0,都可以用EOB(0,0)来标记,这也是为什么EOB之前的ZRL是无效的原因。
举个例子:
RLE input:
RLE output:
block-1: (0,88), (0,57), (0,45), (4,23), (1,-30), (0,-16), (2,1), (15,0), (3,5), (0,0)
block-2: (0,-22), (0,95), (5,77), (3,-8), (15,0), (0,2), (0,0)
6、Huffman Encoder
Huffman code的思想是,将数据拆分成一个个符号(Symbol),统计每个符号出现的频率,根据频率构建出二叉树。之后根据二叉树,为每个符号值分配二进制位编码,频率越高,编码越短,频率越低,编码越长,从而实现整体上的数据压缩。
根据其原理不难理解,要想正确解码,除了要保存编码后的二进制位,还需要保存二叉树信息,这样解码器才能知道符号值和编码值的对应关系。假如保存二叉树本身就占太多空间,那么对于少量数据而言,压缩后总数据量反而会更大,这就得不偿失了。所以要利用好Huffman code,最关键的就是如何用尽量少的空间保存二叉树信息。
Baseline JPEG采用的是Canonical Huffman Code(范式霍夫曼编码),所谓范式,即对Huffman code施加某些强制规定,从而能够利用很少的数据便能重构出符号和编码的对应关系。因为规则固定,所以硬件上很容易使用查找表(LUT)的方式来实现Huffman Encoding。下面解释一下JPEG使用的Huffman表,其中,Y和UV各自有两张表,一张是DC表,一张是AC表,这样总共会用到4张表。
表一:DC-0
HT index | 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 |
HT encode | 00 01 02 03 04 05 06 07 08 09 0A 0B |
HT index是一个索引表,包含16 Byte,从左到右依次表示位数为1~16bit的Huffman编码各有几个。比如第一字节是00,表示没有位数为1bit的编码。第二字节是01,表示位数为2bit的编码有一个。第三字节是05,表示位数为3bit的编码有5个,以此类推。Huffman编码本身是二进制递进的,但在跨越index字节的时候需要左移1bit(这是为了保证每个Huffman编码的独特性,否则在解码的时候就找不到边界了),由此我们可以得到下面的Huffman树:
编码bit数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10~16 |
有几个编码 | 0 | 1 | 5 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
Huffman编码 | NULL | 00 | 010 011 100 101 110 | 1110 | 11110 | 111110 | 1111110 | 11111110 | 111111110 | NULL |
HT encode | NULL | 0 | 1 2 3 4 5 | 6 | 7 | 8 | 9 | A | B | NULL |
我们从上表可以看到,由index推导出来的Huffman编码一共有12个,那么HT encode的意义就比较简单了,它表示每个Huffman编码所对应的VALUE(即DC值)占了多少个bit。VALUE本身采用对称分组的二进制编码,对应关系见下表。
L | DC VALUE | Binary Encode |
0 | 0 | NULL |
1 | -1,1 | 0,1 |
2 | -3,-2,2,3 | 00,01,10,11 |
3 | -7,-6,-5,-4,4,5,6,7 | 000,001,010,011,100,101,110,111 |
4 | -15,-14,…,-8,8,…,14,15 | 0000,0001,…,0111,1000,…,1110,1111 |
5 | -31,-30,…,-16,16,…,30,31 | 00000,00001,…,01111,10000,…,11110,11111 |
6 | -63,…,-32,32,…,63 | 000000,…,011111,100000,…,111111 |
7 | -127,…,-64,64,…,127 | 0000000,…,0111111,1000000,…,1111111 |
8 | -255,…-128,128,…,255 | 00000000,…,01111111,10000000,…,11111111 |
9 | -511,…,-256,256,…,511 | 000000000,…,011111111,100000000,…,111111111 |
10 | -1023,…,-512,512,…,1023 | 0000000000,…,0111111111,1000000000,…,1111111111 |
11 | -2047,…,-1024,1024,…,2047 | 00000000000,…,01111111111,10000000000,…,11111111111 |
我们把上面这张表中的DC VALUE取绝对值,很容易看出来,以(2n~2n+1-1)为边界,越小的值所占用编码的位数就越少。这里其实隐含了一个假设,即一幅图中大部分DC VALUE的值都很小(还记得RLE中,DC VALUE实际上存的是前后两个block的Δ值,而相邻的两个block出现亮度跃变的概率是比较低的),所以经过编码后,能有效压缩数据体积。其硬件实现也很简单,正数直接就等于其无符号二进制值,负数的话先取其绝对值,再按位取反即可。
上面介绍了Huffman DC表的含义以及编码规则,那么DC编码的格式是怎样的呢?DC编码由两部分组成:
Len指示Value经编码后的bit length;Value即编码后的DC值。
我们以上一节RLE output的例子来说明DC编码的步骤:
RLE output:
block-1: (0,88), (0,57), (0,45), (4,23), (1,-30), (0,-16), (2,1), (15,0), (3,5), (0,0)
(1)88前面的0可以扔掉,单看88,到二进制码表查到它对应的L=7,编码为1011000;
(2)L=7说明它的bit length为7,我们到Huffman树里面找到HT encode =7对应的Huffman编码为11110;
(3)把它俩拼接起来即最终的DC编码:11110_1011000,总共占用12bit。
表二:AC-0
HT index | 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7D |
HT encode | 01 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 A1 08 23 42 B1 C1 15 52 D1 F0 24 33 62 72 82 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA |
有DC表做铺垫,AC表也就比较好理解了。Index依然表示从1~16bit的Huffman编码各有几个,这里的encode跟DC的就不太一样了,它分为高4bit和低4bit两个部分,我们可以标记为{RRRR,SSSS},高4bit即游程编码里的Run,低4bit表示AC VALUE的Size(即bit length)。
构建Huffman树:
编码bit数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
有几个编码 | 0 | 2 | 1 | 3 | 3 | 2 | 4 | 3 | 5 |
Huffman编码 | NA | 00 01 | 100 | 1010 1011 1100 | 11010 11011 11100 | 111010 111011 | 1111000 1111001 1111010 1111011 | 11111000 11111001 11111010 | 111110110 111110111 111111000 111111001 111111010 |
encode | NA | {0,1} {0,2} | {0,3} | {0,0} {0,4} {1,1} | {0,5} {1,2} {2,1} | {3,1} {4,1} | {0,6} {1,3} {5,1} {6,1} | {0,7} {2,2} {7,1} | {1,4} {3,2} {8,1} {9,1} {A,1} |
编码bit数 | 10 | 11 | 12 | 13 | 14 | 15 |
有几个编码 | 5 | 4 | 4 | 0 | 0 | 1 |
Huffman编码 | 1111110110 1111110111 1111111000 1111111001 1111111010 | 11111110110 11111110111 11111111000 11111111001 | 111111110100 111111110101 111111110110 111111110111 | NA | NA | 111111111000000 |
encode | {0,8} {2,3} {4,2} {B,1} {C,1} | {1,5} {5,2} {D,1} {F,0} | {2,4} {3,3} {6,2} {7,2} | NA | NA | {8,2} |
编码bit数 | 16 |
有几个编码 | 125 |
Huffman编码 | 1111111110000010 1111111110000011 1111111110000100 … … 1111111111111100 1111111111111101 1111111111111110 |
encode | {0,9} {0,A} {1,6} … … {F,8} {F,9} {F,A} |
AC VALUE跟DC使用的是一模一样的二进制编码规则,这里就不再赘述了。
AC的编码也是分为两部分:
还是通过举例来说明:
RLE output:
block-1: (0,88), (0,57), (0,45), (4,23), (1,-30),(0,-16), (2,1), (15,0), (3,5), (0,0)
我们取其中4组数据进行AC编码。
Example-1:(0,-16)
(1) 首先根据VALUE=-16,查到其二进制编码为01111,bit length = 5(Size);
(2) Run=0,跟Size一起组成8bit encode = {0,5},在Huffman树中查到其Huffman编码为11010;
(3) 把它俩拼接起来即最终的AC编码:11010_01111,占用10bit。
Example-2: (2,1)
(1) 首先根据VALUE=1,查到其二进制编码为1,bit length = 1(Size);
(2) Run=2,跟Size一起组成8bit encode = {2,1},在Huffman树中查到其Huffman编码为11100;
(3) 把它俩拼接起来即最终的AC编码:11100_1,占用6bit。
Example-3: (15,0)
(1) 首先根据VALUE=0,查到其二进制编码为NULL,bit length = 0(Size);
(2) Run=15,跟Size一起组成8bit encode = {F,0},在Huffman树中查到其Huffman编码为11111111001;
(3) 因为VALUE不占用bit,所以无需拼接,AC编码即:11111111001,占用11bit;
(4) RLE小节有讲到,(15,0)是一种特殊数据,标记为ZRL。
Example-4: (0,0)
(1) 首先根据VALUE=0,查到其二进制编码为NULL,bit length = 0(Size);
(2) Run=0,跟Size一起组成8bit encode = {0,0},在Huffman树中查到其Huffman编码为1010;
(3) 因为VALUE不占用bit,所以无需拼接,AC编码即:1010,占用4bit;RLE小节有讲到,(0,0)也是一种特殊数据,标记为EOB。
表三:DC-1
HT index | 00 03 01 01 01 01 01 01 01 01 01 00 00 00 00 00 |
HT encode | 00 01 02 03 04 05 06 07 08 09 0A 0B |
跟表一的逻辑是一样的,这里只列出推导出来的Huffman树:
编码bit数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
有几个编码 | 0 | 3 | 1 | 1 | 1 | 1 | 1 |
Huffman编码 | NULL | 00 01 10 | 110 | 1110 | 11110 | 111110 | 1111110 |
HT encode | NULL | 0 1 2 | 3 | 4 | 5 | 6 | 7 |
编码bit数 | 8 | 9 | 10 | 11 | 12~16 |
有几个编码 | 1 | 1 | 1 | 1 | 0 |
Huffman编码 | 11111110 | 111111110 | 1111111110 | 11111111110 | NULL |
HT encode | 8 | 9 | A | B | NULL |
表四:AC-1
HT index | 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 |
HT encode | 00 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 22 32 81 08 14 42 91 A1 B1 C1 09 23 33 52 F0 15 62 72 D1 0A 16 24 34 E1 25 F1 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 F7 F8 F9 FA |
跟表二的逻辑是一样的,这里只列出推导出来的Huffman树:
编码bit数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
有几个编码 | 0 | 2 | 1 | 2 | 4 | 4 | 3 | 4 | 7 |
Huffman编码 | NA | 00 01 | 100 | 1010 1011 | 11000 11001 11010 11011 | 111000 111001 111010 111011 | 1111000 1111001 1111010 | 11110110 11110111 11111000 11111001 | 111110100 111110101 111110110 111110111 111111000 111111001 111111010 |
encode | NA | {0,0} {0,1} | {0,2} | {0,3} {1,1} | {0,4} {0,5} {2,1} {3,1} | {0,6} {1,2} {4,1} {5,1} | {0,7} {6,1} {7,1} | {1,3} {2,2} {3,2} {8,1} | {0,8} {1,4} {4,2} {9,1} {A,1} {B,1} {C,1} |
编码bit数 | 10 | 11 | 12 | 13 | 14 |
有几个编码 | 5 | 4 | 4 | 0 | 1 |
Huffman编码 | 1111110110 1111110111 1111111000 1111111001 1111111010 | 11111110110 11111110111 11111111000 11111111001 | 111111110100 111111110101 111111110110 111111110111 | NULL | 11111111100000 |
encode | {0,9} {2,3} {3,3} {5,2} {F,0} | {1,5} {6,2} {7,2} {D,1} | {0,A} {1,6} {2,4} {3,4} | NULL | {E,1} |
编码bit数 | 15 | 16 |
有几个编码 | 2 | 119 |
Huffman编码 | 111111111000010 111111111000011 | 1111111110001000 1111111110001001 … … 1111111111111101 1111111111111110 |
encode | {2,5} {F,1} | {1,7} {1,8} … … {F,9} {F,A} |
(注:Y使用表一和表二,U/V使用表三和表四)
在Huffman Encoding之后,还需要做以下操作:
(1) huffman输出的可变长编码,需要做移位拼接处理,从而满足硬件接口位宽的要求;
(2) 在一幅图像的最后,比特位凑不够硬件接口位宽的部分,用1补齐;
(3)数据中如果出现0xFF,需要替换成0xFF00,从而避免跟控制字符的混淆;
(4) 在图像数据结尾处添加FFD9,用于标识EOI(End Of Image)。
7、JFIF Header
JFIF Header是事先存在register bank里的,在输出JPEG数据流时,拼接到图像数据前面。一个典型的JFIF Header包含下表中列出的信息。
Address | Field | Content | Note |
0 | SOI marker | FF D8 | Start of image |
2 | JFIF APP0 maker | FF E0 | Indicates this is a JPEG file using JFIF specification |
4 | Length | 00 10 | APP0 info length, fixed 16 |
6 | JFIF ASCII | 4A 46 49 46 00 | “JFIF” + 00h |
11 | Major version | 01 | |
12 | Minor version | 01 | |
13 | Density unit | 00 | DPI. 00 means N/A |
14 | X density | 00 01 | N/A |
16 | Y density | 00 01 | N/A |
18 | Thumbnail | 00 00 | N/A |
20 | DQT marker | FF DB | |
22 | Length | 00 43 | DQT info length, fixed 67 |
24 | QT info | 00 | Lower 4bit: QT NO. = 0 Higher 4bit: QT precision is 8bit |
25 | QT content | 10 0B 0C 0E 0C 0A 10 0E 0D 0E 12 11 10 13 18 28 1A 18 16 16 18 31 23 25 1D 28 3A 33 3D 3C 39 33 38 37 40 48 5C 4E 40 44 57 45 37 38 50 6D 51 57 5F 62 67 68 67 3E 4D 71 79 70 64 78 5C 65 67 63 | QT value in zig-zag sequence Write different QT to control the compression ratio. |
89 | DQT marker | FF DB | |
91 | Length | 00 43 | DQT info length, fixed 67 |
93 | QT info | 01 | Lower 4bit: QT NO. = 1 Higher 4bit: QT precision is 8bit |
94 | QT content | 11 12 12 18 15 18 2F 1A 1A 2F 63 42 38 42 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 | QT value in zig-zag sequence Write different QT to control the compression ratio. |
158 | SOF marker | FF C0 | SOF0: Baseline DCT |
160 | Length | 00 11 | SOF0 info length, fixed 17 |
162 | Pixel depth | 08 | 8bit |
163 | Image height | 00 F0 | The same as original YUV input image resolution |
165 | Image width | 01 40 | The same as original YUV input image resolution |
167 | Number of component | 03 | YUV |
168 | Y info | 01 21 00 | Sample = 2(H)/2(V), DQT-0 |
171 | U info | 02 11 01 | Sample = 1(H)/2(V), DQT-1 |
174 | V info | 03 11 01 | Sample = 1(H)/2(V), DQT-1 |
177 | DHT marker | FF C4 | Define Huffman table |
179 | Length | 00 1F | DHT info length, fixed 31 |
181 | HT type | 00 | DC-0 table |
182 | HT index | 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 | |
198 | HT encode | 00 01 02 03 04 05 06 07 08 09 0A 0B | |
210 | DHT marker | FF C4 | Define Huffman table |
212 | Length | 00 B5 | DHT info length, fixed 181 |
214 | HT type | 10 | AC-0 table |
215 | HT index | 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7D | |
231 | HT encode | 01 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 A1 08 23 42 B1 C1 15 52 D1 F0 24 33 62 72 82 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA | |
393 | DHT marker | FF C4 | Define Huffman table |
395 | Length | 00 1F | DHT info length, fixed 31 |
397 | HT type | 01 | DC-1 table |
398 | HT index | 00 03 01 01 01 01 01 01 01 01 01 00 00 00 00 00 | |
414 | HT encode | 00 01 02 03 04 05 06 07 08 09 0A 0B | |
426 | DHT marker | FF C4 | Define Huffman table |
428 | Length | 00 B5 | DHT info length, fixed 181 |
430 | HT type | 11 | AC-1 table |
431 | HT index | 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 | |
447 | HT encode | 00 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 22 32 81 08 14 42 91 A1 B1 C1 09 23 33 52 F0 15 62 72 D1 0A 16 24 34 E1 25 F1 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 F7 F8 F9 FA | |
609 | SOS marker | FF DA | Start of scan |
611 | Length | 00 0C | SOS info length, fixed 12 |
613 | Number of component | 03 | YUV |
614 | Y info | 01 00 | 01 – Y 00 – HT DC-0/AC-0 |
616 | U info | 02 11 | 02 – U 11 – HT DC-1/AC-1 |
618 | V info | 03 11 | 03 – V 11 – HT DC-1/AC-1 |
620 | Payload marker | 00 3F 00 | Indicates the following data is payload |