当前位置:   article > 正文

《AV1 Bitstream & Decoding Process Specification》,译名:AV1比特流及解码规范-Chapter 05-语法结构-Section 11~12_av1 语法文档

av1 语法文档

Table of Contents

5.11 Tile组OBU语法

5.11.1 tile_group_obu语法

5.11.2 decode_tile语法

5.11.3 clear_block_decoded_flags函数

5.11.4 decode_partition语法

5.11.5 decode_block语法

5.11.6 mode_info语法

5.11.7 intra_frame_mode_info语法

5.11.8 intra_segment_id语法

5.11.9 read_segment_id语法

5.11.10 read_skip_mode语法

5.11.11 read_skip语法

5.11.12 read_delta_qindex语法

5.11.13 read_delta_lf语法

5.11.14 seg_feature_active_idx函数

5.11.15 read_tx_size语法

5.11.16 read_block_tx_size语法

5.11.17 read_var_tx_size语法

5.11.18 inter_frame_mode_info语法

5.11.19 inter_segment_id语法

5.11.20 read_is_inter语法

5.11.21 get_segment_id函数

5.11.22 intra_block_mode_info语法

5.11.23 inter_block_mode_info语法

5.11.24 filter_intra_mode_info语法

5.11.25 read_ref_frames语法

5.11.26 assign_mv语法

5.11.27 read_motion_mode语法

5.11.28 read_interintra_mode语法

5.11.29 read_compound_type语法

5.11.30 get_mode函数

5.11.31 read_mv语法

5.11.32 read_mv_component语法

5.11.33 compute_prediction语法

5.11.34 residual语法

5.11.35 transform_block语法

5.11.36 transform_tree语法

5.11.37 get_tx_size函数

5.11.38 get_plane_residual_size函数

5.11.39 coeffs语法

5.11.40 compute_tx_type函数

5.11.41 get_mrow_scan函数

5.11.42 intra_angle_info_y语法

5.11.43 intra_angle_info_uv语法

5.11.44 is_directional_mode语法

5.11.45 read_cfl_alphas语法

5.11.46 palette_mode_info语法

5.11.47 transform_type语法

5.11.48 get_tx_set语法

5.11.49 palette_tokens语法

5.11.50 get_palette_color_context函数

5.11.51 is_inside函数

5.11.52 is_inside_filter_region函数

5.11.53 clamp_mv_row函数

5.11.54 clamp_mv_col函数

5.11.55 clear_cdef函数

5.11.56 read_cdef语法

5.11.57 read_Ir语法

5.11.58 read_lr_unit语法

5.12 Tile列表OBU语法

5.12.1 tile_list_obu语法

5.12.2 tile_list_entry语法


5.11 Tile组OBU语法

5.11.1 tile_group_obu语法

  1. tile_group_obu( sz )
  2. {
  3. NumTiles = TileCols * TileRows
  4. startBitPos = get_position( )
  5. tile_start_and_end_present_flag = 0
  6. if ( NumTiles > 1 )
  7. tile_start_and_end_present_flag // Type f(1)
  8. if ( NumTiles == 1 || !tile_start_and_end_present_flag )
  9. {
  10. tg_start = 0
  11. tg_end = NumTiles - 1
  12. }
  13. else
  14. {
  15. tileBits = TileColsLog2 + TileRowsLog2
  16. tg_start // Type f(tileBits)
  17. tg_end // Type f(tileBits)
  18. }
  19. byte_alignment( )
  20. endBitPos = get_position( )
  21. headerBytes = (endBitPos - startBitPos) / 8
  22. sz -= headerBytes
  23. for ( TileNum = tg_start; TileNum <= tg_end; TileNum++ )
  24. {
  25. tileRow = TileNum / TileCols
  26. tileCol = TileNum % TileCols
  27. lastTile = TileNum == tg_end
  28. if ( lastTile )
  29. {
  30. tileSize = sz
  31. }
  32. else
  33. {
  34. tile_size_minus_1 // Type le(TileSizeBytes)
  35. tileSize = tile_size_minus_1 + 1
  36. sz -= tileSize + TileSizeBytes
  37. }
  38. MiRowStart = MiRowStarts[ tileRow ]
  39. MiRowEnd = MiRowStarts[ tileRow + 1 ]
  40. MiColStart = MiColStarts[ tileCol ]
  41. MiColEnd = MiColStarts[ tileCol + 1 ]
  42. CurrentQIndex = base_q_idx
  43. init_symbol( tileSize )
  44. decode_tile( )
  45. exit_symbol( )
  46. }
  47. if ( tg_end == NumTiles - 1 )
  48. {
  49. if ( !disable_frame_end_update_cdf )
  50. {
  51. frame_end_update_cdf( )
  52. }
  53. decode_frame_wrapup( )
  54. SeenFrameHeader = 0
  55. }
  56. }

5.11.2 decode_tile语法

  1. decode_tile( )
  2. {
  3. clear_above_context( )
  4. for ( i = 0; i < FRAME_LF_COUNT; i++ )
  5. DeltaLF[ i ] = 0
  6. for ( plane = 0; plane < NumPlanes; plane++ )
  7. {
  8. for ( pass = 0; pass < 2; pass++ )
  9. {
  10. RefSgrXqd[ plane ][ pass ] = Sgrproj_Xqd_Mid[ pass ]
  11. for ( i = 0; i < WIENER_COEFFS; i++ )
  12. {
  13. RefLrWiener[ plane ][ pass ][ i ] = Wiener_Taps_Mid[ i ]
  14. }
  15. }
  16. }
  17. sbSize = use_128x128_superblock ? BLOCK_128X128 : BLOCK_64X64
  18. sbSize4 = Num_4x4_Blocks_Wide[ sbSize ]
  19. for ( r = MiRowStart; r < MiRowEnd; r += sbSize4 )
  20. {
  21. clear_left_context( )
  22. for ( c = MiColStart; c < MiColEnd; c += sbSize4 )
  23. {
  24. ReadDeltas = delta_q_present
  25. clear_cdef( r, c )
  26. clear_block_decoded_flags( r, c, sbSize4 )
  27. read_lr( r, c, sbSize )
  28. decode_partition( r, c, sbSize )
  29. }
  30. }
  31. }

其中的常量查找表Sgrproj_Xqd_Mid和Wiener_Taps_Mid定义如下,

  1. Wiener_Taps_Mid[3] = { 3, -7, 15 }
  2. Sgrproj_Xqd_Mid[2] = { -32, 31 }

5.11.3 clear_block_decoded_flags函数

  1. clear_block_decoded_flags( r, c, sbSize4 )
  2. {
  3. for ( plane = 0; plane < NumPlanes; plane++ )
  4. {
  5. subX = (plane > 0) ? subsampling_x : 0
  6. subY = (plane > 0) ? subsampling_y : 0
  7. sbWidth4 = ( MiColEnd - c ) >> subX
  8. sbHeight4 = ( MiRowEnd - r ) >> subY
  9. for ( y = -1; y <= ( sbSize4 >> subY ); y++ )
  10. for ( x = -1; x <= ( sbSize4 >> subX ); x++ )
  11. {
  12. if ( y < 0 && x < sbWidth4 )
  13. BlockDecoded[ plane ][ y ][ x ] = 1
  14. else if ( x < 0 && y < sbHeight4 )
  15. BlockDecoded[ plane ][ y ][ x ] = 1
  16. else
  17. BlockDecoded[ plane ][ y ][ x ] = 0
  18. }
  19. BlockDecoded[ plane ][ sbSize4 >> subY ][ -1 ] = 0
  20. }
  21. }

5.11.4 decode_partition语法

  1. decode_partition( r, c, bSize )
  2. {
  3. if ( r >= MiRows || c >= MiCols )
  4. return 0
  5. AvailU = is_inside( r - 1, c )
  6. AvailL = is_inside( r, c - 1 )
  7. num4x4 = Num_4x4_Blocks_Wide[ bSize ]
  8. halfBlock4x4 = num4x4 >> 1
  9. quarterBlock4x4 = halfBlock4x4 >> 1
  10. hasRows = ( r + halfBlock4x4 ) < MiRows
  11. hasCols = ( c + halfBlock4x4 ) < MiCols
  12. if ( bSize < BLOCK_8X8 )
  13. {
  14. partition = PARTITION_NONE
  15. }
  16. else if ( hasRows && hasCols )
  17. {
  18. partition // Type S()
  19. }
  20. else if ( hasCols )
  21. {
  22. split_or_horz // Type S()
  23. partition = split_or_horz ? PARTITION_SPLIT : PARTITION_HORZ
  24. }
  25. else if ( hasRows )
  26. {
  27. split_or_vert // Type S()
  28. partition = split_or_vert ? PARTITION_SPLIT : PARTITION_VERT
  29. }
  30. else
  31. {
  32. partition = PARTITION_SPLIT
  33. }
  34. subSize = Partition_Subsize[ partition ][ bSize ]
  35. splitSize = Partition_Subsize[ PARTITION_SPLIT ][ bSize ]
  36. if ( partition == PARTITION_NONE )
  37. {
  38. decode_block( r, c, subSize )
  39. }
  40. else if ( partition == PARTITION_HORZ )
  41. {
  42. decode_block( r, c, subSize )
  43. if ( hasRows )
  44. decode_block( r + halfBlock4x4, c, subSize )
  45. }
  46. else if ( partition == PARTITION_VERT )
  47. {
  48. decode_block( r, c, subSize )
  49. if ( hasCols )
  50. decode_block( r, c + halfBlock4x4, subSize )
  51. }
  52. else if ( partition == PARTITION_SPLIT )
  53. {
  54. decode_partition( r, c, subSize )
  55. decode_partition( r, c + halfBlock4x4, subSize )
  56. decode_partition( r + halfBlock4x4, c, subSize )
  57. decode_partition( r + halfBlock4x4, c + halfBlock4x4, subSize )
  58. }
  59. else if ( partition == PARTITION_HORZ_A )
  60. {
  61. decode_block( r, c, splitSize )
  62. decode_block( r, c + halfBlock4x4, splitSize )
  63. decode_block( r + halfBlock4x4, c, subSize )
  64. }
  65. else if ( partition == PARTITION_HORZ_B )
  66. {
  67. decode_block( r, c, subSize )
  68. decode_block( r + halfBlock4x4, c, splitSize )
  69. decode_block( r + halfBlock4x4, c + halfBlock4x4, splitSize )
  70. }
  71. else if ( partition == PARTITION_VERT_A )
  72. {
  73. decode_block( r, c, splitSize )
  74. decode_block( r + halfBlock4x4, c, splitSize )
  75. decode_block( r, c + halfBlock4x4, subSize )
  76. }
  77. else if ( partition == PARTITION_VERT_B )
  78. {
  79. decode_block( r, c, subSize )
  80. decode_block( r, c + halfBlock4x4, splitSize )
  81. decode_block( r + halfBlock4x4, c + halfBlock4x4, splitSize )
  82. }
  83. else if ( partition == PARTITION_HORZ_4 )
  84. {
  85. decode_block( r + quarterBlock4x4 * 0, c, subSize )
  86. decode_block( r + quarterBlock4x4 * 1, c, subSize )
  87. decode_block( r + quarterBlock4x4 * 2, c, subSize )
  88. if ( r + quarterBlock4x4 * 3 < MiRows )
  89. decode_block( r + quarterBlock4x4 * 3, c, subSize )
  90. }
  91. else
  92. {
  93. decode_block( r, c + quarterBlock4x4 * 0, subSize )
  94. decode_block( r, c + quarterBlock4x4 * 1, subSize )
  95. decode_block( r, c + quarterBlock4x4 * 2, subSize )
  96. if ( c + quarterBlock4x4 * 3 < MiCols )
  97. decode_block( r, c + quarterBlock4x4 * 3, subSize )
  98. }
  99. }

5.11.5 decode_block语法

  1. decode_block( r, c, subSize )
  2. {
  3. MiRow = r
  4. MiCol = c
  5. MiSize = subSize
  6. bw4 = Num_4x4_Blocks_Wide[ subSize ]
  7. bh4 = Num_4x4_Blocks_High[ subSize ]
  8. if ( bh4 == 1 && subsampling_y && (MiRow & 1) == 0 )
  9. HasChroma = 0
  10. else if ( bw4 == 1 && subsampling_x && (MiCol & 1) == 0 )
  11. HasChroma = 0
  12. else
  13. HasChroma = NumPlanes > 1
  14. AvailU = is_inside( r - 1, c )
  15. AvailL = is_inside( r, c - 1 )
  16. AvailUChroma = AvailU
  17. AvailLChroma = AvailL
  18. if ( HasChroma )
  19. {
  20. if ( subsampling_y && bh4 == 1 )
  21. AvailUChroma = is_inside( r - 2, c )
  22. if ( subsampling_x && bw4 == 1 )
  23. AvailLChroma = is_inside( r, c - 2 )
  24. }
  25. else
  26. {
  27. AvailUChroma = 0
  28. AvailLChroma = 0
  29. }
  30. mode_info( )
  31. palette_tokens( )
  32. read_block_tx_size( )
  33. if ( skip )
  34. reset_block_context( bw4, bh4 )
  35. isCompound = RefFrame[ 1 ] > INTRA_FRAME
  36. for ( y = 0; y < bh4; y++ )
  37. {
  38. for ( x = 0; x < bw4; x++ )
  39. {
  40. YModes [ r + y ][ c + x ] = YMode
  41. if ( RefFrame[ 0 ] == INTRA_FRAME && HasChroma )
  42. UVModes [ r + y ][ c + x ] = UVMode
  43. for ( refList = 0; refList < 2; refList++ )
  44. RefFrames[ r + y ][ c + x ][ refList ] = RefFrame[ refList ]
  45. if ( is_inter )
  46. {
  47. if ( !use_intrabc )
  48. {
  49. CompGroupIdxs[ r + y ][ c + x ] = comp_group_idx
  50. CompoundIdxs[ r + y ][ c + x ] = compound_idx
  51. }
  52. for ( dir = 0; dir < 2; dir++ )
  53. {
  54. InterpFilters[ r + y ][ c + x ][ dir ] = interp_filter[ dir ]
  55. }
  56. for ( refList = 0; refList < 1 + isCompound; refList++ )
  57. {
  58. Mvs[ r + y ][ c + x ][ refList ] = Mv[ refList ]
  59. }
  60. }
  61. }
  62. }
  63. compute_prediction( )
  64. residual( )
  65. for ( y = 0; y < bh4; y++ )
  66. {
  67. for ( x = 0; x < bw4; x++ )
  68. {
  69. IsInters[ r + y ][ c + x ] = is_inter
  70. SkipModes[ r + y ][ c + x ] = skip_mode
  71. Skips[ r + y ][ c + x ] = skip
  72. TxSizes[ r + y ][ c + x ] = TxSize
  73. MiSizes[ r + y ][ c + x ] = MiSize
  74. SegmentIds[ r + y ][ c + x ] = segment_id
  75. PaletteSizes[ 0 ][ r + y ][ c + x ] = PaletteSizeY
  76. PaletteSizes[ 1 ][ r + y ][ c + x ] = PaletteSizeUV
  77. for ( i = 0; i < PaletteSizeY; i++ )
  78. PaletteColors[ 0 ][ r + y ][ c + x ][ i ] = palette_colors_y[ i ]
  79. for ( i = 0; i < PaletteSizeUV; i++ )
  80. PaletteColors[ 1 ][ r + y ][ c + x ][ i ] = palette_colors_u[ i ]
  81. for ( i = 0; i < FRAME_LF_COUNT; i++ )
  82. DeltaLFs[ r + y ][ c + x ][ i ] = DeltaLF[ i ]
  83. }
  84. }
  85. }

其中的reset_block_context()定义如下,

  1. reset_block_context( bw4, bh4 )
  2. {
  3. for ( plane = 0; plane < 1 + 2 * HasChroma; plane++ )
  4. {
  5. subX = (plane > 0) ? subsampling_x : 0
  6. subY = (plane > 0) ? subsampling_y : 0
  7. for ( i = MiCol >> subX; i < ( ( MiCol + bw4 ) >> subX ); i++)
  8. {
  9. AboveLevelContext[ plane ][ i ] = 0
  10. AboveDcContext[ plane ][ i ] = 0
  11. }
  12. for ( i = MiRow >> subY; i < ( ( MiRow + bh4 ) >> subY ); i++)
  13. {
  14. LeftLevelContext[ plane ][ i ] = 0
  15. LeftDcContext[ plane ][ i ] = 0
  16. }
  17. }
  18. }

5.11.6 mode_info语法

  1. mode_info( )
  2. {
  3. if ( FrameIsIntra )
  4. intra_frame_mode_info( )
  5. else
  6. inter_frame_mode_info( )
  7. }

5.11.7 intra_frame_mode_info语法

  1. intra_frame_mode_info( )
  2. {
  3. skip = 0
  4. if ( SegIdPreSkip )
  5. intra_segment_id( )
  6. skip_mode = 0
  7. read_skip( )
  8. if ( !SegIdPreSkip )
  9. intra_segment_id( )
  10. read_cdef( )
  11. read_delta_qindex( )
  12. read_delta_lf( )
  13. ReadDeltas = 0
  14. RefFrame[ 0 ] = INTRA_FRAME
  15. RefFrame[ 1 ] = NONE
  16. if ( allow_intrabc )
  17. {
  18. use_intrabc // Type S()
  19. }
  20. else
  21. {
  22. use_intrabc = 0
  23. }
  24. if ( use_intrabc )
  25. {
  26. is_inter = 1
  27. YMode = DC_PRED
  28. UVMode = DC_PRED
  29. motion_mode = SIMPLE
  30. compound_type = COMPOUND_AVERAGE
  31. PaletteSizeY = 0
  32. PaletteSizeUV = 0
  33. interp_filter[ 0 ] = BILINEAR
  34. interp_filter[ 1 ] = BILINEAR
  35. find_mv_stack( 0 )
  36. assign_mv( 0 )
  37. }
  38. else
  39. {
  40. is_inter = 0
  41. intra_frame_y_mode // Type S()
  42. YMode = intra_frame_y_mode
  43. intra_angle_info_y( )
  44. if ( HasChroma )
  45. {
  46. uv_mode // Type S()
  47. UVMode = uv_mode
  48. if ( UVMode == UV_CFL_PRED )
  49. {
  50. read_cfl_alphas( )
  51. }
  52. intra_angle_info_uv( )
  53. }
  54. PaletteSizeY = 0
  55. PaletteSizeUV = 0
  56. if ( MiSize >= BLOCK_8X8
  57. && Block_Width[ MiSize ] <= 64
  58. && Block_Height[ MiSize ] <= 64
  59. && allow_screen_content_tools )
  60. {
  61. palette_mode_info( )
  62. }
  63. filter_intra_mode_info( )
  64. }
  65. }

5.11.8 intra_segment_id语法

  1. intra_segment_id( )
  2. {
  3. if ( segmentation_enabled )
  4. read_segment_id( )
  5. else
  6. segment_id = 0
  7. Lossless = LosslessArray[ segment_id ]
  8. }

5.11.9 read_segment_id语法

  1. read_segment_id( )
  2. {
  3. if ( AvailU && AvailL )
  4. prevUL = SegmentIds[ MiRow - 1 ][ MiCol - 1 ]
  5. else
  6. prevUL = -1
  7. if ( AvailU )
  8. prevU = SegmentIds[ MiRow - 1 ][ MiCol ]
  9. else
  10. prevU = -1
  11. if ( AvailL )
  12. prevL = SegmentIds[ MiRow ][ MiCol - 1 ]
  13. else
  14. prevL = -1
  15. if ( prevU == -1 )
  16. pred = (prevL == -1) ? 0 : prevL
  17. else if ( prevL == -1 )
  18. pred = prevU
  19. else
  20. pred = (prevUL == prevU) ? prevU : prevL
  21. if ( skip )
  22. {
  23. segment_id = pred
  24. }
  25. else
  26. {
  27. segment_id // Type S()
  28. segment_id = neg_deinterleave( segment_id, pred, LastActiveSegId + 1 )
  29. }
  30. }

其中的neg_deinterleave()定义如下,

  1. neg_deinterleave(diff, ref, max)
  2. {
  3. if ( !ref )
  4. return diff
  5. if ( ref >= (max - 1) )
  6. return max - diff - 1
  7. if ( 2 * ref < max )
  8. {
  9. if ( diff <= 2 * ref )
  10. {
  11. if ( diff & 1 )
  12. return ref + ((diff + 1) >> 1)
  13. else
  14. return ref - (diff >> 1)
  15. }
  16. return diff
  17. }
  18. else
  19. {
  20. if ( diff <= 2 * (max - ref - 1) )
  21. {
  22. if ( diff & 1 )
  23. return ref + ((diff + 1) >> 1)
  24. else
  25. return ref - (diff >> 1)
  26. }
  27. return max - (diff + 1)
  28. }
  29. }

5.11.10 read_skip_mode语法

  1. read_skip_mode()
  2. {
  3. if ( seg_feature_active( SEG_LVL_SKIP )
  4. || seg_feature_active( SEG_LVL_REF_FRAME )
  5. || seg_feature_active( SEG_LVL_GLOBALMV )
  6. || !skip_mode_present
  7. || Block_Width[ MiSize ] < 8
  8. || Block_Height[ MiSize ] < 8 )
  9. {
  10. skip_mode = 0
  11. }
  12. else
  13. {
  14. skip_mode // Type S()
  15. }
  16. }

5.11.11 read_skip语法

  1. read_skip()
  2. {
  3. if ( SegIdPreSkip && seg_feature_active( SEG_LVL_SKIP ) )
  4. {
  5. skip = 1
  6. }
  7. else
  8. {
  9. skip // Type S()
  10. }
  11. }

5.11.12 read_delta_qindex语法

  1. read_delta_qindex( )
  2. {
  3. sbSize = use_128x128_superblock ? BLOCK_128X128 : BLOCK_64X64
  4. if ( MiSize == sbSize && skip )
  5. return
  6. if ( ReadDeltas )
  7. {
  8. delta_q_abs // Type S()
  9. if ( delta_q_abs == DELTA_Q_SMALL )
  10. {
  11. delta_q_rem_bits // Type L(3)
  12. delta_q_rem_bits++
  13. delta_q_abs_bits // Type L(delta_q_rem_bits)
  14. delta_q_abs = delta_q_abs_bits + (1 << delta_q_rem_bits) + 1
  15. }
  16. if ( delta_q_abs )
  17. {
  18. delta_q_sign_bit // Type L(1)
  19. reducedDeltaQIndex = delta_q_sign_bit ? -delta_q_abs : delta_q_abs
  20. CurrentQIndex = Clip3(1, 255, CurrentQIndex + (reducedDeltaQIndex << delta_q_res))
  21. }
  22. }
  23. }

5.11.13 read_delta_lf语法

  1. read_delta_lf( )
  2. {
  3. sbSize = use_128x128_superblock ? BLOCK_128X128 : BLOCK_64X64
  4. if ( MiSize == sbSize && skip )
  5. return
  6. if ( ReadDeltas && delta_lf_present )
  7. {
  8. frameLfCount = 1
  9. if ( delta_lf_multi )
  10. {
  11. frameLfCount = ( NumPlanes > 1 ) ? FRAME_LF_COUNT : ( FRAME_LF_COUNT - 2 )
  12. }
  13. for ( i = 0; i < frameLfCount; i++ )
  14. {
  15. delta_lf_abs // Type S()
  16. if ( delta_lf_abs == DELTA_LF_SMALL )
  17. {
  18. delta_lf_rem_bits // Type L(3)
  19. n = delta_lf_rem_bits + 1
  20. delta_lf_abs_bits // Type L(n)
  21. deltaLfAbs = delta_lf_abs_bits + ( 1 << n ) + 1
  22. }
  23. else
  24. {
  25. deltaLfAbs = delta_lf_abs
  26. }
  27. if ( deltaLfAbs )
  28. {
  29. delta_lf_sign_bit // Type L(1)
  30. reducedDeltaLfLevel = delta_lf_sign_bit ? -deltaLfAbs : deltaLfAbs
  31. DeltaLF[ i ] = Clip3( -MAX_LOOP_FILTER, MAX_LOOP_FILTER, DeltaLF[ i ] + (reducedDeltaLfLevel << delta_lf_res) )
  32. }
  33. }
  34. }
  35. }

5.11.14 seg_feature_active_idx函数

  1. seg_feature_active_idx( idx, feature )
  2. {
  3. return segmentation_enabled && FeatureEnabled[ idx ][ feature ]
  4. }
  5. seg_feature_active( feature )
  6. {
  7. return seg_feature_active_idx( segment_id, feature )
  8. }

5.11.15 read_tx_size语法

  1. read_tx_size( allowSelect )
  2. {
  3. if ( Lossless )
  4. {
  5. TxSize = TX_4X4
  6. return
  7. }
  8. maxRectTxSize = Max_Tx_Size_Rect[ MiSize ]
  9. maxTxDepth = Max_Tx_Depth[ MiSize ]
  10. TxSize = maxRectTxSize
  11. if ( MiSize > BLOCK_4X4 && allowSelect && TxMode == TX_MODE_SELECT )
  12. {
  13. tx_depth // Type S()
  14. for ( i = 0; i < tx_depth; i++ )
  15. TxSize = Split_Tx_Size[ TxSize ]
  16. }
  17. }

其中Max_Tx_Depth定义了每个块尺寸的最大变换深度,

  1. Max_Tx_Depth[ BLOCK_SIZES ] =
  2. {
  3. 0, 1, 1, 1,
  4. 2, 2, 2, 3,
  5. 3, 3, 4, 4,
  6. 4, 4, 4, 4,
  7. 2, 2, 3, 3,
  8. 4, 4
  9. }

注意:Max_Tx_Depth包含必须拆分变换以达到4x4变换大小的次数。它可能大于MAX_TX_DEPTH。但是,因为tx_depth只能编码0到2范围内的值,所以无法进行变换深度大于MAX_TX_DEPTH的编码。

5.11.16 read_block_tx_size语法

  1. read_block_tx_size( )
  2. {
  3. bw4 = Num_4x4_Blocks_Wide[ MiSize ]
  4. bh4 = Num_4x4_Blocks_High[ MiSize ]
  5. if ( TxMode == TX_MODE_SELECT && MiSize > BLOCK_4X4 && is_inter && !skip && !Lossless )
  6. {
  7. maxTxSz = Max_Tx_Size_Rect[ MiSize ]
  8. txW4 = Tx_Width[ maxTxSz ] / MI_SIZE
  9. txH4 = Tx_Height[ maxTxSz ] / MI_SIZE
  10. for ( row = MiRow; row < MiRow + bh4; row += txH4 )
  11. for ( col = MiCol; col < MiCol + bw4; col += txW4 )
  12. read_var_tx_size( row, col, maxTxSz, 0 )
  13. }
  14. else
  15. {
  16. read_tx_size(!skip || !is_inter)
  17. for ( row = MiRow; row < MiRow + bh4; row++ )
  18. for ( col = MiCol; col < MiCol + bw4; col++ )
  19. InterTxSizes[ row ][ col ] = TxSize
  20. }
  21. }

5.11.17 read_var_tx_size语法

用于读取变换尺寸树。

  1. read_var_tx_size( row, col, txSz, depth)
  2. {
  3. if ( row >= MiRows || col >= MiCols )
  4. return
  5. if ( txSz == TX_4X4 || depth == MAX_VARTX_DEPTH )
  6. {
  7. txfm_split = 0
  8. }
  9. else
  10. {
  11. txfm_split // Type S()
  12. }
  13. w4 = Tx_Width[ txSz ] / MI_SIZE
  14. h4 = Tx_Height[ txSz ] / MI_SIZE
  15. if ( txfm_split )
  16. {
  17. subTxSz = Split_Tx_Size[ txSz ]
  18. stepW = Tx_Width[ subTxSz ] / MI_SIZE
  19. stepH = Tx_Height[ subTxSz ] / MI_SIZE
  20. for ( i = 0; i < h4; i += stepH )
  21. for ( j = 0; j < w4; j += stepW )
  22. read_var_tx_size( row + i, col + j, subTxSz, depth+1)
  23. }
  24. else
  25. {
  26. for ( i = 0; i < h4; i++ )
  27. for ( j = 0; j < w4; j++ )
  28. InterTxSizes[ row + i ][ col + j ] = txSz
  29. TxSize = txSz
  30. }
  31. }

5.11.18 inter_frame_mode_info语法

  1. inter_frame_mode_info( )
  2. {
  3. use_intrabc = 0
  4. LeftRefFrame[ 0 ] = AvailL ? RefFrames[ MiRow ][ MiCol-1 ][ 0 ] : INTRA_FRAME
  5. AboveRefFrame[ 0 ] = AvailU ? RefFrames[ MiRow-1 ][ MiCol ][ 0 ] : INTRA_FRAME
  6. LeftRefFrame[ 1 ] = AvailL ? RefFrames[ MiRow ][ MiCol-1 ][ 1 ] : NONE
  7. AboveRefFrame[ 1 ] = AvailU ? RefFrames[ MiRow-1 ][ MiCol ][ 1 ] : NONE
  8. LeftIntra = LeftRefFrame[ 0 ] <= INTRA_FRAME
  9. AboveIntra = AboveRefFrame[ 0 ] <= INTRA_FRAME
  10. LeftSingle = LeftRefFrame[ 1 ] <= INTRA_FRAME
  11. AboveSingle = AboveRefFrame[ 1 ] <= INTRA_FRAME
  12. skip = 0
  13. inter_segment_id( 1 )
  14. read_skip_mode( )
  15. if ( skip_mode )
  16. skip = 1
  17. else
  18. read_skip( )
  19. if ( !SegIdPreSkip )
  20. inter_segment_id( 0 )
  21. Lossless = LosslessArray[ segment_id ]
  22. read_cdef( )
  23. read_delta_qindex( )
  24. read_delta_lf( )
  25. ReadDeltas = 0
  26. read_is_inter( )
  27. if ( is_inter )
  28. inter_block_mode_info( )
  29. else
  30. intra_block_mode_info( )
  31. }

5.11.19 inter_segment_id语法

This is called before (preSkip equal to 1) and after (preSkip equal to 0) the skip syntax element has been read.

  1. inter_segment_id( preSkip )
  2. {
  3. if ( segmentation_enabled )
  4. {
  5. predictedSegmentId = get_segment_id( )
  6. if ( segmentation_update_map )
  7. {
  8. if ( preSkip && !SegIdPreSkip )
  9. {
  10. segment_id = 0
  11. return
  12. }
  13. if ( !preSkip )
  14. {
  15. if ( skip )
  16. {
  17. seg_id_predicted = 0
  18. for ( i = 0; i < Num_4x4_Blocks_Wide[ MiSize ]; i++ )
  19. AboveSegPredContext[ MiCol + i ] = seg_id_predicted
  20. for ( i = 0; i < Num_4x4_Blocks_High[ MiSize ]; i++ )
  21. LeftSegPredContext[ MiRow + i ] = seg_id_predicted
  22. read_segment_id( )
  23. return
  24. }
  25. }
  26. if ( segmentation_temporal_update == 1 )
  27. {
  28. seg_id_predicted // Type S()
  29. if ( seg_id_predicted )
  30. segment_id = predictedSegmentId
  31. else
  32. read_segment_id( )
  33. for ( i = 0; i < Num_4x4_Blocks_Wide[ MiSize ]; i++ )
  34. AboveSegPredContext[ MiCol + i ] = seg_id_predicted
  35. for ( i = 0; i < Num_4x4_Blocks_High[ MiSize ]; i++ )
  36. LeftSegPredContext[ MiRow + i ] = seg_id_predicted
  37. }
  38. else
  39. {
  40. read_segment_id( )
  41. }
  42. }
  43. else
  44. {
  45. segment_id = predictedSegmentId
  46. }
  47. }
  48. else
  49. {
  50. segment_id = 0
  51. }
  52. }

5.11.20 read_is_inter语法

  1. read_is_inter( )
  2. {
  3. if ( skip_mode )
  4. {
  5. is_inter = 1
  6. }
  7. else if ( seg_feature_active ( SEG_LVL_REF_FRAME ) )
  8. {
  9. is_inter = FeatureData[ segment_id ][ SEG_LVL_REF_FRAME ] != INTRA_FRAME
  10. }
  11. else if ( seg_feature_active ( SEG_LVL_GLOBALMV ) )
  12. {
  13. is_inter = 1
  14. }
  15. else
  16. {
  17. is_inter // Type S()
  18. }
  19. }

5.11.21 get_segment_id函数

segment_id是在当前块覆盖的分割图的屏幕中找到的最小值。

  1. get_segment_id( )
  2. {
  3. bw4 = Num_4x4_Blocks_Wide[ MiSize ]
  4. bh4 = Num_4x4_Blocks_High[ MiSize ]
  5. xMis = Min( MiCols - MiCol, bw4 )
  6. yMis = Min( MiRows - MiRow, bh4 )
  7. seg = 7
  8. for ( y = 0; y < yMis; y++ )
  9. for ( x = 0; x < xMis; x++ )
  10. seg = Min( seg, PrevSegmentIds[ MiRow + y ][ MiCol + x ] )
  11. return seg
  12. }

5.11.22 intra_block_mode_info语法

  1. intra_block_mode_info( )
  2. {
  3. RefFrame[ 0 ] = INTRA_FRAME
  4. RefFrame[ 1 ] = NONE
  5. y_mode // Type S()
  6. YMode = y_mode
  7. intra_angle_info_y( )
  8. if ( HasChroma )
  9. {
  10. uv_mode // Type S()
  11. UVMode = uv_mode
  12. if ( UVMode == UV_CFL_PRED )
  13. {
  14. read_cfl_alphas( )
  15. }
  16. intra_angle_info_uv( )
  17. }
  18. PaletteSizeY = 0
  19. PaletteSizeUV = 0
  20. if ( MiSize >= BLOCK_8X8
  21. && Block_Width[ MiSize ] <= 64
  22. && Block_Height[ MiSize ] <= 64
  23. && allow_screen_content_tools )
  24. palette_mode_info( )
  25. filter_intra_mode_info( )
  26. }

5.11.23 inter_block_mode_info语法

  1. inter_block_mode_info( )
  2. {
  3. PaletteSizeY = 0
  4. PaletteSizeUV = 0
  5. read_ref_frames( )
  6. isCompound = RefFrame[ 1 ] > INTRA_FRAME
  7. find_mv_stack( isCompound )
  8. if ( skip_mode )
  9. {
  10. YMode = NEAREST_NEARESTMV
  11. }
  12. else if ( seg_feature_active( SEG_LVL_SKIP ) || seg_feature_active( SEG_LVL_GLOBALMV ) )
  13. {
  14. YMode = GLOBALMV
  15. }
  16. else if ( isCompound )
  17. {
  18. compound_mode // Type S()
  19. YMode = NEAREST_NEARESTMV + compound_mode
  20. }
  21. else
  22. {
  23. new_mv // Type S()
  24. if ( new_mv == 0 )
  25. {
  26. YMode = NEWMV
  27. }
  28. else
  29. {
  30. zero_mv // Type S()
  31. if ( zero_mv == 0 )
  32. {
  33. YMode = GLOBALMV
  34. }
  35. else
  36. {
  37. ref_mv // Type S()
  38. YMode = (ref_mv == 0) ? NEARESTMV : NEARMV
  39. }
  40. }
  41. }
  42. RefMvIdx = 0
  43. if ( YMode == NEWMV || YMode == NEW_NEWMV )
  44. {
  45. for ( idx = 0; idx < 2; idx++ )
  46. {
  47. if ( NumMvFound > idx + 1 )
  48. {
  49. drl_mode // Type S()
  50. if ( drl_mode == 0 )
  51. {
  52. RefMvIdx = idx
  53. break
  54. }
  55. RefMvIdx = idx + 1
  56. }
  57. }
  58. }
  59. else if ( has_nearmv( ) )
  60. {
  61. RefMvIdx = 1
  62. for ( idx = 1; idx < 3; idx++ )
  63. {
  64. if ( NumMvFound > idx + 1 )
  65. {
  66. drl_mode // Type S()
  67. if ( drl_mode == 0 )
  68. {
  69. RefMvIdx = idx
  70. break
  71. }
  72. RefMvIdx = idx + 1
  73. }
  74. }
  75. }
  76. assign_mv( isCompound )
  77. read_interintra_mode( isCompound )
  78. read_motion_mode( isCompound )
  79. read_compound_type( isCompound )
  80. if ( interpolation_filter == SWITCHABLE )
  81. {
  82. for ( dir = 0; dir < ( enable_dual_filter ? 2 : 1 ); dir++ )
  83. {
  84. if ( needs_interp_filter( ) )
  85. {
  86. interp_filter[ dir ] // Type S()
  87. }
  88. else
  89. {
  90. interp_filter[ dir ] = EIGHTTAP
  91. }
  92. }
  93. if ( !enable_dual_filter )
  94. interp_filter[ 1 ] = interp_filter[ 0 ]
  95. }
  96. else
  97. {
  98. for ( dir = 0; dir < 2; dir++ )
  99. interp_filter[ dir ] = interpolation_filter
  100. }
  101. }

其中的has_nearmv函数和needs_interp_filter函数定义为,

  1. has_nearmv( )
  2. {
  3. return (YMode == NEARMV || YMode == NEAR_NEARMV || YMode == NEAR_NEWMV || YMode == NEW_NEARMV)
  4. }
  5. needs_interp_filter( )
  6. {
  7. large = (Min(Block_Width[MiSize], Block_Height[MiSize]) >= 8)
  8. if ( skip_mode || motion_mode == LOCALWARP )
  9. {
  10. return 0
  11. }
  12. else if ( large && YMode == GLOBALMV )
  13. {
  14. return (GmType[ RefFrame[ 0 ] ] == TRANSLATION)
  15. }
  16. else if ( large && YMode == GLOBAL_GLOBALMV )
  17. {
  18. return (GmType[ RefFrame[ 0 ] ] == TRANSLATION || GmType[ RefFrame[ 1 ] ] == TRANSLATION)
  19. }
  20. else
  21. {
  22. return 1
  23. }
  24. }

5.11.24 filter_intra_mode_info语法

  1. filter_intra_mode_info( )
  2. {
  3. use_filter_intra = 0
  4. if ( enable_filter_intra
  5. && YMode == DC_PRED
  6. && PaletteSizeY == 0
  7. && Max( Block_Width[ MiSize ], Block_Height[ MiSize ] ) <= 32 )
  8. {
  9. use_filter_intra // Type S()
  10. if ( use_filter_intra )
  11. {
  12. filter_intra_mode // Type S()
  13. }
  14. }
  15. }

5.11.25 read_ref_frames语法

  1. read_ref_frames( )
  2. {
  3. if ( skip_mode )
  4. {
  5. RefFrame[ 0 ] = SkipModeFrame[ 0 ]
  6. RefFrame[ 1 ] = SkipModeFrame[ 1 ]
  7. }
  8. else if ( seg_feature_active( SEG_LVL_REF_FRAME ) )
  9. {
  10. RefFrame[ 0 ] = FeatureData[ segment_id ][ SEG_LVL_REF_FRAME ]
  11. RefFrame[ 1 ] = NONE
  12. }
  13. else if ( seg_feature_active( SEG_LVL_SKIP ) || seg_feature_active( SEG_LVL_GLOBALMV ) )
  14. {
  15. RefFrame[ 0 ] = LAST_FRAME
  16. RefFrame[ 1 ] = NONE
  17. }
  18. else
  19. {
  20. bw4 = Num_4x4_Blocks_Wide[ MiSize ]
  21. bh4 = Num_4x4_Blocks_High[ MiSize ]
  22. if ( reference_select && ( Min( bw4, bh4 ) >= 2 ) )
  23. comp_mode // Type S()
  24. else
  25. comp_mode = SINGLE_REFERENCE
  26. if ( comp_mode == COMPOUND_REFERENCE )
  27. {
  28. comp_ref_type // Type S()
  29. if ( comp_ref_type == UNIDIR_COMP_REFERENCE )
  30. {
  31. uni_comp_ref // Type S()
  32. if ( uni_comp_ref )
  33. {
  34. RefFrame[0] = BWDREF_FRAME
  35. RefFrame[1] = ALTREF_FRAME
  36. }
  37. else
  38. {
  39. uni_comp_ref_p1 // Type S()
  40. if ( uni_comp_ref_p1 )
  41. {
  42. uni_comp_ref_p2 // Type S()
  43. if ( uni_comp_ref_p2 )
  44. {
  45. RefFrame[0] = LAST_FRAME
  46. RefFrame[1] = GOLDEN_FRAME
  47. }
  48. else
  49. {
  50. RefFrame[0] = LAST_FRAME
  51. RefFrame[1] = LAST3_FRAME
  52. }
  53. }
  54. else
  55. {
  56. RefFrame[0] = LAST_FRAME
  57. RefFrame[1] = LAST2_FRAME
  58. }
  59. }
  60. }
  61. else
  62. {
  63. comp_ref // Type S()
  64. if ( comp_ref == 0 )
  65. {
  66. comp_ref_p1 // Type S()
  67. RefFrame[ 0 ] = comp_ref_p1 ? LAST2_FRAME : LAST_FRAME
  68. }
  69. else
  70. {
  71. comp_ref_p2 // Type S()
  72. RefFrame[ 0 ] = comp_ref_p2 ? GOLDEN_FRAME : LAST3_FRAME
  73. }
  74. comp_bwdref // Type S()
  75. if ( comp_bwdref == 0 )
  76. {
  77. comp_bwdref_p1 // Type S()
  78. RefFrame[ 1 ] = comp_bwdref_p1 ? ALTREF2_FRAME : BWDREF_FRAME
  79. }
  80. else
  81. {
  82. RefFrame[ 1 ] = ALTREF_FRAME
  83. }
  84. }
  85. }
  86. else
  87. {
  88. single_ref_p1 // Type S()
  89. if ( single_ref_p1 )
  90. {
  91. single_ref_p2 // Type S()
  92. if ( single_ref_p2 == 0 )
  93. {
  94. single_ref_p6 // Type S()
  95. RefFrame[ 0 ] = single_ref_p6 ? ALTREF2_FRAME : BWDREF_FRAME
  96. }
  97. else
  98. {
  99. RefFrame[ 0 ] = ALTREF_FRAME
  100. }
  101. }
  102. else
  103. {
  104. single_ref_p3 // Type S()
  105. if ( single_ref_p3 )
  106. {
  107. single_ref_p5 // Type S()
  108. RefFrame[ 0 ] = single_ref_p5 ? GOLDEN_FRAME : LAST3_FRAME
  109. }
  110. else
  111. {
  112. single_ref_p4 // Type S()
  113. RefFrame[ 0 ] = single_ref_p4 ? LAST2_FRAME : LAST_FRAME
  114. }
  115. }
  116. RefFrame[ 1 ] = NONE
  117. }
  118. }
  119. }

5.11.26 assign_mv语法

  1. assign_mv( isCompound )
  2. {
  3. for ( i = 0; i < 1 + isCompound; i++ )
  4. {
  5. if ( use_intrabc )
  6. {
  7. compMode = NEWMV
  8. }
  9. else
  10. {
  11. compMode = get_mode( i )
  12. }
  13. if ( use_intrabc )
  14. {
  15. PredMv[ 0 ] = RefStackMv[ 0 ][ 0 ]
  16. if ( PredMv[ 0 ][ 0 ] == 0 && PredMv[ 0 ][ 1 ] == 0 )
  17. {
  18. PredMv[ 0 ] = RefStackMv[ 1 ][ 0 ]
  19. }
  20. if ( PredMv[ 0 ][ 0 ] == 0 && PredMv[ 0 ][ 1 ] == 0 )
  21. {
  22. sbSize = use_128x128_superblock ? BLOCK_128X128 : BLOCK_64X64
  23. sbSize4 = Num_4x4_Blocks_High[ sbSize ]
  24. if ( MiRow - sbSize4 < MiRowStart )
  25. {
  26. PredMv[ 0 ][ 0 ] = 0
  27. PredMv[ 0 ][ 1 ] = -(sbSize4 * MI_SIZE + INTRABC_DELAY_PIXELS) * 8
  28. }
  29. else
  30. {
  31. PredMv[ 0 ][ 0 ] = -(sbSize4 * MI_SIZE * 8)
  32. PredMv[ 0 ][ 1 ] = 0
  33. }
  34. }
  35. }
  36. else if ( compMode == GLOBALMV )
  37. {
  38. PredMv[ i ] = GlobalMvs[ i ]
  39. }
  40. else
  41. {
  42. pos = ( compMode == NEARESTMV ) ? 0 : RefMvIdx
  43. if ( compMode == NEWMV && NumMvFound <= 1 )
  44. pos = 0
  45. PredMv[ i ] = RefStackMv[ pos ][ i ]
  46. }
  47. if ( compMode == NEWMV )
  48. {
  49. read_mv( i )
  50. }
  51. else
  52. {
  53. Mv[ i ] = PredMv[ i ]
  54. }
  55. }
  56. }

5.11.27 read_motion_mode语法

  1. read_motion_mode( isCompound )
  2. {
  3. if ( skip_mode )
  4. {
  5. motion_mode = SIMPLE
  6. return
  7. }
  8. if ( !is_motion_mode_switchable )
  9. {
  10. motion_mode = SIMPLE
  11. return
  12. }
  13. if ( Min( Block_Width[ MiSize ], Block_Height[ MiSize ] ) < 8 )
  14. {
  15. motion_mode = SIMPLE
  16. return
  17. }
  18. if ( !force_integer_mv && ( YMode == GLOBALMV || YMode == GLOBAL_GLOBALMV ) )
  19. {
  20. if ( GmType[ RefFrame[ 0 ] ] > TRANSLATION )
  21. {
  22. motion_mode = SIMPLE
  23. return
  24. }
  25. }
  26. if ( isCompound || RefFrame[ 1 ] == INTRA_FRAME || !has_overlappable_candidates( ) )
  27. {
  28. motion_mode = SIMPLE
  29. return
  30. }
  31. find_warp_samples()
  32. if ( force_integer_mv || NumSamples == 0 || !allow_warped_motion || is_scaled( RefFrame[0] ) )
  33. {
  34. use_obmc // Type S()
  35. motion_mode = use_obmc ? OBMC : SIMPLE
  36. }
  37. else
  38. {
  39. motion_mode
  40. }
  41. }

其中的is_scaled函数定义为,

  1. is_scaled( refFrame )
  2. {
  3. refIdx = ref_frame_idx[ refFrame - LAST_FRAME ]
  4. xScale = ( ( RefUpscaledWidth[ refIdx ] << REF_SCALE_SHIFT ) + ( FrameWidth / 2 ) ) / FrameWidth
  5. yScale = ( ( RefFrameHeight[ refIdx ] << REF_SCALE_SHIFT ) + ( FrameHeight / 2 ) ) / FrameHeight
  6. noScale = 1 << REF_SCALE_SHIFT
  7. return xScale != noScale || yScale != noScale
  8. }

5.11.28 read_interintra_mode语法

  1. read_interintra_mode( isCompound )
  2. {
  3. if ( !skip_mode
  4. && enable_interintra_compound
  5. && !isCompound
  6. && MiSize >= BLOCK_8X8
  7. && MiSize <= BLOCK_32X32)
  8. {
  9. interintra // Type S()
  10. if ( interintra )
  11. {
  12. interintra_mode // Type S()
  13. RefFrame[1] = INTRA_FRAME
  14. AngleDeltaY = 0
  15. AngleDeltaUV = 0
  16. use_filter_intra = 0
  17. wedge_interintra // Type S()
  18. if ( wedge_interintra )
  19. {
  20. wedge_index // Type S()
  21. wedge_sign = 0
  22. }
  23. }
  24. }
  25. else
  26. {
  27. interintra = 0
  28. }
  29. }

5.11.29 read_compound_type语法

  1. read_compound_type( isCompound )
  2. {
  3. comp_group_idx = 0
  4. compound_idx = 1
  5. if ( skip_mode )
  6. {
  7. compound_type = COMPOUND_AVERAGE
  8. return
  9. }
  10. if ( isCompound )
  11. {
  12. n = Wedge_Bits[ MiSize ]
  13. if ( enable_masked_compound )
  14. {
  15. comp_group_idx // Type S()
  16. }
  17. if ( comp_group_idx == 0 )
  18. {
  19. if ( enable_jnt_comp )
  20. {
  21. compound_idx // Type S()
  22. compound_type = compound_idx ? COMPOUND_AVERAGE : COMPOUND_DISTANCE
  23. }
  24. else
  25. {
  26. compound_type = COMPOUND_AVERAGE
  27. }
  28. }
  29. else
  30. {
  31. if ( n == 0 )
  32. {
  33. compound_type = COMPOUND_DIFFWTD
  34. }
  35. else
  36. {
  37. compound_type // Type S()
  38. }
  39. }
  40. if ( compound_type == COMPOUND_WEDGE )
  41. {
  42. wedge_index // Type S()
  43. wedge_sign // Type L(1)
  44. }
  45. else if ( compound_type == COMPOUND_DIFFWTD )
  46. {
  47. mask_type // Type L(1)
  48. }
  49. }
  50. else
  51. {
  52. if ( interintra )
  53. {
  54. compound_type = wedge_interintra ? COMPOUND_WEDGE : COMPOUND_INTRA
  55. }
  56. else
  57. {
  58. compound_type = COMPOUND_AVERAGE
  59. }
  60. }
  61. }

5.11.30 get_mode函数

  1. get_mode( refList )
  2. {
  3. if ( refList == 0 )
  4. {
  5. if ( YMode < NEAREST_NEARESTMV )
  6. compMode = YMode
  7. else if ( YMode == NEW_NEWMV || YMode == NEW_NEARESTMV || YMode == NEW_NEARMV )
  8. compMode = NEWMV
  9. else if ( YMode == NEAREST_NEARESTMV || YMode == NEAREST_NEWMV )
  10. compMode = NEARESTMV
  11. else if ( YMode == NEAR_NEARMV || YMode == NEAR_NEWMV )
  12. compMode = NEARMV
  13. else
  14. compMode = GLOBALMV
  15. }
  16. else
  17. {
  18. if ( YMode == NEW_NEWMV || YMode == NEAREST_NEWMV || YMode == NEAR_NEWMV )
  19. compMode = NEWMV
  20. else if ( YMode == NEAREST_NEARESTMV || YMode == NEW_NEARESTMV )
  21. compMode = NEARESTMV
  22. else if ( YMode == NEAR_NEARMV || YMode == NEW_NEARMV )
  23. compMode = NEARMV
  24. else
  25. compMode = GLOBALMV
  26. }
  27. return compMode
  28. }

5.11.31 read_mv语法

  1. read_mv( ref )
  2. {
  3. diffMv[ 0 ] = 0
  4. diffMv[ 1 ] = 0
  5. if ( use_intrabc )
  6. {
  7. MvCtx = MV_INTRABC_CONTEXT
  8. }
  9. else
  10. {
  11. MvCtx = 0
  12. }
  13. mv_joint // Type S()
  14. if ( mv_joint == MV_JOINT_HZVNZ || mv_joint == MV_JOINT_HNZVNZ )
  15. diffMv[ 0 ] = read_mv_component( 0 )
  16. if ( mv_joint == MV_JOINT_HNZVZ || mv_joint == MV_JOINT_HNZVNZ )
  17. diffMv[ 1 ] = read_mv_component( 1 )
  18. Mv[ ref ][ 0 ] = PredMv[ ref ][ 0 ] + diffMv[ 0 ]
  19. Mv[ ref ][ 1 ] = PredMv[ ref ][ 1 ] + diffMv[ 1 ]
  20. }

5.11.32 read_mv_component语法

  1. read_mv_component( comp )
  2. {
  3. mv_sign // Type S()
  4. mv_class // Type S()
  5. if ( mv_class == MV_CLASS_0 )
  6. {
  7. mv_class0_bit // Type S()
  8. if ( force_integer_mv )
  9. mv_class0_fr = 3
  10. else
  11. mv_class0_fr // Type S()
  12. if ( allow_high_precision_mv )
  13. mv_class0_hp // Type S()
  14. else
  15. mv_class0_hp = 1
  16. mag = ( ( mv_class0_bit << 3 ) | ( mv_class0_fr << 1 ) | mv_class0_hp ) + 1
  17. }
  18. else
  19. {
  20. d = 0
  21. for ( i = 0; i < mv_class; i++ )
  22. {
  23. mv_bit // Type S()
  24. d |= mv_bit << i
  25. }
  26. mag = CLASS0_SIZE << ( mv_class + 2 )
  27. if ( force_integer_mv )
  28. mv_fr = 3
  29. else
  30. mv_fr // Type S()
  31. if ( allow_high_precision_mv )
  32. mv_hp // Type S()
  33. else
  34. mv_hp = 1
  35. mag += ( ( d << 3 ) | ( mv_fr << 1 ) | mv_hp ) + 1
  36. }
  37. return mv_sign ? -mag : mag
  38. }

5.11.33 compute_prediction语法

  1. compute_prediction()
  2. {
  3. sbMask = use_128x128_superblock ? 31 : 15
  4. subBlockMiRow = MiRow & sbMask
  5. subBlockMiCol = MiCol & sbMask
  6. for ( plane = 0; plane < 1 + HasChroma * 2; plane++ )
  7. {
  8. planeSz = get_plane_residual_size( MiSize, plane )
  9. num4x4W = Num_4x4_Blocks_Wide[ planeSz ]
  10. num4x4H = Num_4x4_Blocks_High[ planeSz ]
  11. log2W = MI_SIZE_LOG2 + Mi_Width_Log2[ planeSz ]
  12. log2H = MI_SIZE_LOG2 + Mi_Height_Log2[ planeSz ]
  13. subX = (plane > 0) ? subsampling_x : 0
  14. subY = (plane > 0) ? subsampling_y : 0
  15. baseX = (MiCol >> subX) * MI_SIZE
  16. baseY = (MiRow >> subY) * MI_SIZE
  17. candRow = (MiRow >> subY) << subY
  18. candCol = (MiCol >> subX) << subX
  19. IsInterIntra = ( is_inter && RefFrame[ 1 ] == INTRA_FRAME )
  20. if ( IsInterIntra )
  21. {
  22. if ( interintra_mode == II_DC_PRED ) mode = DC_PRED
  23. else if ( interintra_mode == II_V_PRED ) mode = V_PRED
  24. else if ( interintra_mode == II_H_PRED ) mode = H_PRED
  25. else mode = SMOOTH_PRED
  26. predict_intra( plane, baseX, baseY, plane == 0 ? AvailL : AvailLChroma, plane == 0 ? AvailU : AvailUChroma, BlockDecoded[ plane ][ ( subBlockMiRow >> subY ) - 1 ][ ( subBlockMiCol >> subX ) + num4x4W ], BlockDecoded[ plane ][ ( subBlockMiRow >> subY ) + num4x4H ][ ( subBlockMiCol >> subX ) - 1 ], mode, log2W, log2H )
  27. }
  28. if ( is_inter )
  29. {
  30. predW = Block_Width[ MiSize ] >> subX
  31. predH = Block_Height[ MiSize ] >> subY
  32. someUseIntra = 0
  33. for ( r = 0; r < (num4x4H << subY); r++ )
  34. for ( c = 0; c < (num4x4W << subX); c++ )
  35. if ( RefFrames[ candRow + r ][ candCol + c ][ 0 ] == INTRA_FRAME )
  36. someUseIntra = 1
  37. if ( someUseIntra )
  38. {
  39. predW = num4x4W * 4
  40. predH = num4x4H * 4
  41. candRow = MiRow
  42. candCol = MiCol
  43. }
  44. r = 0
  45. for ( y = 0; y < num4x4H * 4; y += predH )
  46. {
  47. c = 0
  48. for ( x = 0; x < num4x4W * 4; x += predW )
  49. {
  50. predict_inter( plane, baseX + x, baseY + y, predW, predH, candRow + r, candCol + c)
  51. c++
  52. }
  53. r++
  54. }
  55. }
  56. }
  57. }

5.11.34 residual语法

  1. residual( )
  2. {
  3. sbMask = use_128x128_superblock ? 31 : 15
  4. widthChunks = Max( 1, Block_Width[ MiSize ] >> 6 )
  5. heightChunks = Max( 1, Block_Height[ MiSize ] >> 6 )
  6. miSizeChunk = ( widthChunks > 1 || heightChunks > 1 ) ? BLOCK_64X64 : MiSize
  7. for ( chunkY = 0; chunkY < heightChunks; chunkY++ )
  8. {
  9. for ( chunkX = 0; chunkX < widthChunks; chunkX++ )
  10. {
  11. miRowChunk = MiRow + ( chunkY << 4 )
  12. miColChunk = MiCol + ( chunkX << 4 )
  13. subBlockMiRow = miRowChunk & sbMask
  14. subBlockMiCol = miColChunk & sbMask
  15. for ( plane = 0; plane < 1 + HasChroma * 2; plane++ )
  16. {
  17. txSz = Lossless ? TX_4X4 : get_tx_size( plane, TxSize )
  18. stepX = Tx_Width[ txSz ] >> 2
  19. stepY = Tx_Height[ txSz ] >> 2
  20. planeSz = get_plane_residual_size( miSizeChunk, plane )
  21. num4x4W = Num_4x4_Blocks_Wide[ planeSz ]
  22. num4x4H = Num_4x4_Blocks_High[ planeSz ]
  23. subX = (plane > 0) ? subsampling_x : 0
  24. subY = (plane > 0) ? subsampling_y : 0
  25. baseX = (miColChunk >> subX) * MI_SIZE
  26. baseY = (miRowChunk >> subY) * MI_SIZE
  27. if ( is_inter && !Lossless && !plane )
  28. {
  29. transform_tree( baseX, baseY, num4x4W * 4, num4x4H * 4 )
  30. }
  31. else
  32. {
  33. baseXBlock = (MiCol >> subX) * MI_SIZE
  34. baseYBlock = (MiRow >> subY) * MI_SIZE
  35. for ( y = 0; y < num4x4H; y += stepY )
  36. for ( x = 0; x < num4x4W; x += stepX )
  37. transform_block( plane, baseXBlock, baseYBlock, txSz, x + ( ( chunkX << 4 ) >> subX ), y + ( ( chunkY << 4 ) >> subY ) )
  38. }
  39. }
  40. }
  41. }
  42. }

5.11.35 transform_block语法

  1. transform_block(plane, baseX, baseY, txSz, x, y)
  2. {
  3. startX = baseX + 4 * x
  4. startY = baseY + 4 * y
  5. subX = (plane > 0) ? subsampling_x : 0
  6. subY = (plane > 0) ? subsampling_y : 0
  7. row = ( startY << subY ) >> MI_SIZE_LOG2
  8. col = ( startX << subX ) >> MI_SIZE_LOG2
  9. sbMask = use_128x128_superblock ? 31 : 15
  10. subBlockMiRow = row & sbMask
  11. subBlockMiCol = col & sbMask
  12. stepX = Tx_Width[ txSz ] >> MI_SIZE_LOG2
  13. stepY = Tx_Height[ txSz ] >> MI_SIZE_LOG2
  14. maxX = (MiCols * MI_SIZE) >> subX
  15. maxY = (MiRows * MI_SIZE) >> subY
  16. if ( startX >= maxX || startY >= maxY )
  17. {
  18. return
  19. }
  20. if ( !is_inter )
  21. {
  22. if ( ( ( plane == 0 ) && PaletteSizeY ) || ( ( plane != 0 ) && PaletteSizeUV ) )
  23. {
  24. predict_palette( plane, startX, startY, x, y, txSz )
  25. }
  26. else
  27. {
  28. isCfl = (plane > 0 && UVMode == UV_CFL_PRED)
  29. if ( plane == 0 )
  30. {
  31. mode = YMode
  32. }
  33. else
  34. {
  35. mode = ( isCfl ) ? DC_PRED : UVMode
  36. }
  37. log2W = Tx_Width_Log2[ txSz ]
  38. log2H = Tx_Height_Log2[ txSz ]
  39. predict_intra( plane, startX, startY, ( plane == 0 ? AvailL : AvailLChroma ) || x > 0, ( plane == 0 ? AvailU : AvailUChroma ) || y > 0, BlockDecoded[ plane ][ ( subBlockMiRow >> subY ) - 1 ][ ( subBlockMiCol >> subX ) + stepX ], BlockDecoded[ plane ][ ( subBlockMiRow >> subY ) + stepY ][ ( subBlockMiCol >> subX ) - 1 ], mode, log2W, log2H )
  40. if ( isCfl )
  41. {
  42. predict_chroma_from_luma( plane, startX, startY, txSz )
  43. }
  44. }
  45. if ( plane == 0 )
  46. {
  47. MaxLumaW = startX + stepX * 4
  48. MaxLumaH = startY + stepY * 4
  49. }
  50. }
  51. if ( !skip )
  52. {
  53. eob = coeffs( plane, startX, startY, txSz )
  54. if ( eob > 0 )
  55. reconstruct( plane, startX, startY, txSz )
  56. }
  57. for ( i = 0; i < stepY; i++ )
  58. {
  59. for ( j = 0; j < stepX; j++ )
  60. {
  61. LoopfilterTxSizes[ plane ][ (row >> subY) + i ][ (col >> subX) + j ] = txSz
  62. BlockDecoded[ plane ][ ( subBlockMiRow >> subY ) + i ][ ( subBlockMiCol >> subX ) + j ] = 1
  63. }
  64. }
  65. }

5.11.36 transform_tree语法

用于读取一系列的转换块。

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

其中的find_tx_size函数定义为,

  1. find_tx_size( w, h )
  2. {
  3. for ( txSz = 0; txSz < TX_SIZES_ALL; txSz++ )
  4. if ( Tx_Width[ txSz ] == w && Tx_Height[ txSz ] == h )
  5. break
  6. return txSz
  7. }

5.11.37 get_tx_size函数

  1. get_tx_size( plane, txSz )
  2. {
  3. if ( plane == 0 )
  4. return txSz
  5. uvTx = Max_Tx_Size_Rect[ get_plane_residual_size( MiSize, plane ) ]
  6. if ( Tx_Width[ uvTx ] == 64 || Tx_Height[ uvTx ] == 64 )
  7. {
  8. if ( Tx_Width[ uvTx ] == 16 )
  9. {
  10. return TX_16X32
  11. }
  12. if ( Tx_Height[ uvTx ] == 16 )
  13. {
  14. return TX_32X16
  15. }
  16. return TX_32X32
  17. }
  18. return uvTx
  19. }

5.11.38 get_plane_residual_size函数

get_plane_residual_size返回指定平面的残留块的大小。(残留块的宽度和高度始终至少等于4)

  1. get_plane_residual_size( subsize, plane )
  2. {
  3. subx = plane > 0 ? subsampling_x : 0
  4. suby = plane > 0 ? subsampling_y : 0
  5. return Subsampled_Size[ subsize ][ subx ][ suby ]
  6. }

其中的Subsampled_Size定义如下,

  1. Subsampled_Size[ BLOCK_SIZES ][ 2 ][ 2 ] = {
  2. { { BLOCK_4X4, BLOCK_4X4}, {BLOCK_4X4, BLOCK_4X4} },
  3. { { BLOCK_4X8, BLOCK_4X4}, {BLOCK_INVALID, BLOCK_4X4} },
  4. { { BLOCK_8X4, BLOCK_INVALID}, {BLOCK_4X4, BLOCK_4X4} },
  5. { { BLOCK_8X8, BLOCK_8X4}, {BLOCK_4X8, BLOCK_4X4} },
  6. { {BLOCK_8X16, BLOCK_8X8}, {BLOCK_INVALID, BLOCK_4X8} },
  7. { {BLOCK_16X8, BLOCK_INVALID}, {BLOCK_8X8, BLOCK_8X4} },
  8. { {BLOCK_16X16, BLOCK_16X8}, {BLOCK_8X16, BLOCK_8X8} },
  9. { {BLOCK_16X32, BLOCK_16X16}, {BLOCK_INVALID, BLOCK_8X16} },
  10. { {BLOCK_32X16, BLOCK_INVALID}, {BLOCK_16X16, BLOCK_16X8} },
  11. { {BLOCK_32X32, BLOCK_32X16}, {BLOCK_16X32, BLOCK_16X16} },
  12. { {BLOCK_32X64, BLOCK_32X32}, {BLOCK_INVALID, BLOCK_16X32} },
  13. { {BLOCK_64X32, BLOCK_INVALID}, {BLOCK_32X32, BLOCK_32X16} },
  14. { {BLOCK_64X64, BLOCK_64X32}, {BLOCK_32X64, BLOCK_32X32} },
  15. { {BLOCK_64X128, BLOCK_64X64}, {BLOCK_INVALID, BLOCK_32X64} },
  16. { {BLOCK_128X64, BLOCK_INVALID}, {BLOCK_64X64, BLOCK_64X32} },
  17. { {BLOCK_128X128, BLOCK_128X64}, {BLOCK_64X128, BLOCK_64X64} },
  18. { {BLOCK_4X16, BLOCK_4X8}, {BLOCK_INVALID, BLOCK_4X8} },
  19. { {BLOCK_16X4, BLOCK_INVALID}, {BLOCK_8X4, BLOCK_8X4} },
  20. { {BLOCK_8X32, BLOCK_8X16}, {BLOCK_INVALID, BLOCK_4X16} },
  21. { {BLOCK_32X8, BLOCK_INVALID}, {BLOCK_16X8, BLOCK_16X4} },
  22. { {BLOCK_16X64, BLOCK_16X32}, {BLOCK_INVALID, BLOCK_8X32} },
  23. { {BLOCK_64X16, BLOCK_INVALID}, {BLOCK_32X16, BLOCK_32X8} },
  24. }

5.11.39 coeffs语法

  1. coeffs( plane, startX, startY, txSz )
  2. {
  3. x4 = startX >> 2
  4. y4 = startY >> 2
  5. w4 = Tx_Width[ txSz ] >> 2
  6. h4 = Tx_Height[ txSz ] >> 2
  7. txSzCtx = ( Tx_Size_Sqr[txSz] + Tx_Size_Sqr_Up[txSz] + 1 ) >> 1
  8. ptype = plane > 0
  9. segEob = ( txSz == TX_16X64 || txSz == TX_64X16 ) ? 512 : Min( 1024, Tx_Width[ txSz ] * Tx_Height[ txSz ] )
  10. for ( c = 0; c < segEob; c++ )
  11. Quant[c] = 0
  12. for ( i = 0; i < 64; i++ )
  13. for ( j = 0; j < 64; j++ )
  14. Dequant[ i ][ j ] = 0
  15. eob = 0
  16. culLevel = 0
  17. dcCategory = 0
  18. all_zero // Type S()
  19. if ( all_zero )
  20. {
  21. c = 0
  22. if ( plane == 0 )
  23. {
  24. for ( i = 0; i < w4; i++ )
  25. {
  26. for ( j = 0; j < h4; j++ )
  27. {
  28. TxTypes[ y4 + j ][ x4 + i ] = DCT_DCT
  29. }
  30. }
  31. }
  32. }
  33. else
  34. {
  35. if ( plane == 0 )
  36. transform_type( x4, y4, txSz )
  37. PlaneTxType = compute_tx_type( plane, txSz, x4, y4 )
  38. scan = get_scan( txSz )
  39. eobMultisize = Min( Tx_Width_Log2[ txSz ], 5) + Min( Tx_Height_Log2[ txSz ], 5) - 4
  40. if ( eobMultisize == 0 )
  41. {
  42. eob_pt_16 // Type S()
  43. eobPt = eob_pt_16 + 1
  44. }
  45. else if ( eobMultisize == 1 )
  46. {
  47. eob_pt_32 // Type S()
  48. eobPt = eob_pt_32 + 1
  49. }
  50. else if ( eobMultisize == 2 )
  51. {
  52. eob_pt_64 // Type S()
  53. eobPt = eob_pt_64 + 1
  54. }
  55. else if ( eobMultisize == 3 )
  56. {
  57. eob_pt_128 // Type S()
  58. eobPt = eob_pt_128 + 1
  59. }
  60. else if ( eobMultisize == 4 )
  61. {
  62. eob_pt_256 // Type S()
  63. eobPt = eob_pt_256 + 1
  64. }
  65. else if ( eobMultisize == 5 )
  66. {
  67. eob_pt_512 // Type S()
  68. eobPt = eob_pt_512 + 1
  69. }
  70. else
  71. {
  72. eob_pt_1024 // Type S()
  73. eobPt = eob_pt_1024 + 1
  74. }
  75. eob = ( eobPt < 2 ) ? eobPt : ( ( 1 << ( eobPt - 2 ) ) + 1 )
  76. eobShift = Max( -1, eobPt - 3 )
  77. if ( eobShift >= 0 )
  78. {
  79. eob_extra // Type S()
  80. if ( eob_extra )
  81. {
  82. eob += ( 1 << eobShift )
  83. }
  84. for ( i = 1; i < Max( 0, eobPt - 2 ); i++ )
  85. {
  86. eobShift = Max( 0, eobPt - 2 ) - 1 – i
  87. if ( eob_extra_bit )
  88. {
  89. eob += ( 1 << eobShift )
  90. }
  91. }
  92. }
  93. for ( c = eob - 1; c >= 0; c-- )
  94. {
  95. pos = scan[ c ]
  96. if ( c == ( eob - 1 ) )
  97. {
  98. coeff_base_eob // Type S()
  99. level = coeff_base_eob + 1
  100. }
  101. else
  102. {
  103. coeff_base // Type S()
  104. level = coeff_base
  105. }
  106. if ( level > NUM_BASE_LEVELS )
  107. {
  108. for ( idx = 0; idx < COEFF_BASE_RANGE / ( BR_CDF_SIZE - 1 ); idx++ )
  109. {
  110. coeff_br // Type S()
  111. level += coeff_br
  112. if ( coeff_br < ( BR_CDF_SIZE - 1 ) )
  113. break
  114. }
  115. }
  116. Quant[ pos ] = level
  117. }
  118. for ( c = 0; c < eob; c++ )
  119. {
  120. pos = scan[ c ]
  121. if ( Quant[ pos ] != 0 )
  122. {
  123. if ( c == 0 )
  124. {
  125. dc_sign // Type S()
  126. sign = dc_sign
  127. }
  128. else
  129. {
  130. sign_bit // Type L(1)
  131. sign = sign_bit
  132. }
  133. }
  134. else
  135. {
  136. sign = 0
  137. }
  138. if ( Quant[ pos ] > ( NUM_BASE_LEVELS + COEFF_BASE_RANGE ) )
  139. {
  140. length = 0
  141. do
  142. {
  143. length++
  144. golomb_length_bit // Type L(1)
  145. } while ( !golomb_length_bit )
  146. x = 1
  147. for ( i = length - 2; i >= 0; i-- )
  148. {
  149. golomb_data_bit // Type L(1)
  150. x = ( x << 1 ) | golomb_data_bit
  151. }
  152. Quant[ pos ] = x + COEFF_BASE_RANGE + NUM_BASE_LEVELS
  153. }
  154. if ( pos == 0 && Quant[ pos ] > 0 )
  155. {
  156. dcCategory = sign ? 1 : 2
  157. }
  158. Quant[ pos ] = Quant[ pos ] & 0xFFFFF
  159. culLevel += Quant[ pos ]
  160. if ( sign )
  161. Quant[ pos ] = - Quant[ pos ]
  162. }
  163. culLevel = Min( 63, culLevel )
  164. }
  165. for ( i = 0; i < w4; i++ )
  166. {
  167. AboveLevelContext[ plane ][ x4 + i ] = culLevel
  168. AboveDcContext[ plane ][ x4 + i ] = dcCategory
  169. }
  170. for ( i = 0; i < h4; i++ )
  171. {
  172. LeftLevelContext[ plane ][ y4 + i ] = culLevel
  173. LeftDcContext[ plane ][ y4 + i ] = dcCategory
  174. }
  175. return eob
  176. }

5.11.40 compute_tx_type函数

  1. compute_tx_type( plane, txSz, blockX, blockY )
  2. {
  3. txSzSqrUp = Tx_Size_Sqr_Up[ txSz ]
  4. if ( Lossless || txSzSqrUp > TX_32X32 )
  5. return DCT_DCT
  6. txSet = get_tx_set( txSz )
  7. if ( plane == 0 )
  8. {
  9. return TxTypes[ blockY ][ blockX ]
  10. }
  11. if ( is_inter )
  12. {
  13. x4 = Max( MiCol, blockX << subsampling_x )
  14. y4 = Max( MiRow, blockY << subsampling_y )
  15. txType = TxTypes[ y4 ][ x4 ]
  16. if ( !is_tx_type_in_set( txSet, txType ) )
  17. return DCT_DCT
  18. return txType
  19. }
  20. txType = Mode_To_Txfm[ UVMode ]
  21. if ( !is_tx_type_in_set( txSet, txType ) )
  22. return DCT_DCT
  23. return txType
  24. }
  25. is_tx_type_in_set( txSet, txType )
  26. {
  27. return is_inter ? Tx_Type_In_Set_Inter[ txSet ][ txType ] : Tx_Type_In_Set_Intra[ txSet ][ txType ]
  28. }

其中的常量查找表定义为,

  1. Tx_Type_In_Set_Intra[ TX_SET_TYPES_INTRA ][ TX_TYPES ] = {
  2. {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
  3. {1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,},
  4. {1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,}
  5. }
  6. Tx_Type_In_Set_Inter[ TX_SET_TYPES_INTER ][ TX_TYPES ] = {
  7. {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
  8. {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
  9. {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,},
  10. {1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,}
  11. }

5.11.41 get_mrow_scan函数

  1. get_mrow_scan( txSz )
  2. {
  3. if ( txSz == TX_4X4 )
  4. return Mrow_Scan_4x4
  5. else if ( txSz == TX_4X8 )
  6. return Mrow_Scan_4x8
  7. else if ( txSz == TX_8X4 )
  8. return Mrow_Scan_8x4
  9. else if ( txSz == TX_8X8 )
  10. return Mrow_Scan_8x8
  11. else if ( txSz == TX_8X16 )
  12. return Mrow_Scan_8x16
  13. else if ( txSz == TX_16X8 )
  14. return Mrow_Scan_16x8
  15. else if ( txSz == TX_16X16 )
  16. return Mrow_Scan_16x16
  17. else if ( txSz == TX_4X16 )
  18. return Mrow_Scan_4x16
  19. return Mrow_Scan_16x4
  20. }
  21. get_mcol_scan( txSz )
  22. {
  23. if ( txSz == TX_4X4 )
  24. return Mcol_Scan_4x4
  25. else if ( txSz == TX_4X8 )
  26. return Mcol_Scan_4x8
  27. else if ( txSz == TX_8X4 )
  28. return Mcol_Scan_8x4
  29. else if ( txSz == TX_8X8 )
  30. return Mcol_Scan_8x8
  31. else if ( txSz == TX_8X16 )
  32. return Mcol_Scan_8x16
  33. else if ( txSz == TX_16X8 )
  34. return Mcol_Scan_16x8
  35. else if ( txSz == TX_16X16 )
  36. return Mcol_Scan_16x16
  37. else if ( txSz == TX_4X16 )
  38. return Mcol_Scan_4x16
  39. return Mcol_Scan_16x4
  40. }
  41. get_default_scan( txSz )
  42. {
  43. if ( txSz == TX_4X4 )
  44. return Default_Scan_4x4
  45. else if ( txSz == TX_4X8 )
  46. return Default_Scan_4x8
  47. else if ( txSz == TX_8X4 )
  48. return Default_Scan_8x4
  49. else if ( txSz == TX_8X8 )
  50. return Default_Scan_8x8
  51. else if ( txSz == TX_8X16 )
  52. return Default_Scan_8x16
  53. else if ( txSz == TX_16X8 )
  54. return Default_Scan_16x8
  55. else if ( txSz == TX_16X16 )
  56. return Default_Scan_16x16
  57. else if ( txSz == TX_16X32 )
  58. return Default_Scan_16x32
  59. else if ( txSz == TX_32X16 )
  60. return Default_Scan_32x16
  61. else if ( txSz == TX_4X16 )
  62. return Default_Scan_4x16
  63. else if ( txSz == TX_16X4 )
  64. return Default_Scan_16x4
  65. else if ( txSz == TX_8X32 )
  66. return Default_Scan_8x32
  67. else if ( txSz == TX_32X8 )
  68. return Default_Scan_32x8
  69. return Default_Scan_32x32
  70. }
  71. get_scan( txSz )
  72. {
  73. if ( txSz == TX_16X64 )
  74. {
  75. return Default_Scan_16x32
  76. }
  77. if ( txSz == TX_64X16 )
  78. {
  79. return Default_Scan_32x16
  80. }
  81. if ( Tx_Size_Sqr_Up[ txSz ] == TX_64X64 )
  82. {
  83. return Default_Scan_32x32
  84. }
  85. if ( PlaneTxType == IDTX )
  86. {
  87. return get_default_scan( txSz )
  88. }
  89. preferRow = ( PlaneTxType == V_DCT || PlaneTxType == V_ADST || PlaneTxType == V_FLIPADST )
  90. preferCol = ( PlaneTxType == H_DCT || PlaneTxType == H_ADST || PlaneTxType == H_FLIPADST )
  91. if ( preferRow )
  92. {
  93. return get_mrow_scan( txSz )
  94. }
  95. else if ( preferCol )
  96. {
  97. return get_mcol_scan( txSz )
  98. }
  99. return get_default_scan( txSz )
  100. }

5.11.42 intra_angle_info_y语法

  1. intra_angle_info_y( )
  2. {
  3. AngleDeltaY = 0
  4. if ( MiSize >= BLOCK_8X8 )
  5. {
  6. if ( is_directional_mode( YMode ) )
  7. {
  8. angle_delta_y // Type S()
  9. AngleDeltaY = angle_delta_y - MAX_ANGLE_DELTA
  10. }
  11. }
  12. }

5.11.43 intra_angle_info_uv语法

  1. intra_angle_info_uv( )
  2. {
  3. AngleDeltaUV = 0
  4. if ( MiSize >= BLOCK_8X8 )
  5. {
  6. if ( is_directional_mode( UVMode ) )
  7. {
  8. angle_delta_uv // Type S()
  9. AngleDeltaUV = angle_delta_uv - MAX_ANGLE_DELTA
  10. }
  11. }
  12. }

5.11.44 is_directional_mode语法

  1. is_directional_mode( mode )
  2. {
  3. if ( ( mode >= V_PRED ) && ( mode <= D67_PRED ) )
  4. {
  5. return 1
  6. }
  7. return 0
  8. }

5.11.45 read_cfl_alphas语法

  1. read_cfl_alphas()
  2. {
  3. cfl_alpha_signs // Type S()
  4. signU = (cfl_alpha_signs + 1 ) / 3
  5. signV = (cfl_alpha_signs + 1 ) % 3
  6. if ( signU != CFL_SIGN_ZERO )
  7. {
  8. cfl_alpha_u // Type S()
  9. CflAlphaU = 1 + cfl_alpha_u
  10. if ( signU == CFL_SIGN_NEG )
  11. CflAlphaU = -CflAlphaU
  12. }
  13. else
  14. {
  15. CflAlphaU = 0
  16. }
  17. if ( signV != CFL_SIGN_ZERO )
  18. {
  19. cfl_alpha_v // Type S()
  20. CflAlphaV = 1 + cfl_alpha_v
  21. if ( signV == CFL_SIGN_NEG )
  22. CflAlphaV = -CflAlphaV
  23. }
  24. else
  25. {
  26. CflAlphaV = 0
  27. }
  28. }

5.11.46 palette_mode_info语法

  1. palette_mode_info( )
  2. {
  3. bsizeCtx = Mi_Width_Log2[ MiSize ] + Mi_Height_Log2[ MiSize ] - 2
  4. if ( YMode == DC_PRED )
  5. {
  6. has_palette_y // Type S()
  7. if ( has_palette_y )
  8. {
  9. palette_size_y_minus_2 // Type S()
  10. PaletteSizeY = palette_size_y_minus_2 + 2
  11. cacheN = get_palette_cache( 0 )
  12. idx = 0
  13. for ( i = 0; i < cacheN && idx < PaletteSizeY; i++ )
  14. {
  15. use_palette_color_cache_y // Type L(1)
  16. if ( use_palette_color_cache_y )
  17. {
  18. palette_colors_y[ idx ] = PaletteCache[ i ]
  19. idx++
  20. }
  21. }
  22. if ( idx < PaletteSizeY )
  23. {
  24. palette_colors_y[ idx ] // Type L(BitDepth)
  25. idx++
  26. }
  27. if ( idx < PaletteSizeY )
  28. {
  29. minBits = BitDepth - 3
  30. palette_num_extra_bits_y // Type L(2)
  31. paletteBits = minBits + palette_num_extra_bits_y
  32. }
  33. while ( idx < PaletteSizeY )
  34. {
  35. palette_delta_y // Type L(paletteBits)
  36. palette_delta_y++
  37. palette_colors_y[ idx ] = Clip1( palette_colors_y[ idx - 1 ] + palette_delta_y )
  38. range = ( 1 << BitDepth ) - palette_colors_y[ idx ] - 1
  39. paletteBits = Min( paletteBits, CeilLog2( range ) )
  40. idx++
  41. }
  42. sort( palette_colors_y, 0, PaletteSizeY - 1 )
  43. }
  44. }
  45. if ( HasChroma && UVMode == DC_PRED )
  46. {
  47. has_palette_uv // Type S()
  48. if ( has_palette_uv )
  49. {
  50. palette_size_uv_minus_2 // Type S()
  51. PaletteSizeUV = palette_size_uv_minus_2 + 2
  52. cacheN = get_palette_cache( 1 )
  53. idx = 0
  54. for ( i = 0; i < cacheN && idx < PaletteSizeUV; i++ )
  55. {
  56. use_palette_color_cache_u // Type L(1)
  57. if ( use_palette_color_cache_u )
  58. {
  59. palette_colors_u[ idx ] = PaletteCache[ i ]
  60. idx++
  61. }
  62. }
  63. if ( idx < PaletteSizeUV )
  64. {
  65. palette_colors_u[ idx ] // Type L(BitDepth)
  66. idx++
  67. }
  68. if ( idx < PaletteSizeUV )
  69. {
  70. minBits = BitDepth - 3
  71. palette_num_extra_bits_u // Type L(2)
  72. paletteBits = minBits + palette_num_extra_bits_u
  73. }
  74. while ( idx < PaletteSizeUV )
  75. {
  76. palette_delta_u // Type L(paletteBits)
  77. palette_colors_u[ idx ] = Clip1( palette_colors_u[ idx - 1 ] + palette_delta_u )
  78. range = ( 1 << BitDepth ) - palette_colors_u[ idx ]
  79. paletteBits = Min( paletteBits, CeilLog2( range ) )
  80. idx++
  81. }
  82. sort( palette_colors_u, 0, PaletteSizeUV - 1 )
  83. delta_encode_palette_colors_v // Type L(1)
  84. if ( delta_encode_palette_colors_v )
  85. {
  86. minBits = BitDepth - 4
  87. maxVal = 1 << BitDepth
  88. palette_num_extra_bits_v // Type L(2)
  89. paletteBits = minBits + palette_num_extra_bits_v
  90. palette_colors_v[ 0 ] // Type L(BitDepth)
  91. for ( idx = 1; idx < PaletteSizeUV; idx++ )
  92. {
  93. palette_delta_v // Type L(paletteBits)
  94. if ( palette_delta_v )
  95. {
  96. palette_delta_sign_bit_v // Type L(1)
  97. if ( palette_delta_sign_bit_v )
  98. {
  99. palette_delta_v = -palette_delta_v
  100. }
  101. }
  102. val = palette_colors_v[ idx - 1 ] + palette_delta_v
  103. if ( val < 0 ) val += maxVal
  104. if ( val >= maxVal ) val -= maxVal
  105. palette_colors_v[ idx ] = Clip1( val )
  106. }
  107. }
  108. else
  109. {
  110. for ( idx = 0; idx < PaletteSizeUV; idx++ )
  111. {
  112. palette_colors_v[ idx ] // Type L(BitDepth)
  113. }
  114. }
  115. }
  116. }
  117. }

函数sort(arr,i1,i2)按顺序对数组arr的子数组进行就地排序,要排序的子阵列在索引i1和i2之间。

注意:调色板颜色按升序生成,调色板缓存也按升序排列。这意味着可以在实现中通过合并两个排序列表替换sort函数。

其中的get_palette_cache函数定义如下,

  1. get_palette_cache( plane )
  2. {
  3. aboveN = 0
  4. if ( ( MiRow * MI_SIZE ) % 64 )
  5. {
  6. aboveN = PaletteSizes[ plane ][ MiRow - 1 ][ MiCol ]
  7. }
  8. leftN = 0
  9. if ( AvailL )
  10. {
  11. leftN = PaletteSizes[ plane ][ MiRow ][ MiCol - 1 ]
  12. }
  13. aboveIdx = 0
  14. leftIdx = 0
  15. n = 0
  16. while ( aboveIdx < aboveN && leftIdx < leftN )
  17. {
  18. aboveC = PaletteColors[ plane ][ MiRow - 1 ][ MiCol ][ aboveIdx ]
  19. leftC = PaletteColors[ plane ][ MiRow ][ MiCol - 1 ][ leftIdx ]
  20. if ( leftC < aboveC )
  21. {
  22. if ( n == 0 || leftC != PaletteCache[ n - 1 ] )
  23. {
  24. PaletteCache[ n ] = leftC
  25. n++
  26. }
  27. leftIdx++
  28. }
  29. else
  30. {
  31. if ( n == 0 || aboveC != PaletteCache[ n - 1 ] )
  32. {
  33. PaletteCache[ n ] = aboveC
  34. n++
  35. }
  36. aboveIdx++
  37. if ( leftC == aboveC )
  38. {
  39. leftIdx++
  40. }
  41. }
  42. }
  43. while ( aboveIdx < aboveN )
  44. {
  45. val = PaletteColors[ plane ][ MiRow - 1 ][ MiCol ][ aboveIdx ]
  46. aboveIdx++
  47. if ( n == 0 || val != PaletteCache[ n - 1 ] )
  48. {
  49. PaletteCache[ n ] = val
  50. n++
  51. }
  52. }
  53. while ( leftIdx < leftN )
  54. {
  55. val = PaletteColors[ plane ][ MiRow ][ MiCol - 1 ][ leftIdx ]
  56. leftIdx++
  57. if ( n == 0 || val != PaletteCache[ n - 1 ] )
  58. {
  59. PaletteCache[ n ] = val
  60. n++
  61. }
  62. }
  63. return n
  64. }

注意:get_palette_cache相当于从上方和左侧排列可用的调色板颜色并删除重复项。

5.11.47 transform_type语法

  1. transform_type( x4, y4, txSz )
  2. {
  3. set = get_tx_set( txSz )
  4. if ( set > 0 && ( segmentation_enabled ? get_qindex( 1, segment_id ) : base_q_idx ) > 0 )
  5. {
  6. if ( is_inter )
  7. {
  8. inter_tx_type // Type S()
  9. if ( set == TX_SET_INTER_1 )
  10. TxType = Tx_Type_Inter_Inv_Set1[ inter_tx_type ]
  11. else if ( set == TX_SET_INTER_2 )
  12. TxType = Tx_Type_Inter_Inv_Set2[ inter_tx_type ]
  13. else
  14. TxType = Tx_Type_Inter_Inv_Set3[ inter_tx_type ]
  15. }
  16. else
  17. {
  18. intra_tx_type // Type S()
  19. if ( set == TX_SET_INTRA_1 )
  20. TxType = Tx_Type_Intra_Inv_Set1[ intra_tx_type ]
  21. else
  22. TxType = Tx_Type_Intra_Inv_Set2[ intra_tx_type ]
  23. }
  24. }
  25. else
  26. {
  27. TxType = DCT_DCT
  28. }
  29. for ( i = 0; i < ( Tx_Width[ txSz ] >> 2 ); i++ )
  30. {
  31. for ( j = 0; j < ( Tx_Height[ txSz ] >> 2 ); j++ )
  32. {
  33. TxTypes[ y4 + j ][ x4 + i ] = TxType
  34. }
  35. }
  36. }

其中使用转换表定义如下,

  1. Tx_Type_Intra_Inv_Set1[ 7 ] = { IDTX, DCT_DCT, V_DCT, H_DCT, ADST_ADST, ADST_DCT, DCT_ADST }
  2. Tx_Type_Intra_Inv_Set2[ 5 ] = { IDTX, DCT_DCT, ADST_ADST, ADST_DCT, DCT_ADST }
  3. Tx_Type_Inter_Inv_Set1[ 16 ] = { IDTX, V_DCT, H_DCT, V_ADST, H_ADST, V_FLIPADST, H_FLIPADST, DCT_DCT, ADST_DCT, DCT_ADST, FLIPADST_DCT, DCT_FLIPADST, ADST_ADST, FLIPADST_FLIPADST, ADST_FLIPADST, FLIPADST_ADST }
  4. Tx_Type_Inter_Inv_Set2[ 12 ] = { IDTX, V_DCT, H_DCT, DCT_DCT, ADST_DCT, DCT_ADST, FLIPADST_DCT, DCT_FLIPADST, ADST_ADST, FLIPADST_FLIPADST, ADST_FLIPADST, LIPADST_ADST }
  5. Tx_Type_Inter_Inv_Set3[ 2 ] = { IDTX, DCT_DCT }

5.11.48 get_tx_set语法

  1. get_tx_set( txSz )
  2. {
  3. txSzSqr = Tx_Size_Sqr[ txSz ]
  4. txSzSqrUp = Tx_Size_Sqr_Up[ txSz ]
  5. if ( txSzSqrUp > TX_32X32 )
  6. return TX_SET_DCTONLY
  7. if ( is_inter )
  8. {
  9. if ( reduced_tx_set || txSzSqrUp == TX_32X32 )
  10. return TX_SET_INTER_3
  11. else if ( txSzSqr == TX_16X16 )
  12. return TX_SET_INTER_2
  13. return TX_SET_INTER_1
  14. }
  15. else
  16. {
  17. if ( txSzSqrUp == TX_32X32 ) return TX_SET_DCTONLY
  18. else if ( reduced_tx_set ) return TX_SET_INTRA_2
  19. else if ( txSzSqr == TX_16X16 ) return TX_SET_INTRA_2
  20. return TX_SET_INTRA_1
  21. }
  22. }

5.11.49 palette_tokens语法

  1. palette_tokens( )
  2. {
  3. blockHeight = Block_Height[ MiSize ]
  4. blockWidth = Block_Width[ MiSize ]
  5. onscreenHeight = Min( blockHeight, (MiRows - MiRow) * MI_SIZE )
  6. onscreenWidth = Min( blockWidth, (MiCols - MiCol) * MI_SIZE )
  7. if ( PaletteSizeY )
  8. {
  9. color_index_map_y // Type NS(PaletteSizeY)
  10. ColorMapY[0][0] = color_index_map_y
  11. for ( i = 1; i < onscreenHeight + onscreenWidth - 1; i++ )
  12. {
  13. for ( j = Min( i, onscreenWidth - 1 ); j >= Max( 0, i - onscreenHeight + 1 ); j-- )
  14. {
  15. get_palette_color_context(ColorMapY, ( i - j ), j, PaletteSizeY )
  16. palette_color_idx_y // Type S()
  17. ColorMapY[ i - j ][ j ] = ColorOrder[ palette_color_idx_y ]
  18. }
  19. }
  20. for ( i = 0; i < onscreenHeight; i++ )
  21. {
  22. for ( j = onscreenWidth; j < blockWidth; j++ )
  23. {
  24. ColorMapY[ i ][ j ] = ColorMapY[ i ][ onscreenWidth - 1 ]
  25. }
  26. }
  27. for ( i = onscreenHeight; i < blockHeight; i++ )
  28. {
  29. for ( j = 0; j < blockWidth; j++ )
  30. {
  31. ColorMapY[ i ][ j ] = ColorMapY[ onscreenHeight - 1 ][ j ]
  32. }
  33. }
  34. }
  35. if ( PaletteSizeUV )
  36. {
  37. color_index_map_uv // Type NS(PaletteSizeUV)
  38. ColorMapUV[0][0] = color_index_map_uv
  39. blockHeight = blockHeight >> subsampling_y
  40. blockWidth = blockWidth >> subsampling_x
  41. onscreenHeight = onscreenHeight >> subsampling_y
  42. onscreenWidth = onscreenWidth >> subsampling_x
  43. if ( blockWidth < 4 )
  44. {
  45. blockWidth += 2
  46. onscreenWidth += 2
  47. }
  48. if ( blockHeight < 4 )
  49. {
  50. blockHeight += 2
  51. onscreenHeight += 2
  52. }
  53. for ( i = 1; i < onscreenHeight + onscreenWidth - 1; i++ )
  54. {
  55. for ( j = Min( i, onscreenWidth - 1 ); j >= Max( 0, i - onscreenHeight + 1 ); j-- )
  56. {
  57. get_palette_color_context(ColorMapUV, ( i - j ), j, PaletteSizeUV )
  58. palette_color_idx_uv // Type S()
  59. ColorMapUV[ i - j ][ j ] = ColorOrder[ palette_color_idx_uv ]
  60. }
  61. }
  62. for ( i = 0; i < onscreenHeight; i++ )
  63. {
  64. for ( j = onscreenWidth; j < blockWidth; j++ )
  65. {
  66. ColorMapUV[ i ][ j ] = ColorMapUV[ i ][ onscreenWidth - 1 ]
  67. }
  68. }
  69. for ( i = onscreenHeight; i < blockHeight; i++ )
  70. {
  71. for ( j = 0; j < blockWidth; j++ )
  72. {
  73. ColorMapUV[ i ][ j ] = ColorMapUV[ onscreenHeight - 1 ][ j ]
  74. }
  75. }
  76. }
  77. }

5.11.50 get_palette_color_context函数

  1. get_palette_color_context( colorMap, r, c, n )
  2. {
  3. for ( i = 0; i < PALETTE_COLORS; i++ )
  4. {
  5. scores[ i ] = 0
  6. ColorOrder[i] = i
  7. }
  8. if ( c > 0 )
  9. {
  10. neighbor = colorMap[ r ][ c - 1 ]
  11. scores[ neighbor ] += 2
  12. }
  13. if ( ( r > 0 ) && ( c > 0 ) )
  14. {
  15. neighbor = colorMap[ r - 1 ][ c - 1 ]
  16. scores[ neighbor ] += 1
  17. }
  18. if ( r > 0 )
  19. {
  20. neighbor = colorMap[ r - 1 ][ c ]
  21. scores[ neighbor ] += 2
  22. }
  23. for ( i = 0; i < PALETTE_NUM_NEIGHBORS; i++ )
  24. {
  25. maxScore = scores[ i ]
  26. maxIdx = i
  27. for ( j = i + 1; j < n; j++ )
  28. {
  29. if ( scores[ j ] > maxScore )
  30. {
  31. maxScore = scores[ j ]
  32. maxIdx = j
  33. }
  34. }
  35. if ( maxIdx != i )
  36. {
  37. maxScore = scores[ maxIdx ]
  38. maxColorOrder = ColorOrder[ maxIdx ]
  39. for ( k = maxIdx; k > i; k-- )
  40. {
  41. scores[ k ] = scores[ k - 1 ]
  42. ColorOrder[ k ] = ColorOrder[ k - 1 ]
  43. }
  44. scores[ i ] = maxScore
  45. ColorOrder[ i ] = maxColorOrder
  46. }
  47. }
  48. ColorContextHash = 0
  49. for ( i = 0; i < PALETTE_NUM_NEIGHBORS; i++ )
  50. {
  51. ColorContextHash += scores[ i ] * Palette_Color_Hash_Multipliers[ i ]
  52. }
  53. }

5.11.51 is_inside函数

  1. is_inside( candidateR, candidateC )
  2. {
  3. return ( candidateC >= MiColStart && candidateC < MiColEnd && candidateR >= MiRowStart && candidateR < MiRowEnd )
  4. }

5.11.52 is_inside_filter_region函数

  1. is_inside_filter_region( candidateR, candidateC )
  2. {
  3. colStart = 0
  4. colEnd = MiCols
  5. rowStart = 0
  6. rowEnd = MiRows
  7. return (candidateC >= colStart && candidateC < colEnd && candidateR >= rowStart && candidateR < rowEnd)
  8. }

5.11.53 clamp_mv_row函数

  1. clamp_mv_row( mvec, border )
  2. {
  3. bh4 = Num_4x4_Blocks_High[ MiSize ]
  4. mbToTopEdge = -((MiRow * MI_SIZE) * 8)
  5. mbToBottomEdge = ((MiRows - bh4 - MiRow) * MI_SIZE) * 8
  6. return Clip3( mbToTopEdge - border, mbToBottomEdge + border, mvec )
  7. }

5.11.54 clamp_mv_col函数

  1. clamp_mv_col( mvec, border )
  2. {
  3. bw4 = Num_4x4_Blocks_Wide[ MiSize ]
  4. mbToLeftEdge = -((MiCol * MI_SIZE) * 8)
  5. mbToRightEdge = ((MiCols - bw4 - MiCol) * MI_SIZE) * 8
  6. return Clip3( mbToLeftEdge - border, mbToRightEdge + border, mvec )
  7. }

5.11.55 clear_cdef函数

  1. clear_cdef( r, c )
  2. {
  3. cdef_idx[ r ][ c ] = -1
  4. if ( use_128x128_superblock )
  5. {
  6. cdefSize4 = Num_4x4_Blocks_Wide[ BLOCK_64X64 ]
  7. cdef_idx[ r ][ c + cdefSize4 ] = -1
  8. cdef_idx[ r + cdefSize4][ c ] = -1
  9. cdef_idx[ r + cdefSize4][ c + cdefSize4 ] = -1
  10. }
  11. }

5.11.56 read_cdef语法

  1. read_cdef( )
  2. {
  3. if ( skip || CodedLossless || !enable_cdef || allow_intrabc)
  4. {
  5. return
  6. }
  7. cdefSize4 = Num_4x4_Blocks_Wide[ BLOCK_64X64 ]
  8. cdefMask4 = ~(cdefSize4 - 1)
  9. r = MiRow & cdefMask4
  10. c = MiCol & cdefMask4
  11. if ( cdef_idx[ r ][ c ] == -1 )
  12. {
  13. cdef_idx[ r ][ c ] // Type L(cdef_bits)
  14. w4 = Num_4x4_Blocks_Wide[ MiSize ]
  15. h4 = Num_4x4_Blocks_High[ MiSize ]
  16. for ( i = r; i < r + h4 ; i += cdefSize4 )
  17. {
  18. for ( j = c; j < c + w4 ; j += cdefSize4 )
  19. {
  20. cdef_idx[ i ][ j ] = cdef_idx[ r ][ c ]
  21. }
  22. }
  23. }
  24. }

5.11.57 read_Ir语法

  1. read_lr( r, c, bSize )
  2. {
  3. if ( allow_intrabc )
  4. {
  5. return
  6. }
  7. w = Num_4x4_Blocks_Wide[ bSize ]
  8. h = Num_4x4_Blocks_High[ bSize ]
  9. for ( plane = 0; plane < NumPlanes; plane++ )
  10. {
  11. if ( FrameRestorationType[ plane ] != RESTORE_NONE )
  12. {
  13. subX = (plane == 0) ? 0 : subsampling_x
  14. subY = (plane == 0) ? 0 : subsampling_y
  15. unitSize = LoopRestorationSize[ plane ]
  16. unitRows = count_units_in_frame( unitSize, Round2( FrameHeight, subY) )
  17. unitCols = count_units_in_frame( unitSize, Round2( UpscaledWidth, subX) )
  18. unitRowStart = ( r * ( MI_SIZE >> subY) + unitSize - 1 ) / unitSize
  19. unitRowEnd = Min( unitRows, ( (r + h) * ( MI_SIZE >> subY) + unitSize - 1 ) / unitSize)
  20. if ( use_superres )
  21. {
  22. numerator = (MI_SIZE >> subX) * SuperresDenom
  23. denominator = unitSize * SUPERRES_NUM
  24. }
  25. else
  26. {
  27. numerator = MI_SIZE >> subX
  28. denominator = unitSize
  29. }
  30. unitColStart = ( c * numerator + denominator - 1 ) / denominator
  31. unitColEnd = Min( unitCols, ( (c + w) * numerator + denominator - 1 ) / denominator)
  32. for ( unitRow = unitRowStart; unitRow < unitRowEnd; unitRow++ )
  33. {
  34. for ( unitCol = unitColStart; unitCol < unitColEnd; unitCol++ )
  35. {
  36. read_lr_unit(plane, unitRow, unitCol)
  37. }
  38. }
  39. }
  40. }
  41. }

其中的count_units_in_frame函数定义如下,

  1. count_units_in_frame(unitSize, frameSize)
  2. {
  3. return Max((frameSize + (unitSize >> 1)) / unitSize, 1)
  4. }

5.11.58 read_lr_unit语法

  1. read_lr_unit(plane, unitRow, unitCol)
  2. {
  3. if ( FrameRestorationType[ plane ] == RESTORE_WIENER )
  4. {
  5. use_wiener // Type S()
  6. restoration_type = use_wiener ? RESTORE_WIENER : RESTORE_NONE
  7. }
  8. else if ( FrameRestorationType[ plane ] == RESTORE_SGRPROJ )
  9. {
  10. use_sgrproj // Type S()
  11. restoration_type = use_sgrproj ? RESTORE_SGRPROJ : RESTORE_NONE
  12. }
  13. else
  14. {
  15. restoration_type // Type S()
  16. }
  17. LrType[ plane ][ unitRow ][ unitCol ] = restoration_type
  18. if ( restoration_type == RESTORE_WIENER )
  19. {
  20. for ( pass = 0; pass < 2; pass++ )
  21. {
  22. if ( plane )
  23. {
  24. firstCoeff = 1
  25. LrWiener[ plane ][ unitRow ][ unitCol ][ pass ][0] = 0
  26. }
  27. else
  28. {
  29. firstCoeff = 0
  30. }
  31. for ( j = firstCoeff; j < 3; j++ )
  32. {
  33. min = Wiener_Taps_Min[ j ]
  34. max = Wiener_Taps_Max[ j ]
  35. k = Wiener_Taps_K[ j ]
  36. v = decode_signed_subexp_with_ref_bool(min, max + 1, k, RefLrWiener[ plane ][ pass ][ j ] )
  37. LrWiener[ plane ][ unitRow ][ unitCol ][ pass ][ j ] = v
  38. RefLrWiener[ plane ][ pass ][ j ] = v
  39. }
  40. }
  41. }
  42. else if ( restoration_type == RESTORE_SGRPROJ )
  43. {
  44. lr_sgr_set // Type L(SGRPROJ_PARAMS_BITS)
  45. LrSgrSet[ plane ][ unitRow ][ unitCol ] = lr_sgr_set
  46. for ( i = 0; i < 2; i++ )
  47. {
  48. radius = Sgr_Params[ lr_sgr_set ][ i * 2 ]
  49. min = Sgrproj_Xqd_Min[i]
  50. max = Sgrproj_Xqd_Max[i]
  51. if ( radius )
  52. {
  53. v = decode_signed_subexp_with_ref_bool(min, max + 1, SGRPROJ_PRJ_SUBEXP_K, RefSgrXqd[ plane ][ i ])
  54. }
  55. else
  56. {
  57. v = 0
  58. if ( i == 1 )
  59. {
  60. v = Clip3( min, max, (1 << SGRPROJ_PRJ_BITS) - RefSgrXqd[ plane ][ 0 ] )
  61. }
  62. }
  63. LrSgrXqd[ plane ][ unitRow ][ unitCol ][ i ] = v
  64. RefSgrXqd[ plane ][ i ] = v
  65. }
  66. }
  67. }

其中的常量查找表和函数定义如下,

  1. Wiener_Taps_Min[3] = { -5, -23, -17 }
  2. Wiener_Taps_Max[3] = { 10, 8, 46 }
  3. Wiener_Taps_K[3] = { 1, 2, 3 }
  4. Sgrproj_Xqd_Min[2] = { -96, -32 }
  5. Sgrproj_Xqd_Max[2] = { 31, 95 }
  6. decode_signed_subexp_with_ref_bool( low, high, k, r )
  7. {
  8. x = decode_unsigned_subexp_with_ref_bool(high - low, k, r - low)
  9. return x + low
  10. }
  11. decode_unsigned_subexp_with_ref_bool( mx, k, r )
  12. {
  13. v = decode_subexp_bool( mx, k )
  14. if ( (r << 1) <= mx )
  15. {
  16. return inverse_recenter(r, v)
  17. }
  18. else
  19. {
  20. return mx - 1 - inverse_recenter(mx - 1 - r, v)
  21. }
  22. }
  23. decode_subexp_bool( numSyms, k )
  24. {
  25. i = 0
  26. mk = 0
  27. while ( 1 )
  28. {
  29. b2 = i ? k + i - 1 : k
  30. a = 1 << b2
  31. if ( numSyms <= mk + 3 * a )
  32. {
  33. subexp_unif_bools // Type NS(numSyms - mk)
  34. return subexp_unif_bools + mk
  35. }
  36. else
  37. {
  38. subexp_more_bools // Type L(1)
  39. if ( subexp_more_bools )
  40. {
  41. i++
  42. mk += a
  43. }
  44. else
  45. {
  46. subexp_bools // Type L(b2)
  47. return subexp_bools + mk
  48. }
  49. }
  50. }
  51. }

注意:decode_signed_subexp_with_ref_bool函数与decode_signed_subexp_with_ref函数相同,除了用于表示符号的比特是算术编码而不是直接从比特流读取。

5.12 Tile列表OBU语法

5.12.1 tile_list_obu语法

  1. tile_list_obu( )
  2. {
  3. output_frame_width_in_tiles_minus_1 // Type f(8)
  4. output_frame_height_in_tiles_minus_1 // Type f(8)
  5. tile_count_minus_1 // Type f(16)
  6. for ( tile = 0; tile <= tile_count_minus_1; tile++ )
  7. tile_list_entry( )
  8. }

5.12.2 tile_list_entry语法

  1. tile_list_entry( )
  2. {
  3. anchor_frame_idx // Type f(8)
  4. anchor_tile_row // Type f(8)
  5. anchor_tile_col // Type f(8)
  6. tile_data_size_minus_1 // Type f(16)
  7. N = 8 * (tile_data_size_minus_1 + 1)
  8. coded_tile_data // Type f(N)
  9. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/468083
推荐阅读
相关标签
  

闽ICP备14008679号