Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 4 | * This source code is subject to the terms of the BSD 2 Clause License and |
| 5 | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 6 | * was not distributed with this source code in the LICENSE file, you can |
| 7 | * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 8 | * Media Patent License 1.0 was not distributed with this source code in the |
| 9 | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #include <math.h> |
| 13 | |
| 14 | #include "av1/common/common.h" |
| 15 | #include "av1/common/entropymode.h" |
| 16 | |
| 17 | #include "av1/encoder/cost.h" |
| 18 | #include "av1/encoder/encodemv.h" |
| 19 | #include "av1/encoder/subexp.h" |
| 20 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 21 | #include "aom_dsp/aom_dsp_common.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 22 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 23 | static struct av1_token mv_joint_encodings[MV_JOINTS]; |
| 24 | static struct av1_token mv_class_encodings[MV_CLASSES]; |
| 25 | static struct av1_token mv_fp_encodings[MV_FP_SIZE]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 26 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 27 | void av1_entropy_mv_init(void) { |
| 28 | av1_tokens_from_tree(mv_joint_encodings, av1_mv_joint_tree); |
| 29 | av1_tokens_from_tree(mv_class_encodings, av1_mv_class_tree); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 30 | av1_tokens_from_tree(mv_fp_encodings, av1_mv_fp_tree); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 31 | } |
| 32 | |
Thomas | 9ac5508 | 2016-09-23 18:04:17 +0100 | [diff] [blame] | 33 | static void encode_mv_component(aom_writer *w, int comp, nmv_component *mvcomp, |
Alex Converse | 6b2584c | 2017-05-02 09:51:21 -0700 | [diff] [blame] | 34 | MvSubpelPrecision precision) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 35 | int offset; |
| 36 | const int sign = comp < 0; |
| 37 | const int mag = sign ? -comp : comp; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 38 | const int mv_class = av1_get_mv_class(mag - 1, &offset); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 39 | const int d = offset >> 3; // int mv data |
| 40 | const int fr = (offset >> 1) & 3; // fractional mv data |
| 41 | const int hp = offset & 1; // high precision mv data |
| 42 | |
| 43 | assert(comp != 0); |
| 44 | |
Thomas Davies | 599395e | 2017-07-21 18:02:48 +0100 | [diff] [blame] | 45 | // Sign |
| 46 | #if CONFIG_NEW_MULTISYMBOL |
| 47 | aom_write_bit(w, sign); |
| 48 | #else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 49 | aom_write(w, sign, mvcomp->sign); |
Thomas Davies | 599395e | 2017-07-21 18:02:48 +0100 | [diff] [blame] | 50 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 51 | |
Nathan E. Egge | 476c63c | 2017-05-18 18:35:16 -0400 | [diff] [blame] | 52 | // Class |
Nathan E. Egge | d7b893c | 2016-09-08 15:08:48 -0400 | [diff] [blame] | 53 | aom_write_symbol(w, mv_class, mvcomp->class_cdf, MV_CLASSES); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 54 | |
| 55 | // Integer bits |
| 56 | if (mv_class == MV_CLASS_0) { |
Thomas Davies | 599395e | 2017-07-21 18:02:48 +0100 | [diff] [blame] | 57 | #if CONFIG_NEW_MULTISYMBOL |
| 58 | aom_write_symbol(w, d, mvcomp->class0_cdf, CLASS0_SIZE); |
| 59 | #else |
Nathan E. Egge | 45ea963 | 2016-09-08 17:25:49 -0400 | [diff] [blame] | 60 | aom_write(w, d, mvcomp->class0[0]); |
Thomas Davies | 599395e | 2017-07-21 18:02:48 +0100 | [diff] [blame] | 61 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 62 | } else { |
| 63 | int i; |
| 64 | const int n = mv_class + CLASS0_BITS - 1; // number of bits |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 65 | for (i = 0; i < n; ++i) aom_write(w, (d >> i) & 1, mvcomp->bits[i]); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 66 | } |
| 67 | |
Alex Converse | 6b2584c | 2017-05-02 09:51:21 -0700 | [diff] [blame] | 68 | // Fractional bits |
| 69 | #if CONFIG_INTRABC |
| 70 | if (precision > MV_SUBPEL_NONE) |
| 71 | #endif // CONFIG_INTRABC |
| 72 | { |
| 73 | aom_write_symbol(w, fr, mv_class == MV_CLASS_0 ? mvcomp->class0_fp_cdf[d] |
| 74 | : mvcomp->fp_cdf, |
| 75 | MV_FP_SIZE); |
| 76 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 77 | |
| 78 | // High precision bit |
Alex Converse | 6b2584c | 2017-05-02 09:51:21 -0700 | [diff] [blame] | 79 | if (precision > MV_SUBPEL_LOW_PRECISION) |
Thomas Davies | 599395e | 2017-07-21 18:02:48 +0100 | [diff] [blame] | 80 | #if CONFIG_NEW_MULTISYMBOL |
| 81 | aom_write_symbol( |
| 82 | w, hp, mv_class == MV_CLASS_0 ? mvcomp->class0_hp_cdf : mvcomp->hp_cdf, |
| 83 | 2); |
| 84 | #else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 85 | aom_write(w, hp, mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp); |
Thomas Davies | 599395e | 2017-07-21 18:02:48 +0100 | [diff] [blame] | 86 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 87 | } |
| 88 | |
| 89 | static void build_nmv_component_cost_table(int *mvcost, |
| 90 | const nmv_component *const mvcomp, |
Alex Converse | d5d9b6c | 2017-05-23 15:23:45 -0700 | [diff] [blame] | 91 | MvSubpelPrecision precision) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 92 | int i, v; |
| 93 | int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE]; |
| 94 | int bits_cost[MV_OFFSET_BITS][2]; |
| 95 | int class0_fp_cost[CLASS0_SIZE][MV_FP_SIZE], fp_cost[MV_FP_SIZE]; |
| 96 | int class0_hp_cost[2], hp_cost[2]; |
| 97 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 98 | sign_cost[0] = av1_cost_zero(mvcomp->sign); |
| 99 | sign_cost[1] = av1_cost_one(mvcomp->sign); |
| 100 | av1_cost_tokens(class_cost, mvcomp->classes, av1_mv_class_tree); |
| 101 | av1_cost_tokens(class0_cost, mvcomp->class0, av1_mv_class0_tree); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 102 | for (i = 0; i < MV_OFFSET_BITS; ++i) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 103 | bits_cost[i][0] = av1_cost_zero(mvcomp->bits[i]); |
| 104 | bits_cost[i][1] = av1_cost_one(mvcomp->bits[i]); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | for (i = 0; i < CLASS0_SIZE; ++i) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 108 | av1_cost_tokens(class0_fp_cost[i], mvcomp->class0_fp[i], av1_mv_fp_tree); |
| 109 | av1_cost_tokens(fp_cost, mvcomp->fp, av1_mv_fp_tree); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 110 | |
Alex Converse | d5d9b6c | 2017-05-23 15:23:45 -0700 | [diff] [blame] | 111 | if (precision > MV_SUBPEL_LOW_PRECISION) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 112 | class0_hp_cost[0] = av1_cost_zero(mvcomp->class0_hp); |
| 113 | class0_hp_cost[1] = av1_cost_one(mvcomp->class0_hp); |
| 114 | hp_cost[0] = av1_cost_zero(mvcomp->hp); |
| 115 | hp_cost[1] = av1_cost_one(mvcomp->hp); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 116 | } |
| 117 | mvcost[0] = 0; |
| 118 | for (v = 1; v <= MV_MAX; ++v) { |
| 119 | int z, c, o, d, e, f, cost = 0; |
| 120 | z = v - 1; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 121 | c = av1_get_mv_class(z, &o); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 122 | cost += class_cost[c]; |
| 123 | d = (o >> 3); /* int mv data */ |
| 124 | f = (o >> 1) & 3; /* fractional pel mv data */ |
| 125 | e = (o & 1); /* high precision mv data */ |
| 126 | if (c == MV_CLASS_0) { |
| 127 | cost += class0_cost[d]; |
| 128 | } else { |
Urvang Joshi | 454280d | 2016-10-14 16:51:44 -0700 | [diff] [blame] | 129 | const int b = c + CLASS0_BITS - 1; /* number of bits */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 130 | for (i = 0; i < b; ++i) cost += bits_cost[i][((d >> i) & 1)]; |
| 131 | } |
Alex Converse | d5d9b6c | 2017-05-23 15:23:45 -0700 | [diff] [blame] | 132 | #if CONFIG_INTRABC |
| 133 | if (precision > MV_SUBPEL_NONE) |
| 134 | #endif // CONFIG_INTRABC |
| 135 | { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 136 | if (c == MV_CLASS_0) { |
Alex Converse | d5d9b6c | 2017-05-23 15:23:45 -0700 | [diff] [blame] | 137 | cost += class0_fp_cost[d][f]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 138 | } else { |
Alex Converse | d5d9b6c | 2017-05-23 15:23:45 -0700 | [diff] [blame] | 139 | cost += fp_cost[f]; |
| 140 | } |
| 141 | if (precision > MV_SUBPEL_LOW_PRECISION) { |
| 142 | if (c == MV_CLASS_0) { |
| 143 | cost += class0_hp_cost[e]; |
| 144 | } else { |
| 145 | cost += hp_cost[e]; |
| 146 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 147 | } |
| 148 | } |
| 149 | mvcost[v] = cost + sign_cost[0]; |
| 150 | mvcost[-v] = cost + sign_cost[1]; |
| 151 | } |
| 152 | } |
| 153 | |
Thomas Davies | 599395e | 2017-07-21 18:02:48 +0100 | [diff] [blame] | 154 | #if !CONFIG_NEW_MULTISYMBOL |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 155 | static void update_mv(aom_writer *w, const unsigned int ct[2], aom_prob *cur_p, |
| 156 | aom_prob upd_p) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 157 | (void)upd_p; |
Yaowu Xu | 859a527 | 2016-11-10 15:32:21 -0800 | [diff] [blame] | 158 | // Just use the default maximum number of tile groups to avoid passing in the |
| 159 | // actual |
Thomas Davies | 80188d1 | 2016-10-26 16:08:35 -0700 | [diff] [blame] | 160 | // number |
Thomas Davies | af6df17 | 2016-11-09 14:04:18 +0000 | [diff] [blame] | 161 | av1_cond_prob_diff_update(w, cur_p, ct, DEFAULT_MAX_NUM_TG); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 162 | } |
| 163 | |
Jingning Han | fd0cf16 | 2016-09-30 10:33:50 -0700 | [diff] [blame] | 164 | void av1_write_nmv_probs(AV1_COMMON *cm, int usehp, aom_writer *w, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 165 | nmv_context_counts *const nmv_counts) { |
Yaowu Xu | 8af861b | 2016-11-01 12:12:11 -0700 | [diff] [blame] | 166 | int i; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 167 | int nmv_ctx = 0; |
| 168 | for (nmv_ctx = 0; nmv_ctx < NMV_CONTEXTS; ++nmv_ctx) { |
| 169 | nmv_context *const mvc = &cm->fc->nmvc[nmv_ctx]; |
| 170 | nmv_context_counts *const counts = &nmv_counts[nmv_ctx]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 171 | |
| 172 | if (usehp) { |
| 173 | for (i = 0; i < 2; ++i) { |
| 174 | update_mv(w, counts->comps[i].class0_hp, &mvc->comps[i].class0_hp, |
| 175 | MV_UPDATE_PROB); |
| 176 | update_mv(w, counts->comps[i].hp, &mvc->comps[i].hp, MV_UPDATE_PROB); |
| 177 | } |
| 178 | } |
| 179 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 180 | } |
Thomas Davies | 599395e | 2017-07-21 18:02:48 +0100 | [diff] [blame] | 181 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 182 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 183 | void av1_encode_mv(AV1_COMP *cpi, aom_writer *w, const MV *mv, const MV *ref, |
Thomas | 9ac5508 | 2016-09-23 18:04:17 +0100 | [diff] [blame] | 184 | nmv_context *mvctx, int usehp) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 185 | const MV diff = { mv->row - ref->row, mv->col - ref->col }; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 186 | const MV_JOINT_TYPE j = av1_get_mv_joint(&diff); |
Nathan E. Egge | 5f7fd7a | 2016-09-08 11:22:03 -0400 | [diff] [blame] | 187 | aom_write_symbol(w, j, mvctx->joint_cdf, MV_JOINTS); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 188 | if (mv_joint_vertical(j)) |
| 189 | encode_mv_component(w, diff.row, &mvctx->comps[0], usehp); |
| 190 | |
| 191 | if (mv_joint_horizontal(j)) |
| 192 | encode_mv_component(w, diff.col, &mvctx->comps[1], usehp); |
| 193 | |
| 194 | // If auto_mv_step_size is enabled then keep track of the largest |
| 195 | // motion vector component used. |
| 196 | if (cpi->sf.mv.auto_mv_step_size) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 197 | unsigned int maxv = AOMMAX(abs(mv->row), abs(mv->col)) >> 3; |
| 198 | cpi->max_mv_magnitude = AOMMAX(maxv, cpi->max_mv_magnitude); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 199 | } |
| 200 | } |
| 201 | |
Alex Converse | 2874430 | 2017-04-13 14:46:22 -0700 | [diff] [blame] | 202 | #if CONFIG_INTRABC |
| 203 | void av1_encode_dv(aom_writer *w, const MV *mv, const MV *ref, |
| 204 | nmv_context *mvctx) { |
| 205 | const MV diff = { mv->row - ref->row, mv->col - ref->col }; |
| 206 | const MV_JOINT_TYPE j = av1_get_mv_joint(&diff); |
| 207 | |
Alex Converse | 2874430 | 2017-04-13 14:46:22 -0700 | [diff] [blame] | 208 | aom_write_symbol(w, j, mvctx->joint_cdf, MV_JOINTS); |
Alex Converse | 2874430 | 2017-04-13 14:46:22 -0700 | [diff] [blame] | 209 | if (mv_joint_vertical(j)) |
Alex Converse | 6b2584c | 2017-05-02 09:51:21 -0700 | [diff] [blame] | 210 | encode_mv_component(w, diff.row, &mvctx->comps[0], MV_SUBPEL_NONE); |
Alex Converse | 2874430 | 2017-04-13 14:46:22 -0700 | [diff] [blame] | 211 | |
| 212 | if (mv_joint_horizontal(j)) |
Alex Converse | 6b2584c | 2017-05-02 09:51:21 -0700 | [diff] [blame] | 213 | encode_mv_component(w, diff.col, &mvctx->comps[1], MV_SUBPEL_NONE); |
Alex Converse | 2874430 | 2017-04-13 14:46:22 -0700 | [diff] [blame] | 214 | } |
| 215 | #endif // CONFIG_INTRABC |
| 216 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 217 | void av1_build_nmv_cost_table(int *mvjoint, int *mvcost[2], |
Alex Converse | d5d9b6c | 2017-05-23 15:23:45 -0700 | [diff] [blame] | 218 | const nmv_context *ctx, |
| 219 | MvSubpelPrecision precision) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 220 | av1_cost_tokens(mvjoint, ctx->joints, av1_mv_joint_tree); |
Alex Converse | d5d9b6c | 2017-05-23 15:23:45 -0700 | [diff] [blame] | 221 | build_nmv_component_cost_table(mvcost[0], &ctx->comps[0], precision); |
| 222 | build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], precision); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 223 | } |
| 224 | |
| 225 | #if CONFIG_EXT_INTER |
| 226 | static void inc_mvs(const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT *mbmi_ext, |
Sebastien Alaiwan | e140c50 | 2017-04-27 09:52:34 +0200 | [diff] [blame] | 227 | const int_mv mvs[2], const int_mv pred_mvs[2], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 228 | nmv_context_counts *nmv_counts) { |
| 229 | int i; |
| 230 | PREDICTION_MODE mode = mbmi->mode; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 231 | |
Zoe Liu | 7f24e1b | 2017-03-17 17:42:05 -0700 | [diff] [blame] | 232 | if (mode == NEWMV || mode == NEW_NEWMV) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 233 | for (i = 0; i < 1 + has_second_ref(mbmi); ++i) { |
Zoe Liu | 7f24e1b | 2017-03-17 17:42:05 -0700 | [diff] [blame] | 234 | const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_mv; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 235 | const MV diff = { mvs[i].as_mv.row - ref->row, |
| 236 | mvs[i].as_mv.col - ref->col }; |
Yaowu Xu | 4306b6e | 2016-09-27 12:55:32 -0700 | [diff] [blame] | 237 | int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame); |
| 238 | int nmv_ctx = |
| 239 | av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type], |
| 240 | mbmi_ext->ref_mv_stack[rf_type], i, mbmi->ref_mv_idx); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 241 | nmv_context_counts *counts = &nmv_counts[nmv_ctx]; |
| 242 | (void)pred_mvs; |
Alex Converse | 6317c88 | 2016-09-29 14:21:37 -0700 | [diff] [blame] | 243 | av1_inc_mv(&diff, counts, 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 244 | } |
| 245 | } else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) { |
| 246 | const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_mv; |
| 247 | const MV diff = { mvs[1].as_mv.row - ref->row, |
| 248 | mvs[1].as_mv.col - ref->col }; |
Yaowu Xu | 4306b6e | 2016-09-27 12:55:32 -0700 | [diff] [blame] | 249 | int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame); |
| 250 | int nmv_ctx = |
| 251 | av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type], |
| 252 | mbmi_ext->ref_mv_stack[rf_type], 1, mbmi->ref_mv_idx); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 253 | nmv_context_counts *counts = &nmv_counts[nmv_ctx]; |
Alex Converse | 6317c88 | 2016-09-29 14:21:37 -0700 | [diff] [blame] | 254 | av1_inc_mv(&diff, counts, 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 255 | } else if (mode == NEW_NEARESTMV || mode == NEW_NEARMV) { |
| 256 | const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_mv; |
| 257 | const MV diff = { mvs[0].as_mv.row - ref->row, |
| 258 | mvs[0].as_mv.col - ref->col }; |
Yaowu Xu | 4306b6e | 2016-09-27 12:55:32 -0700 | [diff] [blame] | 259 | int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame); |
| 260 | int nmv_ctx = |
| 261 | av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type], |
| 262 | mbmi_ext->ref_mv_stack[rf_type], 0, mbmi->ref_mv_idx); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 263 | nmv_context_counts *counts = &nmv_counts[nmv_ctx]; |
Alex Converse | 6317c88 | 2016-09-29 14:21:37 -0700 | [diff] [blame] | 264 | av1_inc_mv(&diff, counts, 1); |
Zoe Liu | 85b6646 | 2017-04-20 14:28:19 -0700 | [diff] [blame] | 265 | #if CONFIG_COMPOUND_SINGLEREF |
| 266 | } else { |
| 267 | assert( // mode == SR_NEAREST_NEWMV || |
| 268 | mode == SR_NEAR_NEWMV || mode == SR_ZERO_NEWMV || mode == SR_NEW_NEWMV); |
| 269 | const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_mv; |
| 270 | int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame); |
| 271 | int nmv_ctx = |
| 272 | av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type], |
| 273 | mbmi_ext->ref_mv_stack[rf_type], 0, mbmi->ref_mv_idx); |
| 274 | nmv_context_counts *counts = &nmv_counts[nmv_ctx]; |
| 275 | (void)pred_mvs; |
| 276 | MV diff; |
| 277 | if (mode == SR_NEW_NEWMV) { |
| 278 | diff.row = mvs[0].as_mv.row - ref->row; |
| 279 | diff.col = mvs[0].as_mv.col - ref->col; |
| 280 | av1_inc_mv(&diff, counts, 1); |
| 281 | } |
| 282 | diff.row = mvs[1].as_mv.row - ref->row; |
| 283 | diff.col = mvs[1].as_mv.col - ref->col; |
| 284 | av1_inc_mv(&diff, counts, 1); |
| 285 | #endif // CONFIG_COMPOUND_SINGLEREF |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 286 | } |
| 287 | } |
| 288 | |
| 289 | static void inc_mvs_sub8x8(const MODE_INFO *mi, int block, const int_mv mvs[2], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 290 | const MB_MODE_INFO_EXT *mbmi_ext, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 291 | nmv_context_counts *nmv_counts) { |
| 292 | int i; |
| 293 | PREDICTION_MODE mode = mi->bmi[block].as_mode; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 294 | const MB_MODE_INFO *mbmi = &mi->mbmi; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 295 | |
Zoe Liu | 7f24e1b | 2017-03-17 17:42:05 -0700 | [diff] [blame] | 296 | if (mode == NEWMV || mode == NEW_NEWMV) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 297 | for (i = 0; i < 1 + has_second_ref(&mi->mbmi); ++i) { |
| 298 | const MV *ref = &mi->bmi[block].ref_mv[i].as_mv; |
| 299 | const MV diff = { mvs[i].as_mv.row - ref->row, |
| 300 | mvs[i].as_mv.col - ref->col }; |
Yaowu Xu | 4306b6e | 2016-09-27 12:55:32 -0700 | [diff] [blame] | 301 | int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame); |
| 302 | int nmv_ctx = |
| 303 | av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type], |
| 304 | mbmi_ext->ref_mv_stack[rf_type], i, mbmi->ref_mv_idx); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 305 | nmv_context_counts *counts = &nmv_counts[nmv_ctx]; |
Alex Converse | 6317c88 | 2016-09-29 14:21:37 -0700 | [diff] [blame] | 306 | av1_inc_mv(&diff, counts, 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 307 | } |
| 308 | } else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) { |
| 309 | const MV *ref = &mi->bmi[block].ref_mv[1].as_mv; |
| 310 | const MV diff = { mvs[1].as_mv.row - ref->row, |
| 311 | mvs[1].as_mv.col - ref->col }; |
Yaowu Xu | 4306b6e | 2016-09-27 12:55:32 -0700 | [diff] [blame] | 312 | int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame); |
| 313 | int nmv_ctx = |
| 314 | av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type], |
| 315 | mbmi_ext->ref_mv_stack[rf_type], 1, mbmi->ref_mv_idx); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 316 | nmv_context_counts *counts = &nmv_counts[nmv_ctx]; |
Alex Converse | 6317c88 | 2016-09-29 14:21:37 -0700 | [diff] [blame] | 317 | av1_inc_mv(&diff, counts, 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 318 | } else if (mode == NEW_NEARESTMV || mode == NEW_NEARMV) { |
| 319 | const MV *ref = &mi->bmi[block].ref_mv[0].as_mv; |
| 320 | const MV diff = { mvs[0].as_mv.row - ref->row, |
| 321 | mvs[0].as_mv.col - ref->col }; |
Yaowu Xu | 4306b6e | 2016-09-27 12:55:32 -0700 | [diff] [blame] | 322 | int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame); |
| 323 | int nmv_ctx = |
| 324 | av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type], |
| 325 | mbmi_ext->ref_mv_stack[rf_type], 0, mbmi->ref_mv_idx); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 326 | nmv_context_counts *counts = &nmv_counts[nmv_ctx]; |
Alex Converse | 6317c88 | 2016-09-29 14:21:37 -0700 | [diff] [blame] | 327 | av1_inc_mv(&diff, counts, 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 328 | } |
| 329 | } |
Zoe Liu | 85b6646 | 2017-04-20 14:28:19 -0700 | [diff] [blame] | 330 | #else // !CONFIG_EXT_INTER |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 331 | static void inc_mvs(const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT *mbmi_ext, |
Sebastien Alaiwan | e140c50 | 2017-04-27 09:52:34 +0200 | [diff] [blame] | 332 | const int_mv mvs[2], const int_mv pred_mvs[2], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 333 | nmv_context_counts *nmv_counts) { |
| 334 | int i; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 335 | |
| 336 | for (i = 0; i < 1 + has_second_ref(mbmi); ++i) { |
Yaowu Xu | 4306b6e | 2016-09-27 12:55:32 -0700 | [diff] [blame] | 337 | int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame); |
| 338 | int nmv_ctx = |
| 339 | av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type], |
| 340 | mbmi_ext->ref_mv_stack[rf_type], i, mbmi->ref_mv_idx); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 341 | nmv_context_counts *counts = &nmv_counts[nmv_ctx]; |
| 342 | const MV *ref = &pred_mvs[i].as_mv; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 343 | const MV diff = { mvs[i].as_mv.row - ref->row, |
| 344 | mvs[i].as_mv.col - ref->col }; |
Alex Converse | 6317c88 | 2016-09-29 14:21:37 -0700 | [diff] [blame] | 345 | av1_inc_mv(&diff, counts, 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 346 | } |
| 347 | } |
| 348 | #endif // CONFIG_EXT_INTER |
| 349 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 350 | void av1_update_mv_count(ThreadData *td) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 351 | const MACROBLOCKD *xd = &td->mb.e_mbd; |
| 352 | const MODE_INFO *mi = xd->mi[0]; |
| 353 | const MB_MODE_INFO *const mbmi = &mi->mbmi; |
| 354 | const MB_MODE_INFO_EXT *mbmi_ext = td->mb.mbmi_ext; |
Jingning Han | 599461d | 2016-12-14 11:34:58 -0800 | [diff] [blame] | 355 | #if CONFIG_CB4X4 |
| 356 | const int unify_bsize = 1; |
| 357 | #else |
| 358 | const int unify_bsize = 0; |
| 359 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 360 | |
Jingning Han | 599461d | 2016-12-14 11:34:58 -0800 | [diff] [blame] | 361 | if (mbmi->sb_type < BLOCK_8X8 && !unify_bsize) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 362 | const int num_4x4_w = num_4x4_blocks_wide_lookup[mbmi->sb_type]; |
| 363 | const int num_4x4_h = num_4x4_blocks_high_lookup[mbmi->sb_type]; |
| 364 | int idx, idy; |
| 365 | |
| 366 | for (idy = 0; idy < 2; idy += num_4x4_h) { |
| 367 | for (idx = 0; idx < 2; idx += num_4x4_w) { |
| 368 | const int i = idy * 2 + idx; |
| 369 | |
| 370 | #if CONFIG_EXT_INTER |
| 371 | if (have_newmv_in_inter_mode(mi->bmi[i].as_mode)) |
Sebastien Alaiwan | e140c50 | 2017-04-27 09:52:34 +0200 | [diff] [blame] | 372 | inc_mvs_sub8x8(mi, i, mi->bmi[i].as_mv, mbmi_ext, td->counts->mv); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 373 | #else |
| 374 | if (mi->bmi[i].as_mode == NEWMV) |
Sebastien Alaiwan | e140c50 | 2017-04-27 09:52:34 +0200 | [diff] [blame] | 375 | inc_mvs(mbmi, mbmi_ext, mi->bmi[i].as_mv, mi->bmi[i].pred_mv, |
| 376 | td->counts->mv); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 377 | #endif // CONFIG_EXT_INTER |
| 378 | } |
| 379 | } |
| 380 | } else { |
| 381 | #if CONFIG_EXT_INTER |
| 382 | if (have_newmv_in_inter_mode(mbmi->mode)) |
| 383 | #else |
| 384 | if (mbmi->mode == NEWMV) |
| 385 | #endif // CONFIG_EXT_INTER |
Sebastien Alaiwan | e140c50 | 2017-04-27 09:52:34 +0200 | [diff] [blame] | 386 | inc_mvs(mbmi, mbmi_ext, mbmi->mv, mbmi->pred_mv, td->counts->mv); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 387 | } |
| 388 | } |