| @@ -3831,10 +3831,37 @@ static void assign_partition_info( · 3830 unmodified lines |
| 3831 | } | 3831 | } |
| 3832 | } | 3832 | } |
| 3833 | } | 3833 | } |
| 3834 | static void store_superblock_partition_info( | 3834 | |
| 3835 | const PC_TREE *const pc_tree, PARTITION_INFO *partition_info, | 3835 | static void assign_motion_vector_info(const int block_width_4x4, |
| 3836 | const int square_size_4x4, const int num_unit_rows, const int num_unit_cols, | 3836 | const int block_height_4x4, |
| 3837 | const int row_start_4x4, const int col_start_4x4) { | 3837 | const int row_start_4x4, |
| | 3838 | const int col_start_4x4, |
| | 3839 | const int num_unit_rows, |
| | 3840 | const int num_unit_cols, MV *source_mv[2], |
| | 3841 | MV_REFERENCE_FRAME source_ref_frame[2], |
| | 3842 | MOTION_VECTOR_INFO *motion_vector_info) { |
| | 3843 | int i, j; |
| | 3844 | for (i = 0; i < block_height_4x4; ++i) { |
| | 3845 | for (j = 0; j < block_width_4x4; ++j) { |
| | 3846 | const int row_4x4 = row_start_4x4 + i; |
| | 3847 | const int col_4x4 = col_start_4x4 + j; |
| | 3848 | const int unit_index = row_4x4 * num_unit_cols + col_4x4; |
| | 3849 | if (row_4x4 >= num_unit_rows || col_4x4 >= num_unit_cols) continue; |
| | 3850 | motion_vector_info[unit_index].ref_frame[0] = source_ref_frame[0]; |
| | 3851 | motion_vector_info[unit_index].ref_frame[1] = source_ref_frame[1]; |
| | 3852 | motion_vector_info[unit_index].mv[0].as_mv.row = source_mv[0]->row; |
| | 3853 | motion_vector_info[unit_index].mv[0].as_mv.col = source_mv[0]->col; |
| | 3854 | motion_vector_info[unit_index].mv[1].as_mv.row = source_mv[1]->row; |
| | 3855 | motion_vector_info[unit_index].mv[1].as_mv.col = source_mv[1]->col; |
| | 3856 | } |
| | 3857 | } |
| | 3858 | } |
| | 3859 | |
| | 3860 | static void store_superblock_info( |
| | 3861 | const PC_TREE *const pc_tree, MODE_INFO **mi_grid_visible, |
| | 3862 | const int mi_stride, const int square_size_4x4, const int num_unit_rows, |
| | 3863 | const int num_unit_cols, const int row_start_4x4, const int col_start_4x4, |
| | 3864 | PARTITION_INFO *partition_info, MOTION_VECTOR_INFO *motion_vector_info) { |
| 3838 | const int subblock_square_size_4x4 = square_size_4x4 >> 1; | 3865 | const int subblock_square_size_4x4 = square_size_4x4 >> 1; |
| 3839 | if (row_start_4x4 >= num_unit_rows || col_start_4x4 >= num_unit_cols) return; | 3866 | if (row_start_4x4 >= num_unit_rows || col_start_4x4 >= num_unit_cols) return; |
| 3840 | assert(pc_tree->partitioning != PARTITION_INVALID); | 3867 | assert(pc_tree->partitioning != PARTITION_INVALID); |
| @@ -3842,6 +3869,14 @@ static void store_superblock_partition_info( · 1 unmodified line |
| 3842 | if (pc_tree->partitioning == PARTITION_NONE || | 3869 | if (pc_tree->partitioning == PARTITION_NONE || |
| 3843 | pc_tree->partitioning == PARTITION_HORZ || | 3870 | pc_tree->partitioning == PARTITION_HORZ || |
| 3844 | pc_tree->partitioning == PARTITION_VERT || square_size_4x4 == 1) { | 3871 | pc_tree->partitioning == PARTITION_VERT || square_size_4x4 == 1) { |
| | 3872 | const int mi_row = row_start_4x4 >> 1; |
| | 3873 | const int mi_col = col_start_4x4 >> 1; |
| | 3874 | const int mi_idx = mi_stride * mi_row + mi_col; |
| | 3875 | MODE_INFO **mi = mi_grid_visible + mi_idx; |
| | 3876 | MV *source_mv[2]; |
| | 3877 | MV_REFERENCE_FRAME source_ref_frame[2]; |
| | 3878 | |
| | 3879 | // partition info |
| 3845 | const int block_width_4x4 = (pc_tree->partitioning == PARTITION_VERT) | 3880 | const int block_width_4x4 = (pc_tree->partitioning == PARTITION_VERT) |
| 3846 | ? square_size_4x4 >> 1 | 3881 | ? square_size_4x4 >> 1 |
| 3847 | : square_size_4x4; | 3882 | : square_size_4x4; |
| @@ -3861,25 +3896,124 @@ static void store_superblock_partition_info( · 13 unmodified lines |
| 3861 | num_unit_cols, partition_info); | 3896 | num_unit_cols, partition_info); |
| 3862 | } | 3897 | } |
| 3863 | | 3898 | |
| | 3899 | // motion vector info |
| | 3900 | if (pc_tree->partitioning == PARTITION_HORZ) { |
| | 3901 | int is_valid_second_rectangle = 0; |
| | 3902 | assert(square_size_4x4 > 1); |
| | 3903 | // First rectangle. |
| | 3904 | source_ref_frame[0] = mi[0]->ref_frame[0]; |
| | 3905 | source_ref_frame[1] = mi[0]->ref_frame[1]; |
| | 3906 | source_mv[0] = &mi[0]->mv[0].as_mv; |
| | 3907 | source_mv[1] = &mi[0]->mv[1].as_mv; |
| | 3908 | assign_motion_vector_info(block_width_4x4, block_height_4x4, |
| | 3909 | row_start_4x4, col_start_4x4, num_unit_rows, |
| | 3910 | num_unit_cols, source_mv, source_ref_frame, |
| | 3911 | motion_vector_info); |
| | 3912 | // Second rectangle. |
| | 3913 | if (square_size_4x4 == 2) { |
| | 3914 | is_valid_second_rectangle = 1; |
| | 3915 | source_ref_frame[0] = mi[0]->ref_frame[0]; |
| | 3916 | source_ref_frame[1] = mi[0]->ref_frame[1]; |
| | 3917 | source_mv[0] = &mi[0]->bmi[2].as_mv[0].as_mv; |
| | 3918 | source_mv[1] = &mi[0]->bmi[2].as_mv[1].as_mv; |
| | 3919 | } else { |
| | 3920 | const int mi_row_2 = mi_row + (block_height_4x4 >> 1); |
| | 3921 | const int mi_col_2 = mi_col; |
| | 3922 | if (mi_row_2 * 2 < num_unit_rows && mi_col_2 * 2 < num_unit_cols) { |
| | 3923 | const int mi_idx_2 = mi_stride * mi_row_2 + mi_col_2; |
| | 3924 | is_valid_second_rectangle = 1; |
| | 3925 | mi = mi_grid_visible + mi_idx_2; |
| | 3926 | source_ref_frame[0] = mi[0]->ref_frame[0]; |
| | 3927 | source_ref_frame[1] = mi[0]->ref_frame[1]; |
| | 3928 | source_mv[0] = &mi[0]->mv[0].as_mv; |
| | 3929 | source_mv[1] = &mi[0]->mv[1].as_mv; |
| | 3930 | } |
| | 3931 | } |
| | 3932 | if (is_valid_second_rectangle) { |
| | 3933 | assign_motion_vector_info( |
| | 3934 | block_width_4x4, block_height_4x4, row_start_4x4 + block_height_4x4, |
| | 3935 | col_start_4x4, num_unit_rows, num_unit_cols, source_mv, |
| | 3936 | source_ref_frame, motion_vector_info); |
| | 3937 | } |
| | 3938 | } else if (pc_tree->partitioning == PARTITION_VERT) { |
| | 3939 | int is_valid_second_rectangle = 0; |
| | 3940 | assert(square_size_4x4 > 1); |
| | 3941 | // First rectangle. |
| | 3942 | source_ref_frame[0] = mi[0]->ref_frame[0]; |
| | 3943 | source_ref_frame[1] = mi[0]->ref_frame[1]; |
| | 3944 | source_mv[0] = &mi[0]->mv[0].as_mv; |
| | 3945 | source_mv[1] = &mi[0]->mv[1].as_mv; |
| | 3946 | assign_motion_vector_info(block_width_4x4, block_height_4x4, |
| | 3947 | row_start_4x4, col_start_4x4, num_unit_rows, |
| | 3948 | num_unit_cols, source_mv, source_ref_frame, |
| | 3949 | motion_vector_info); |
| | 3950 | // Second rectangle. |
| | 3951 | if (square_size_4x4 == 2) { |
| | 3952 | is_valid_second_rectangle = 1; |
| | 3953 | source_ref_frame[0] = mi[0]->ref_frame[0]; |
| | 3954 | source_ref_frame[1] = mi[0]->ref_frame[1]; |
| | 3955 | source_mv[0] = &mi[0]->bmi[1].as_mv[0].as_mv; |
| | 3956 | source_mv[1] = &mi[0]->bmi[1].as_mv[1].as_mv; |
| | 3957 | } else { |
| | 3958 | const int mi_row_2 = mi_row; |
| | 3959 | const int mi_col_2 = mi_col + (block_width_4x4 >> 1); |
| | 3960 | if (mi_row_2 * 2 < num_unit_rows && mi_col_2 * 2 < num_unit_cols) { |
| | 3961 | const int mi_idx_2 = mi_stride * mi_row_2 + mi_col_2; |
| | 3962 | is_valid_second_rectangle = 1; |
| | 3963 | mi = mi_grid_visible + mi_idx_2; |
| | 3964 | source_ref_frame[0] = mi[0]->ref_frame[0]; |
| | 3965 | source_ref_frame[1] = mi[0]->ref_frame[1]; |
| | 3966 | source_mv[0] = &mi[0]->mv[0].as_mv; |
| | 3967 | source_mv[1] = &mi[0]->mv[1].as_mv; |
| | 3968 | } |
| | 3969 | } |
| | 3970 | if (is_valid_second_rectangle) { |
| | 3971 | assign_motion_vector_info( |
| | 3972 | block_width_4x4, block_height_4x4, row_start_4x4, |
| | 3973 | col_start_4x4 + block_width_4x4, num_unit_rows, num_unit_cols, |
| | 3974 | source_mv, source_ref_frame, motion_vector_info); |
| | 3975 | } |
| | 3976 | } else { |
| | 3977 | assert(pc_tree->partitioning == PARTITION_NONE || square_size_4x4 == 1); |
| | 3978 | source_ref_frame[0] = mi[0]->ref_frame[0]; |
| | 3979 | source_ref_frame[1] = mi[0]->ref_frame[1]; |
| | 3980 | if (square_size_4x4 == 1) { |
| | 3981 | const int sub8x8_row = row_start_4x4 % 2; |
| | 3982 | const int sub8x8_col = col_start_4x4 % 2; |
| | 3983 | const int sub8x8_idx = sub8x8_row * 2 + sub8x8_col; |
| | 3984 | source_mv[0] = &mi[0]->bmi[sub8x8_idx].as_mv[0].as_mv; |
| | 3985 | source_mv[1] = &mi[0]->bmi[sub8x8_idx].as_mv[1].as_mv; |
| | 3986 | } else { |
| | 3987 | source_mv[0] = &mi[0]->mv[0].as_mv; |
| | 3988 | source_mv[1] = &mi[0]->mv[1].as_mv; |
| | 3989 | } |
| | 3990 | assign_motion_vector_info(block_width_4x4, block_height_4x4, |
| | 3991 | row_start_4x4, col_start_4x4, num_unit_rows, |
| | 3992 | num_unit_cols, source_mv, source_ref_frame, |
| | 3993 | motion_vector_info); |
| | 3994 | } |
| | 3995 | |
| 3864 | return; | 3996 | return; |
| 3865 | } | 3997 | } |
| 3866 | // recursively traverse partition tree when partition is split. | 3998 | // recursively traverse partition tree when partition is split. |
| 3867 | assert(pc_tree->partitioning == PARTITION_SPLIT); | 3999 | assert(pc_tree->partitioning == PARTITION_SPLIT); |
| 3868 | store_superblock_partition_info(pc_tree->split[0], partition_info, | 4000 | store_superblock_info(pc_tree->split[0], mi_grid_visible, mi_stride, |
| 3869 | subblock_square_size_4x4, num_unit_rows, | 4001 | subblock_square_size_4x4, num_unit_rows, num_unit_cols, |
| 3870 | num_unit_cols, row_start_4x4, col_start_4x4); | 4002 | row_start_4x4, col_start_4x4, partition_info, |
| 3871 | store_superblock_partition_info(pc_tree->split[1], partition_info, | 4003 | motion_vector_info); |
| 3872 | subblock_square_size_4x4, num_unit_rows, | 4004 | store_superblock_info(pc_tree->split[1], mi_grid_visible, mi_stride, |
| 3873 | num_unit_cols, row_start_4x4, | 4005 | subblock_square_size_4x4, num_unit_rows, num_unit_cols, |
| 3874 | col_start_4x4 + subblock_square_size_4x4); | 4006 | row_start_4x4, col_start_4x4 + subblock_square_size_4x4, |
| 3875 | store_superblock_partition_info( | 4007 | partition_info, motion_vector_info); |
| 3876 | pc_tree->split[2], partition_info, subblock_square_size_4x4, | 4008 | store_superblock_info(pc_tree->split[2], mi_grid_visible, mi_stride, |
| 3877 | num_unit_rows, num_unit_cols, row_start_4x4 + subblock_square_size_4x4, | 4009 | subblock_square_size_4x4, num_unit_rows, num_unit_cols, |
| 3878 | col_start_4x4); | 4010 | row_start_4x4 + subblock_square_size_4x4, col_start_4x4, |
| 3879 | store_superblock_partition_info( | 4011 | partition_info, motion_vector_info); |
| 3880 | pc_tree->split[3], partition_info, subblock_square_size_4x4, | 4012 | store_superblock_info(pc_tree->split[3], mi_grid_visible, mi_stride, |
| 3881 | num_unit_rows, num_unit_cols, row_start_4x4 + subblock_square_size_4x4, | 4013 | subblock_square_size_4x4, num_unit_rows, num_unit_cols, |
| 3882 | col_start_4x4 + subblock_square_size_4x4); | 4014 | row_start_4x4 + subblock_square_size_4x4, |
| | 4015 | col_start_4x4 + subblock_square_size_4x4, |
| | 4016 | partition_info, motion_vector_info); |
| 3883 | } | 4017 | } |
| 3884 | #endif // CONFIG_RATE_CTRL | 4018 | #endif // CONFIG_RATE_CTRL |
| 3885 | | 4019 | |
| @@ -4458,13 +4592,15 @@ static int rd_pick_partition(VP9_COMP *cpi, ThreadData *td, · 572 unmodified lines |
| 4458 | encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize, | 4592 | encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize, |
| 4459 | pc_tree); | 4593 | pc_tree); |
| 4460 | #if CONFIG_RATE_CTRL | 4594 | #if CONFIG_RATE_CTRL |
| 4461 | // Store partition info. | 4595 | // Store partition, motion vector of the superblock. |
| 4462 | if (output_enabled) { | 4596 | if (output_enabled) { |
| 4463 | const int num_unit_rows = get_num_unit_4x4(cpi->frame_info.frame_height); | 4597 | const int num_unit_rows = get_num_unit_4x4(cpi->frame_info.frame_height); |
| 4464 | const int num_unit_cols = get_num_unit_4x4(cpi->frame_info.frame_width); | 4598 | const int num_unit_cols = get_num_unit_4x4(cpi->frame_info.frame_width); |
| 4465 | store_superblock_partition_info( | 4599 | store_superblock_info(pc_tree, cm->mi_grid_visible, cm->mi_stride, |
| 4466 | pc_tree, cpi->partition_info, num_4x4_blocks_wide_lookup[BLOCK_64X64], | 4600 | num_4x4_blocks_wide_lookup[BLOCK_64X64], |
| 4467 | num_unit_rows, num_unit_cols, mi_row << 1, mi_col << 1); | 4601 | num_unit_rows, num_unit_cols, mi_row << 1, |
| | 4602 | mi_col << 1, cpi->partition_info, |
| | 4603 | cpi->motion_vector_info); |
| 4468 | } | 4604 | } |
| 4469 | #endif // CONFIG_RATE_CTRL | 4605 | #endif // CONFIG_RATE_CTRL |
| 4470 | } | 4606 | } |