History

Store frame motion vector info

Allocate motion vector information for the frame, and store it when a superblock (64x64) is encoded. The unit size of the smallest block is 4x4. A special requirement by the vp9 spec is that sub 8x8 blocks of a 8x8 block must have the same reference frame. There is no such requirement for blocks large or equal to 8x8.

Cheng Chen committed 6 years ago

Commit e582df21 parent 5be37813 files · +189 −23Browse files

Unified · Split

3 files
  1. vp9/encoder/vp9_encodeframe.c +159 −23
  2. vp9/encoder/vp9_encoder.c +2 −0
  3. vp9/encoder/vp9_encoder.h +28 −0
vp9/encoder/vp9_encodeframe.c+159−23
@@ -3831,10 +3831,37 @@ static void assign_partition_info( · 3830 unmodified lines
3831 }3831 }
3832 }3832 }
3833}3833}
3834static void store_superblock_partition_info(3834
3835 const PC_TREE *const pc_tree, PARTITION_INFO *partition_info,3835static 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
3860static 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 >> 13881 ? 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_CTRL4018#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_CTRL4594#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_CTRL4605#endif // CONFIG_RATE_CTRL
4470 }4606 }
vp9/encoder/vp9_encoder.c+2−0
@@ -1023,6 +1023,7 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { · 1022 unmodified lines
1023 1023
1024#if CONFIG_RATE_CTRL1024#if CONFIG_RATE_CTRL
1025 free_partition_info(cpi);1025 free_partition_info(cpi);
1026 free_motion_vector_info(cpi);
1026#endif1027#endif
1027 1028
1028 vp9_free_ref_frame_buffers(cm->buffer_pool);1029 vp9_free_ref_frame_buffers(cm->buffer_pool);
@@ -2654,6 +2655,7 @@ VP9_COMP *vp9_create_compressor(const VP9EncoderConfig *oxcf, · 1625 unmodified lines
2654#if CONFIG_RATE_CTRL2655#if CONFIG_RATE_CTRL
2655 encode_command_init(&cpi->encode_command);2656 encode_command_init(&cpi->encode_command);
2656 partition_info_init(cpi);2657 partition_info_init(cpi);
2658 motion_vector_info_init(cpi);
2657#endif2659#endif
2658 2660
2659 return cpi;2661 return cpi;
vp9/encoder/vp9_encoder.h+28−0
@@ -532,6 +532,11 @@ typedef struct PARTITION_INFO { · 531 unmodified lines
532 int height; // prediction block height532 int height; // prediction block height
533} PARTITION_INFO;533} PARTITION_INFO;
534 534
535typedef struct MOTION_VECTOR_INFO {
536 MV_REFERENCE_FRAME ref_frame[2];
537 int_mv mv[2];
538} MOTION_VECTOR_INFO;
539
535static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) {540static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) {
536 vp9_zero(*encode_command);541 vp9_zero(*encode_command);
537 encode_command->use_external_quantize_index = 0;542 encode_command->use_external_quantize_index = 0;
@@ -862,6 +867,7 @@ typedef struct VP9_COMP { · 324 unmodified lines
862#if CONFIG_RATE_CTRL867#if CONFIG_RATE_CTRL
863 ENCODE_COMMAND encode_command;868 ENCODE_COMMAND encode_command;
864 PARTITION_INFO *partition_info;869 PARTITION_INFO *partition_info;
870 MOTION_VECTOR_INFO *motion_vector_info;
865#endif871#endif
866} VP9_COMP;872} VP9_COMP;
867 873
@@ -886,6 +892,27 @@ static INLINE void free_partition_info(struct VP9_COMP *cpi) { · 18 unmodified lines
886 vpx_free(cpi->partition_info);892 vpx_free(cpi->partition_info);
887 cpi->partition_info = NULL;893 cpi->partition_info = NULL;
888}894}
895
896// Allocates memory for the motion vector information.
897// The unit size is each 4x4 block.
898// Only called once in vp9_create_compressor().
899static INLINE void motion_vector_info_init(struct VP9_COMP *cpi) {
900 VP9_COMMON *const cm = &cpi->common;
901 const int unit_width = get_num_unit_4x4(cpi->frame_info.frame_width);
902 const int unit_height = get_num_unit_4x4(cpi->frame_info.frame_height);
903 CHECK_MEM_ERROR(cm, cpi->motion_vector_info,
904 (MOTION_VECTOR_INFO *)vpx_calloc(unit_width * unit_height,
905 sizeof(MOTION_VECTOR_INFO)));
906 memset(cpi->motion_vector_info, 0,
907 unit_width * unit_height * sizeof(MOTION_VECTOR_INFO));
908}
909
910// Frees memory of the motion vector information.
911// Only called once in dealloc_compressor_data().
912static INLINE void free_motion_vector_info(struct VP9_COMP *cpi) {
913 vpx_free(cpi->motion_vector_info);
914 cpi->motion_vector_info = NULL;
915}
889#endif // CONFIG_RATE_CTRL916#endif // CONFIG_RATE_CTRL
890 917
891typedef struct ENCODE_FRAME_RESULT {918typedef struct ENCODE_FRAME_RESULT {
@@ -896,6 +923,7 @@ typedef struct ENCODE_FRAME_RESULT { · 4 unmodified lines
896 uint64_t sse;923 uint64_t sse;
897 FRAME_COUNTS frame_counts;924 FRAME_COUNTS frame_counts;
898 const PARTITION_INFO *partition_info;925 const PARTITION_INFO *partition_info;
926 const MOTION_VECTOR_INFO *motion_vector_info;
899#endif // CONFIG_RATE_CTRL927#endif // CONFIG_RATE_CTRL
900 int quantize_index;928 int quantize_index;
901} ENCODE_FRAME_RESULT;929} ENCODE_FRAME_RESULT;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t