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
38313831 }
38323832 }
38333833 }
3834−static void store_superblock_partition_info(
3835− const PC_TREE *const pc_tree, PARTITION_INFO *partition_info,
3836− const int square_size_4x4, const int num_unit_rows, const int num_unit_cols,
3837− const int row_start_4x4, const int col_start_4x4) {
3834+
3835+static void assign_motion_vector_info(const int block_width_4x4,
3836+ const int block_height_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) {
38383865 const int subblock_square_size_4x4 = square_size_4x4 >> 1;
38393866 if (row_start_4x4 >= num_unit_rows || col_start_4x4 >= num_unit_cols) return;
38403867 assert(pc_tree->partitioning != PARTITION_INVALID);
@@ -3842,6 +3869,14 @@ static void store_superblock_partition_info( · 1 unmodified line
38423869 if (pc_tree->partitioning == PARTITION_NONE ||
38433870 pc_tree->partitioning == PARTITION_HORZ ||
38443871 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
38453880 const int block_width_4x4 = (pc_tree->partitioning == PARTITION_VERT)
38463881 ? square_size_4x4 >> 1
38473882 : square_size_4x4;
@@ -3861,25 +3896,124 @@ static void store_superblock_partition_info( · 13 unmodified lines
38613896 num_unit_cols, partition_info);
38623897 }
38633898
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+
38643996 return;
38653997 }
38663998 // recursively traverse partition tree when partition is split.
38673999 assert(pc_tree->partitioning == PARTITION_SPLIT);
3868− store_superblock_partition_info(pc_tree->split[0], partition_info,
3869− subblock_square_size_4x4, num_unit_rows,
3870− num_unit_cols, row_start_4x4, col_start_4x4);
3871− store_superblock_partition_info(pc_tree->split[1], partition_info,
3872− subblock_square_size_4x4, num_unit_rows,
3873− num_unit_cols, row_start_4x4,
3874− col_start_4x4 + subblock_square_size_4x4);
3875− store_superblock_partition_info(
3876− pc_tree->split[2], partition_info, subblock_square_size_4x4,
3877− num_unit_rows, num_unit_cols, row_start_4x4 + subblock_square_size_4x4,
3878− col_start_4x4);
3879− store_superblock_partition_info(
3880− pc_tree->split[3], partition_info, subblock_square_size_4x4,
3881− num_unit_rows, num_unit_cols, row_start_4x4 + subblock_square_size_4x4,
3882− col_start_4x4 + subblock_square_size_4x4);
4000+ store_superblock_info(pc_tree->split[0], mi_grid_visible, mi_stride,
4001+ subblock_square_size_4x4, num_unit_rows, num_unit_cols,
4002+ row_start_4x4, col_start_4x4, partition_info,
4003+ motion_vector_info);
4004+ store_superblock_info(pc_tree->split[1], mi_grid_visible, mi_stride,
4005+ subblock_square_size_4x4, num_unit_rows, num_unit_cols,
4006+ row_start_4x4, col_start_4x4 + subblock_square_size_4x4,
4007+ partition_info, motion_vector_info);
4008+ store_superblock_info(pc_tree->split[2], mi_grid_visible, mi_stride,
4009+ subblock_square_size_4x4, num_unit_rows, num_unit_cols,
4010+ row_start_4x4 + subblock_square_size_4x4, col_start_4x4,
4011+ partition_info, motion_vector_info);
4012+ store_superblock_info(pc_tree->split[3], mi_grid_visible, mi_stride,
4013+ subblock_square_size_4x4, num_unit_rows, num_unit_cols,
4014+ row_start_4x4 + subblock_square_size_4x4,
4015+ col_start_4x4 + subblock_square_size_4x4,
4016+ partition_info, motion_vector_info);
38834017 }
38844018 #endif // CONFIG_RATE_CTRL
38854019
@@ -4458,13 +4592,15 @@ static int rd_pick_partition(VP9_COMP *cpi, ThreadData *td, · 572 unmodified lines
44584592 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize,
44594593 pc_tree);
44604594 #if CONFIG_RATE_CTRL
4461− // Store partition info.
4595+ // Store partition, motion vector of the superblock.
44624596 if (output_enabled) {
44634597 const int num_unit_rows = get_num_unit_4x4(cpi->frame_info.frame_height);
44644598 const int num_unit_cols = get_num_unit_4x4(cpi->frame_info.frame_width);
4465− store_superblock_partition_info(
4466− pc_tree, cpi->partition_info, num_4x4_blocks_wide_lookup[BLOCK_64X64],
4467− num_unit_rows, num_unit_cols, mi_row << 1, mi_col << 1);
4599+ store_superblock_info(pc_tree, cm->mi_grid_visible, cm->mi_stride,
4600+ num_4x4_blocks_wide_lookup[BLOCK_64X64],
4601+ num_unit_rows, num_unit_cols, mi_row << 1,
4602+ mi_col << 1, cpi->partition_info,
4603+ cpi->motion_vector_info);
44684604 }
44694605 #endif // CONFIG_RATE_CTRL
44704606 }
vp9/encoder/vp9_encoder.c+2−0
@@ -1023,6 +1023,7 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { · 1022 unmodified lines
10231023
10241024 #if CONFIG_RATE_CTRL
10251025 free_partition_info(cpi);
1026+ free_motion_vector_info(cpi);
10261027 #endif
10271028
10281029 vp9_free_ref_frame_buffers(cm->buffer_pool);
@@ -2654,6 +2655,7 @@ VP9_COMP *vp9_create_compressor(const VP9EncoderConfig *oxcf, · 1625 unmodified lines
26542655 #if CONFIG_RATE_CTRL
26552656 encode_command_init(&cpi->encode_command);
26562657 partition_info_init(cpi);
2658+ motion_vector_info_init(cpi);
26572659 #endif
26582660
26592661 return cpi;
vp9/encoder/vp9_encoder.h+28−0
@@ -532,6 +532,11 @@ typedef struct PARTITION_INFO { · 531 unmodified lines
532532 int height; // prediction block height
533533 } PARTITION_INFO;
534534
535+typedef struct MOTION_VECTOR_INFO {
536+ MV_REFERENCE_FRAME ref_frame[2];
537+ int_mv mv[2];
538+} MOTION_VECTOR_INFO;
539+
535540 static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) {
536541 vp9_zero(*encode_command);
537542 encode_command->use_external_quantize_index = 0;
@@ -862,6 +867,7 @@ typedef struct VP9_COMP { · 324 unmodified lines
862867 #if CONFIG_RATE_CTRL
863868 ENCODE_COMMAND encode_command;
864869 PARTITION_INFO *partition_info;
870+ MOTION_VECTOR_INFO *motion_vector_info;
865871 #endif
866872 } VP9_COMP;
867873
@@ -886,6 +892,27 @@ static INLINE void free_partition_info(struct VP9_COMP *cpi) { · 18 unmodified lines
886892 vpx_free(cpi->partition_info);
887893 cpi->partition_info = NULL;
888894 }
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().
899+static 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().
912+static INLINE void free_motion_vector_info(struct VP9_COMP *cpi) {
913+ vpx_free(cpi->motion_vector_info);
914+ cpi->motion_vector_info = NULL;
915+}
889916 #endif // CONFIG_RATE_CTRL
890917
891918 typedef struct ENCODE_FRAME_RESULT {
@@ -896,6 +923,7 @@ typedef struct ENCODE_FRAME_RESULT { · 4 unmodified lines
896923 uint64_t sse;
897924 FRAME_COUNTS frame_counts;
898925 const PARTITION_INFO *partition_info;
926+ const MOTION_VECTOR_INFO *motion_vector_info;
899927 #endif // CONFIG_RATE_CTRL
900928 int quantize_index;
901929 } 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