1 /*
2  *  Copyright (c) 2019 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef VPX_VP9_ENCODER_VP9_NON_GREEDY_MV_H_
12 #define VPX_VP9_ENCODER_VP9_NON_GREEDY_MV_H_
13 
14 #include "vp9/common/vp9_enums.h"
15 #include "vp9/common/vp9_blockd.h"
16 #include "vpx_scale/yv12config.h"
17 #include "vpx_dsp/variance.h"
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 #define NB_MVS_NUM 4
23 #define LOG2_PRECISION 20
24 #define MF_LOCAL_STRUCTURE_SIZE 4
25 #define SQUARE_BLOCK_SIZES 4
26 
27 typedef enum Status { STATUS_OK = 0, STATUS_FAILED = 1 } Status;
28 
29 typedef struct MotionField {
30   int ready;
31   BLOCK_SIZE bsize;
32   int block_rows;
33   int block_cols;
34   int block_num;  // block_num == block_rows * block_cols
35   int (*local_structure)[MF_LOCAL_STRUCTURE_SIZE];
36   int_mv *mf;
37   int *set_mv;
38   int mv_log_scale;
39 } MotionField;
40 
41 typedef struct MotionFieldInfo {
42   int frame_num;
43   int allocated;
44   MotionField (*motion_field_array)[MAX_INTER_REF_FRAMES][SQUARE_BLOCK_SIZES];
45 } MotionFieldInfo;
46 
47 typedef struct {
48   float row, col;
49 } FloatMV;
50 
get_square_block_idx(BLOCK_SIZE bsize)51 static INLINE int get_square_block_idx(BLOCK_SIZE bsize) {
52   if (bsize == BLOCK_4X4) {
53     return 0;
54   }
55   if (bsize == BLOCK_8X8) {
56     return 1;
57   }
58   if (bsize == BLOCK_16X16) {
59     return 2;
60   }
61   if (bsize == BLOCK_32X32) {
62     return 3;
63   }
64   assert(0 && "ERROR: non-square block size");
65   return -1;
66 }
67 
square_block_idx_to_bsize(int square_block_idx)68 static INLINE BLOCK_SIZE square_block_idx_to_bsize(int square_block_idx) {
69   if (square_block_idx == 0) {
70     return BLOCK_4X4;
71   }
72   if (square_block_idx == 1) {
73     return BLOCK_8X8;
74   }
75   if (square_block_idx == 2) {
76     return BLOCK_16X16;
77   }
78   if (square_block_idx == 3) {
79     return BLOCK_32X32;
80   }
81   assert(0 && "ERROR: invalid square_block_idx");
82   return BLOCK_INVALID;
83 }
84 
85 Status vp9_alloc_motion_field_info(MotionFieldInfo *motion_field_info,
86                                    int frame_num, int mi_rows, int mi_cols);
87 
88 Status vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize,
89                               int block_rows, int block_cols);
90 
91 void vp9_free_motion_field(MotionField *motion_field);
92 
93 void vp9_free_motion_field_info(MotionFieldInfo *motion_field_info);
94 
95 int64_t vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_full_mvs,
96                                  int mv_num);
97 
98 void vp9_get_smooth_motion_field(const MV *search_mf,
99                                  const int (*M)[MF_LOCAL_STRUCTURE_SIZE],
100                                  int rows, int cols, BLOCK_SIZE bize,
101                                  float alpha, int num_iters, MV *smooth_mf);
102 
103 void vp9_get_local_structure(const YV12_BUFFER_CONFIG *cur_frame,
104                              const YV12_BUFFER_CONFIG *ref_frame,
105                              const MV *search_mf,
106                              const vp9_variance_fn_ptr_t *fn_ptr, int rows,
107                              int cols, BLOCK_SIZE bsize,
108                              int (*M)[MF_LOCAL_STRUCTURE_SIZE]);
109 
110 MotionField *vp9_motion_field_info_get_motion_field(
111     MotionFieldInfo *motion_field_info, int frame_idx, int rf_idx,
112     BLOCK_SIZE bsize);
113 
114 void vp9_motion_field_mi_set_mv(MotionField *motion_field, int mi_row,
115                                 int mi_col, int_mv mv);
116 
117 void vp9_motion_field_reset_mvs(MotionField *motion_field);
118 
119 int_mv vp9_motion_field_get_mv(const MotionField *motion_field, int brow,
120                                int bcol);
121 int_mv vp9_motion_field_mi_get_mv(const MotionField *motion_field, int mi_row,
122                                   int mi_col);
123 int vp9_motion_field_is_mv_set(const MotionField *motion_field, int brow,
124                                int bcol);
125 
126 #ifdef __cplusplus
127 }  // extern "C"
128 #endif
129 #endif  // VPX_VP9_ENCODER_VP9_NON_GREEDY_MV_H_
130