AV1-syntax-explanation

0x1 解码流程介绍


解码流程说明如下

0x11 tile_group_obu

对tile group的每个tile调用decode_tile()进行解码,直至tile group中包括的tile都解码完成.

1
2
3
4
5
6
7
for ( TileNum = tg_start; TileNum <= tg_end; TileNum++ ) {
tileRow = TileNum / TileCols
tileCol = TileNum % TileCols
......
decode_tile( )
exit_symbol( )
}

0x12 decode_tile

对tile中包含的每个partition进行解码。

1
2
3
4
5
6
for ( r = MiRowStart; r < MiRowEnd; r += sbSize4 ) {
for ( c = MiColStart; c < MiColEnd; c += sbSize4 ) {
......
decode_partition( r, c, sbSize )
}
}

0x13 decode_partition

每个partition的解码过程就是对一个super block(super block的定义参考0x2)进行解码的过程.
根据partition类型对进一步split, 不能split的类型调用decode_block().

partition类型的定义如下

| Partition index | Type of partition  |
|:-------:|:------------- |
| 0 |PARTITION_NONE|
| 1 |PARTITION_HORZ|
| 2 |PARTITION_VERT|
| 3 |PARTITION_SPLIT|
| 4 |PARTITION_HORZ_A|
| 5 |PARTITION_HORZ_B|
| 6 |PARTITION_VERT_A|
| 7 |PARTITION_VERT_B|
| 8 |PARTITION_HORZ_4|
| 9 |PARTITION_VERT_4|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
if ( partition == PARTITION_NONE ) {
decode_block( r, c, subSize )
} else if ( partition == PARTITION_HORZ ) {
decode_block( r, c, subSize )
if ( hasRows )
decode_block( r + halfBlock4x4, c, subSize )
} else if ( partition == PARTITION_VERT ) {
decode_block( r, c, subSize )
if ( hasCols )
decode_block( r, c + halfBlock4x4, subSize )
} else if ( partition == PARTITION_SPLIT ) {
decode_partition( r, c, subSize )
decode_partition( r, c + halfBlock4x4, subSize )
decode_partition( r + halfBlock4x4, c, subSize )
decode_partition( r + halfBlock4x4, c + halfBlock4x4, subSize )
} else if ( partition == PARTITION_HORZ_A ) {
decode_block( r, c, splitSize )
decode_block( r, c + halfBlock4x4, splitSize )
decode_block( r + halfBlock4x4, c, subSize )
} else if ( partition == PARTITION_HORZ_B ) {
decode_block( r, c, subSize )
decode_block( r + halfBlock4x4, c, splitSize )
decode_block( r + halfBlock4x4, c + halfBlock4x4, splitSize )
} else if ( partition == PARTITION_VERT_A ) {
decode_block( r, c, splitSize )
decode_block( r + halfBlock4x4, c, splitSize )
decode_block( r, c + halfBlock4x4, subSize )
} else if ( partition == PARTITION_VERT_B ) {
decode_block( r, c, subSize )
decode_block( r, c + halfBlock4x4, splitSize )
decode_block( r + halfBlock4x4, c + halfBlock4x4, splitSize )
} else if ( partition == PARTITION_HORZ_4 ) {
decode_block( r + quarterBlock4x4 * 0, c, subSize )
decode_block( r + quarterBlock4x4 * 1, c, subSize )
decode_block( r + quarterBlock4x4 * 2, c, subSize )
if ( r + quarterBlock4x4 * 3 < MiRows )
decode_block( r + quarterBlock4x4 * 3, c, subSize )
} else { //PARTITION_VERT_4
decode_block( r, c + quarterBlock4x4 * 0, subSize )
decode_block( r, c + quarterBlock4x4 * 1, subSize )
decode_block( r, c + quarterBlock4x4 * 2, subSize )
if ( c + quarterBlock4x4 * 3 < MiCols )
decode_block( r, c + quarterBlock4x4 * 3, subSize )
}

0x14 decode_block

对一个block进行解码,进一步调用residual对残差进行解码.

0x15 transform_tree

对不同size的transform块进行解码,它是一个递归函数,递归退出函数是transform_block.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
transform_tree( startX, startY, w, h ) { Type
maxX = MiCols * MI_SIZE
maxY = MiRows * MI_SIZE
if ( startX >= maxX || startY >= maxY ) {
return
}
row = startY >> MI_SIZE_LOG2
col = startX >> MI_SIZE_LOG2
lumaTxSz = InterTxSizes[ row ][ col ]
lumaW = Tx_Width[ lumaTxSz ]
lumaH = Tx_Height[ lumaTxSz ]
if ( w <= lumaW && h <= lumaH ) {
txSz = find_tx_size( w, h )
transform_block( 0, startX, startY, txSz, 0, 0 )
} else {
if ( w > h ) {
transform_tree( startX, startY, w/2, h )
transform_tree( startX + w / 2, startY, w/2, h )
} else if ( w < h ) {
transform_tree( startX, startY, w, h/2 )
transform_tree( startX, startY + h/2, w, h/2 )
} else {
transform_tree( startX, startY, w/2, h/2 )
transform_tree( startX + w/2, startY, w/2, h/2 )
transform_tree( startX, startY + h/2, w/2, h/2 )
transform_tree( startX + w/2, startY + h/2, w/2, h/2 )
}
}
}

0x16 Reconstruct中包括具体的反量化,反dct,重建像素和loop filter等过程.

0x2 super block

下图说明了一个frame由许多super block组成,super block的定义稍后说明.

Super block的定义如下
The top level of the block quadtree within a tile. All superblocks within a frame are the same size and are square. The
superblocks may be 128x128 luma samples or 64x64 luma samples. A superblock may contain 1 or 2 or 4 mode info
blocks, or may be bisected in each direction to create 4 sub-blocks, which may themselves be further subpartitioned,
forming the block quadtree.

通过在sequence_header_obu中的use_128x128_superblock来控制superblock的大小是128x128还是64x64.
sequence_header_obu( ) {
……
use_128x128_superblock f(1)
……
}

use_128x128_superblock的定义如下
when equal to 1, indicates that superblocks contain 128x128 luma samples. When equal to 0,
it indicates that superblocks contain 64x64 luma samples.

0x3 split划分

下图显示了super block(64x64)的split状态, 从图中可以看到,64x64的block会被split到32x32,再进一步split到16x16.

0x4 Intra Y mode

下图显示了Intra Prediction中Y分量的mode,不同的颜色代码不同的mode.

0x5 Intra UV mode

下图显示了Intra Prediction中UV分量的mode,不同的颜色代码不同的mode,其中显示数字的块表示该mode为chroma from luma prediction, 其中显示的数字表示chroma需要从哪个位置的luma预测.

0x6 Motion vector

下图显示了Inter frame帧间预测的运动向量.

0x7 Reference

AV1 analyzer