vp9_encodemv.c 20 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
6
 *  that can be found in the LICENSE file in the root of the source
 *  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.
John Koleszar's avatar
John Koleszar committed
9
10
11
 */


12
#include "vp9/common/vp9_common.h"
13
#include "vp9/encoder/vp9_encodemv.h"
14
15
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_systemdependent.h"
John Koleszar's avatar
John Koleszar committed
16
17
18
19
20
21
22

#include <math.h>

#ifdef ENTROPY_STATS
extern unsigned int active_section;
#endif

23
24
25
26
#ifdef NMV_STATS
nmv_context_counts tnmvcounts;
#endif

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
static void encode_mv_component(vp9_writer* w, int comp,
                                const nmv_component* mvcomp, int usehp) {
  int offset;
  const int sign = comp < 0;
  const int mag = sign ? -comp : comp;
  const int mv_class = vp9_get_mv_class(mag - 1, &offset);
  const int d = offset >> 3;                // int mv data
  const int fr = (offset >> 1) & 3;         // fractional mv data
  const int hp = offset & 1;                // high precision mv data

  assert(comp != 0);

  // Sign
  vp9_write(w, sign, mvcomp->sign);

  // Class
  write_token(w, vp9_mv_class_tree, mvcomp->classes,
              &vp9_mv_class_encodings[mv_class]);

  // Integer bits
  if (mv_class == MV_CLASS_0) {
    write_token(w, vp9_mv_class0_tree, mvcomp->class0,
                &vp9_mv_class0_encodings[d]);
50
  } else {
51
52
53
54
    int i;
    const int n = mv_class + CLASS0_BITS - 1;  // number of bits
    for (i = 0; i < n; ++i)
      vp9_write(w, (d >> i) & 1, mvcomp->bits[i]);
55
56
  }

57
58
59
60
61
62
63
64
65
  // Fractional bits
  write_token(w, vp9_mv_fp_tree,
              mv_class == MV_CLASS_0 ?  mvcomp->class0_fp[d] : mvcomp->fp,
              &vp9_mv_fp_encodings[fr]);

  // High precision bit
  if (usehp)
    vp9_write(w, hp,
              mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp);
66
67
}

68

69
static void build_nmv_component_cost_table(int *mvcost,
John Koleszar's avatar
John Koleszar committed
70
                                           const nmv_component* const mvcomp,
71
72
73
74
75
76
77
                                           int usehp) {
  int i, v;
  int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE];
  int bits_cost[MV_OFFSET_BITS][2];
  int class0_fp_cost[CLASS0_SIZE][4], fp_cost[4];
  int class0_hp_cost[2], hp_cost[2];

78
79
  sign_cost[0] = vp9_cost_zero(mvcomp->sign);
  sign_cost[1] = vp9_cost_one(mvcomp->sign);
80
81
  vp9_cost_tokens(class_cost, mvcomp->classes, vp9_mv_class_tree);
  vp9_cost_tokens(class0_cost, mvcomp->class0, vp9_mv_class0_tree);
82
  for (i = 0; i < MV_OFFSET_BITS; ++i) {
83
84
    bits_cost[i][0] = vp9_cost_zero(mvcomp->bits[i]);
    bits_cost[i][1] = vp9_cost_one(mvcomp->bits[i]);
85
86
87
  }

  for (i = 0; i < CLASS0_SIZE; ++i)
88
89
    vp9_cost_tokens(class0_fp_cost[i], mvcomp->class0_fp[i], vp9_mv_fp_tree);
  vp9_cost_tokens(fp_cost, mvcomp->fp, vp9_mv_fp_tree);
90
91

  if (usehp) {
92
93
94
95
    class0_hp_cost[0] = vp9_cost_zero(mvcomp->class0_hp);
    class0_hp_cost[1] = vp9_cost_one(mvcomp->class0_hp);
    hp_cost[0] = vp9_cost_zero(mvcomp->hp);
    hp_cost[1] = vp9_cost_one(mvcomp->hp);
96
97
98
99
100
  }
  mvcost[0] = 0;
  for (v = 1; v <= MV_MAX; ++v) {
    int z, c, o, d, e, f, cost = 0;
    z = v - 1;
101
    c = vp9_get_mv_class(z, &o);
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    cost += class_cost[c];
    d = (o >> 3);               /* int mv data */
    f = (o >> 1) & 3;           /* fractional pel mv data */
    e = (o & 1);                /* high precision mv data */
    if (c == MV_CLASS_0) {
      cost += class0_cost[d];
    } else {
      int i, b;
      b = c + CLASS0_BITS - 1;  /* number of bits */
      for (i = 0; i < b; ++i)
        cost += bits_cost[i][((d >> i) & 1)];
    }
    if (c == MV_CLASS_0) {
      cost += class0_fp_cost[d][f];
    } else {
      cost += fp_cost[f];
    }
    if (usehp) {
      if (c == MV_CLASS_0) {
        cost += class0_hp_cost[e];
      } else {
        cost += hp_cost[e];
      }
    }
    mvcost[v] = cost + sign_cost[0];
    mvcost[-v] = cost + sign_cost[1];
  }
}

static int update_nmv_savings(const unsigned int ct[2],
132
133
134
                              const vp9_prob cur_p,
                              const vp9_prob new_p,
                              const vp9_prob upd_p) {
135
136

#ifdef LOW_PRECISION_MV_UPDATE
137
  vp9_prob mod_p = new_p | 1;
138
#else
139
  vp9_prob mod_p = new_p;
140
#endif
141
142
  const int cur_b = cost_branch256(ct, cur_p);
  const int mod_b = cost_branch256(ct, mod_p);
143
144
145
146
  const int cost = 7 * 256 +
#ifndef LOW_PRECISION_MV_UPDATE
      256 +
#endif
147
      (vp9_cost_one(upd_p) - vp9_cost_zero(upd_p));
148
149
150
  if (cur_b - mod_b - cost > 0) {
    return cur_b - mod_b - cost;
  } else {
151
    return 0 - vp9_cost_zero(upd_p);
152
153
154
155
  }
}

static int update_nmv(
156
  vp9_writer *const bc,
157
  const unsigned int ct[2],
158
159
160
  vp9_prob *const cur_p,
  const vp9_prob new_p,
  const vp9_prob upd_p) {
161
162

#ifdef LOW_PRECISION_MV_UPDATE
163
  vp9_prob mod_p = new_p | 1;
164
#else
165
  vp9_prob mod_p = new_p;
166
167
#endif

168
169
  const int cur_b = cost_branch256(ct, *cur_p);
  const int mod_b = cost_branch256(ct, mod_p);
170
171
172
173
  const int cost = 7 * 256 +
#ifndef LOW_PRECISION_MV_UPDATE
      256 +
#endif
174
      (vp9_cost_one(upd_p) - vp9_cost_zero(upd_p));
175
176
177

  if (cur_b - mod_b > cost) {
    *cur_p = mod_p;
178
    vp9_write(bc, 1, upd_p);
179
#ifdef LOW_PRECISION_MV_UPDATE
180
    vp9_write_literal(bc, mod_p >> 1, 7);
181
#else
182
    vp9_write_literal(bc, mod_p, 8);
183
184
185
#endif
    return 1;
  } else {
186
    vp9_write(bc, 0, upd_p);
187
188
189
190
    return 0;
  }
}

Deb Mukherjee's avatar
Deb Mukherjee committed
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
void print_nmvcounts(nmv_context_counts tnmvcounts) {
  int i, j, k;
  printf("\nCounts =\n  { ");
  for (j = 0; j < MV_JOINTS; ++j)
    printf("%d, ", tnmvcounts.joints[j]);
  printf("},\n");
  for (i = 0; i < 2; ++i) {
    printf("  {\n");
    printf("    %d/%d,\n", tnmvcounts.comps[i].sign[0],
                           tnmvcounts.comps[i].sign[1]);
    printf("    { ");
    for (j = 0; j < MV_CLASSES; ++j)
      printf("%d, ", tnmvcounts.comps[i].classes[j]);
    printf("},\n");
    printf("    { ");
    for (j = 0; j < CLASS0_SIZE; ++j)
      printf("%d, ", tnmvcounts.comps[i].class0[j]);
    printf("},\n");
    printf("    { ");
    for (j = 0; j < MV_OFFSET_BITS; ++j)
      printf("%d/%d, ", tnmvcounts.comps[i].bits[j][0],
                        tnmvcounts.comps[i].bits[j][1]);
    printf("},\n");

    printf("    {");
    for (j = 0; j < CLASS0_SIZE; ++j) {
      printf("{");
      for (k = 0; k < 4; ++k)
        printf("%d, ", tnmvcounts.comps[i].class0_fp[j][k]);
      printf("}, ");
    }
    printf("},\n");

    printf("    { ");
    for (j = 0; j < 4; ++j)
      printf("%d, ", tnmvcounts.comps[i].fp[j]);
    printf("},\n");

    printf("    %d/%d,\n",
           tnmvcounts.comps[i].class0_hp[0],
           tnmvcounts.comps[i].class0_hp[1]);
    printf("    %d/%d,\n",
           tnmvcounts.comps[i].hp[0],
           tnmvcounts.comps[i].hp[1]);
    printf("  },\n");
  }
}

239
240
#ifdef NMV_STATS
void init_nmvstats() {
241
  vp9_zero(tnmvcounts);
242
243
244
245
246
247
248
249
250
251
252
253
254
255
}

void print_nmvstats() {
  nmv_context prob;
  unsigned int branch_ct_joint[MV_JOINTS - 1][2];
  unsigned int branch_ct_sign[2][2];
  unsigned int branch_ct_classes[2][MV_CLASSES - 1][2];
  unsigned int branch_ct_class0[2][CLASS0_SIZE - 1][2];
  unsigned int branch_ct_bits[2][MV_OFFSET_BITS][2];
  unsigned int branch_ct_class0_fp[2][CLASS0_SIZE][4 - 1][2];
  unsigned int branch_ct_fp[2][4 - 1][2];
  unsigned int branch_ct_class0_hp[2][2];
  unsigned int branch_ct_hp[2][2];
  int i, j, k;
256
  vp9_counts_to_nmv_context(&tnmvcounts, &prob, 1,
257
258
259
260
261
262
263
264
265
                            branch_ct_joint, branch_ct_sign, branch_ct_classes,
                            branch_ct_class0, branch_ct_bits,
                            branch_ct_class0_fp, branch_ct_fp,
                            branch_ct_class0_hp, branch_ct_hp);

  printf("\nCounts =\n  { ");
  for (j = 0; j < MV_JOINTS; ++j)
    printf("%d, ", tnmvcounts.joints[j]);
  printf("},\n");
Deb Mukherjee's avatar
Deb Mukherjee committed
266
  for (i = 0; i < 2; ++i) {
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
    printf("  {\n");
    printf("    %d/%d,\n", tnmvcounts.comps[i].sign[0],
                           tnmvcounts.comps[i].sign[1]);
    printf("    { ");
    for (j = 0; j < MV_CLASSES; ++j)
      printf("%d, ", tnmvcounts.comps[i].classes[j]);
    printf("},\n");
    printf("    { ");
    for (j = 0; j < CLASS0_SIZE; ++j)
      printf("%d, ", tnmvcounts.comps[i].class0[j]);
    printf("},\n");
    printf("    { ");
    for (j = 0; j < MV_OFFSET_BITS; ++j)
      printf("%d/%d, ", tnmvcounts.comps[i].bits[j][0],
                        tnmvcounts.comps[i].bits[j][1]);
    printf("},\n");

    printf("    {");
    for (j = 0; j < CLASS0_SIZE; ++j) {
      printf("{");
      for (k = 0; k < 4; ++k)
        printf("%d, ", tnmvcounts.comps[i].class0_fp[j][k]);
      printf("}, ");
    }
    printf("},\n");

    printf("    { ");
    for (j = 0; j < 4; ++j)
      printf("%d, ", tnmvcounts.comps[i].fp[j]);
    printf("},\n");

    printf("    %d/%d,\n",
           tnmvcounts.comps[i].class0_hp[0],
           tnmvcounts.comps[i].class0_hp[1]);
    printf("    %d/%d,\n",
           tnmvcounts.comps[i].hp[0],
           tnmvcounts.comps[i].hp[1]);
    printf("  },\n");
  }

  printf("\nProbs =\n  { ");
  for (j = 0; j < MV_JOINTS - 1; ++j)
    printf("%d, ", prob.joints[j]);
  printf("},\n");
  for (i=0; i< 2; ++i) {
    printf("  {\n");
    printf("    %d,\n", prob.comps[i].sign);
    printf("    { ");
    for (j = 0; j < MV_CLASSES - 1; ++j)
      printf("%d, ", prob.comps[i].classes[j]);
    printf("},\n");
    printf("    { ");
    for (j = 0; j < CLASS0_SIZE - 1; ++j)
      printf("%d, ", prob.comps[i].class0[j]);
    printf("},\n");
    printf("    { ");
    for (j = 0; j < MV_OFFSET_BITS; ++j)
      printf("%d, ", prob.comps[i].bits[j]);
    printf("},\n");
    printf("    { ");
    for (j = 0; j < CLASS0_SIZE; ++j) {
      printf("{");
      for (k = 0; k < 3; ++k)
        printf("%d, ", prob.comps[i].class0_fp[j][k]);
      printf("}, ");
    }
    printf("},\n");
    printf("    { ");
    for (j = 0; j < 3; ++j)
      printf("%d, ", prob.comps[i].fp[j]);
    printf("},\n");

    printf("    %d,\n", prob.comps[i].class0_hp);
    printf("    %d,\n", prob.comps[i].hp);
    printf("  },\n");
  }
}

John Koleszar's avatar
John Koleszar committed
345
346
static void add_nmvcount(nmv_context_counts* const dst,
                         const nmv_context_counts* const src) {
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
  int i, j, k;
  for (j = 0; j < MV_JOINTS; ++j) {
    dst->joints[j] += src->joints[j];
  }
  for (i = 0; i < 2; ++i) {
    for (j = 0; j < MV_VALS; ++j) {
      dst->comps[i].mvcount[j] += src->comps[i].mvcount[j];
    }
    dst->comps[i].sign[0] += src->comps[i].sign[0];
    dst->comps[i].sign[1] += src->comps[i].sign[1];
    for (j = 0; j < MV_CLASSES; ++j) {
      dst->comps[i].classes[j] += src->comps[i].classes[j];
    }
    for (j = 0; j < CLASS0_SIZE; ++j) {
      dst->comps[i].class0[j] += src->comps[i].class0[j];
    }
    for (j = 0; j < MV_OFFSET_BITS; ++j) {
      dst->comps[i].bits[j][0] += src->comps[i].bits[j][0];
      dst->comps[i].bits[j][1] += src->comps[i].bits[j][1];
    }
  }
  for (i = 0; i < 2; ++i) {
    for (j = 0; j < CLASS0_SIZE; ++j) {
      for (k = 0; k < 4; ++k) {
        dst->comps[i].class0_fp[j][k] += src->comps[i].class0_fp[j][k];
      }
    }
    for (j = 0; j < 4; ++j) {
      dst->comps[i].fp[j] += src->comps[i].fp[j];
    }
    dst->comps[i].class0_hp[0] += src->comps[i].class0_hp[0];
    dst->comps[i].class0_hp[1] += src->comps[i].class0_hp[1];
    dst->comps[i].hp[0] += src->comps[i].hp[0];
    dst->comps[i].hp[1] += src->comps[i].hp[1];
  }
}
#endif

Deb Mukherjee's avatar
Deb Mukherjee committed
385
void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer* const bc) {
386
387
388
389
390
391
392
393
394
395
396
  int i, j;
  nmv_context prob;
  unsigned int branch_ct_joint[MV_JOINTS - 1][2];
  unsigned int branch_ct_sign[2][2];
  unsigned int branch_ct_classes[2][MV_CLASSES - 1][2];
  unsigned int branch_ct_class0[2][CLASS0_SIZE - 1][2];
  unsigned int branch_ct_bits[2][MV_OFFSET_BITS][2];
  unsigned int branch_ct_class0_fp[2][CLASS0_SIZE][4 - 1][2];
  unsigned int branch_ct_fp[2][4 - 1][2];
  unsigned int branch_ct_class0_hp[2][2];
  unsigned int branch_ct_hp[2][2];
Jim Bankoski's avatar
Jim Bankoski committed
397
#ifdef MV_GROUP_UPDATE
398
  int savings = 0;
Jim Bankoski's avatar
Jim Bankoski committed
399
#endif
400
401
402
403
404

#ifdef NMV_STATS
  if (!cpi->dummy_packing)
    add_nmvcount(&tnmvcounts, &cpi->NMVcount);
#endif
405
  vp9_counts_to_nmv_context(&cpi->NMVcount, &prob, usehp,
406
407
408
409
410
411
412
413
414
415
                            branch_ct_joint, branch_ct_sign, branch_ct_classes,
                            branch_ct_class0, branch_ct_bits,
                            branch_ct_class0_fp, branch_ct_fp,
                            branch_ct_class0_hp, branch_ct_hp);
  /* write updates if they help */
#ifdef MV_GROUP_UPDATE
  for (j = 0; j < MV_JOINTS - 1; ++j) {
    savings += update_nmv_savings(branch_ct_joint[j],
                                  cpi->common.fc.nmvc.joints[j],
                                  prob.joints[j],
416
                                  VP9_NMV_UPDATE_PROB);
417
418
419
420
421
  }
  for (i = 0; i < 2; ++i) {
    savings += update_nmv_savings(branch_ct_sign[i],
                                  cpi->common.fc.nmvc.comps[i].sign,
                                  prob.comps[i].sign,
422
                                  VP9_NMV_UPDATE_PROB);
423
424
425
426
    for (j = 0; j < MV_CLASSES - 1; ++j) {
      savings += update_nmv_savings(branch_ct_classes[i][j],
                                    cpi->common.fc.nmvc.comps[i].classes[j],
                                    prob.comps[i].classes[j],
427
                                    VP9_NMV_UPDATE_PROB);
428
429
430
431
432
    }
    for (j = 0; j < CLASS0_SIZE - 1; ++j) {
      savings += update_nmv_savings(branch_ct_class0[i][j],
                                    cpi->common.fc.nmvc.comps[i].class0[j],
                                    prob.comps[i].class0[j],
433
                                    VP9_NMV_UPDATE_PROB);
434
435
436
437
438
    }
    for (j = 0; j < MV_OFFSET_BITS; ++j) {
      savings += update_nmv_savings(branch_ct_bits[i][j],
                                    cpi->common.fc.nmvc.comps[i].bits[j],
                                    prob.comps[i].bits[j],
439
                                    VP9_NMV_UPDATE_PROB);
440
441
442
443
444
445
446
447
448
    }
  }
  for (i = 0; i < 2; ++i) {
    for (j = 0; j < CLASS0_SIZE; ++j) {
      int k;
      for (k = 0; k < 3; ++k) {
        savings += update_nmv_savings(branch_ct_class0_fp[i][j][k],
                                      cpi->common.fc.nmvc.comps[i].class0_fp[j][k],
                                      prob.comps[i].class0_fp[j][k],
449
                                      VP9_NMV_UPDATE_PROB);
450
451
452
453
454
455
      }
    }
    for (j = 0; j < 3; ++j) {
      savings += update_nmv_savings(branch_ct_fp[i][j],
                                    cpi->common.fc.nmvc.comps[i].fp[j],
                                    prob.comps[i].fp[j],
456
                                    VP9_NMV_UPDATE_PROB);
457
458
459
460
461
462
463
    }
  }
  if (usehp) {
    for (i = 0; i < 2; ++i) {
      savings += update_nmv_savings(branch_ct_class0_hp[i],
                                    cpi->common.fc.nmvc.comps[i].class0_hp,
                                    prob.comps[i].class0_hp,
464
                                    VP9_NMV_UPDATE_PROB);
465
466
467
      savings += update_nmv_savings(branch_ct_hp[i],
                                    cpi->common.fc.nmvc.comps[i].hp,
                                    prob.comps[i].hp,
468
                                    VP9_NMV_UPDATE_PROB);
469
470
471
    }
  }
  if (savings <= 0) {
472
    vp9_write_bit(bc, 0);
473
474
    return;
  }
475
  vp9_write_bit(bc, 1);
476
477
478
#endif

  for (j = 0; j < MV_JOINTS - 1; ++j) {
John Koleszar's avatar
John Koleszar committed
479
    update_nmv(bc, branch_ct_joint[j],
480
481
               &cpi->common.fc.nmvc.joints[j],
               prob.joints[j],
482
               VP9_NMV_UPDATE_PROB);
483
484
  }
  for (i = 0; i < 2; ++i) {
John Koleszar's avatar
John Koleszar committed
485
    update_nmv(bc, branch_ct_sign[i],
486
487
               &cpi->common.fc.nmvc.comps[i].sign,
               prob.comps[i].sign,
488
               VP9_NMV_UPDATE_PROB);
489
    for (j = 0; j < MV_CLASSES - 1; ++j) {
John Koleszar's avatar
John Koleszar committed
490
      update_nmv(bc, branch_ct_classes[i][j],
491
492
                 &cpi->common.fc.nmvc.comps[i].classes[j],
                 prob.comps[i].classes[j],
493
                 VP9_NMV_UPDATE_PROB);
494
495
    }
    for (j = 0; j < CLASS0_SIZE - 1; ++j) {
John Koleszar's avatar
John Koleszar committed
496
      update_nmv(bc, branch_ct_class0[i][j],
497
498
                 &cpi->common.fc.nmvc.comps[i].class0[j],
                 prob.comps[i].class0[j],
499
                 VP9_NMV_UPDATE_PROB);
500
501
    }
    for (j = 0; j < MV_OFFSET_BITS; ++j) {
John Koleszar's avatar
John Koleszar committed
502
      update_nmv(bc, branch_ct_bits[i][j],
503
504
                 &cpi->common.fc.nmvc.comps[i].bits[j],
                 prob.comps[i].bits[j],
505
                 VP9_NMV_UPDATE_PROB);
506
507
508
509
510
511
    }
  }
  for (i = 0; i < 2; ++i) {
    for (j = 0; j < CLASS0_SIZE; ++j) {
      int k;
      for (k = 0; k < 3; ++k) {
John Koleszar's avatar
John Koleszar committed
512
        update_nmv(bc, branch_ct_class0_fp[i][j][k],
513
514
                   &cpi->common.fc.nmvc.comps[i].class0_fp[j][k],
                   prob.comps[i].class0_fp[j][k],
515
                   VP9_NMV_UPDATE_PROB);
516
517
518
      }
    }
    for (j = 0; j < 3; ++j) {
John Koleszar's avatar
John Koleszar committed
519
      update_nmv(bc, branch_ct_fp[i][j],
520
521
                 &cpi->common.fc.nmvc.comps[i].fp[j],
                 prob.comps[i].fp[j],
522
                 VP9_NMV_UPDATE_PROB);
523
524
525
526
    }
  }
  if (usehp) {
    for (i = 0; i < 2; ++i) {
John Koleszar's avatar
John Koleszar committed
527
      update_nmv(bc, branch_ct_class0_hp[i],
528
529
                 &cpi->common.fc.nmvc.comps[i].class0_hp,
                 prob.comps[i].class0_hp,
530
                 VP9_NMV_UPDATE_PROB);
John Koleszar's avatar
John Koleszar committed
531
      update_nmv(bc, branch_ct_hp[i],
532
533
                 &cpi->common.fc.nmvc.comps[i].hp,
                 prob.comps[i].hp,
534
                 VP9_NMV_UPDATE_PROB);
535
536
537
538
    }
  }
}

539
540
541
542
543
void vp9_encode_mv(vp9_writer* w, const MV* mv, const MV* ref,
                   const nmv_context* mvctx, int usehp) {
  const MV diff = {mv->row - ref->row,
                   mv->col - ref->col};
  const MV_JOINT_TYPE j = vp9_get_mv_joint(&diff);
544
  usehp = usehp && vp9_use_nmv_hp(ref);
545
546

  write_token(w, vp9_mv_joint_tree, mvctx->joints, &vp9_mv_joint_encodings[j]);
547
  if (mv_joint_vertical(j))
548
    encode_mv_component(w, diff.row, &mvctx->comps[0], usehp);
549
550

  if (mv_joint_horizontal(j))
551
    encode_mv_component(w, diff.col, &mvctx->comps[1], usehp);
552
553
}

554
void vp9_build_nmv_cost_table(int *mvjoint,
555
                              int *mvcost[2],
John Koleszar's avatar
John Koleszar committed
556
                              const nmv_context* const mvctx,
557
558
559
                              int usehp,
                              int mvc_flag_v,
                              int mvc_flag_h) {
560
  vp9_clear_system_state();
561
  vp9_cost_tokens(mvjoint, mvctx->joints, vp9_mv_joint_tree);
562
563
564
565
566
  if (mvc_flag_v)
    build_nmv_component_cost_table(mvcost[0], &mvctx->comps[0], usehp);
  if (mvc_flag_h)
    build_nmv_component_cost_table(mvcost[1], &mvctx->comps[1], usehp);
}
Deb Mukherjee's avatar
Deb Mukherjee committed
567
568
569
570
571

void vp9_update_nmv_count(VP9_COMP *cpi, MACROBLOCK *x,
                         int_mv *best_ref_mv, int_mv *second_best_ref_mv) {
  MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
  MV mv;
572
573
574
  int bwl = b_width_log2(mbmi->sb_type), bw = 1 << bwl;
  int bhl = b_height_log2(mbmi->sb_type), bh = 1 << bhl;
  int idx, idy;
Deb Mukherjee's avatar
Deb Mukherjee committed
575

576
577
578
#if CONFIG_AB4X4
  if (mbmi->sb_type < BLOCK_SIZE_SB8X8) {
#else
Deb Mukherjee's avatar
Deb Mukherjee committed
579
  if (mbmi->mode == SPLITMV) {
580
#endif
Deb Mukherjee's avatar
Deb Mukherjee committed
581
    int i;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
582
    PARTITION_INFO *pi = x->partition_info;
583
584
585
586
587
588
589
590
591
592
#if !CONFIG_AB4X4
    bw = 1, bh = 1;
#endif
    for (idy = 0; idy < 2; idy += bh) {
      for (idx = 0; idx < 2; idx += bw) {
        i = idy * 2 + idx;
        if (pi->bmi[i].mode == NEW4X4) {
          mv.row = (pi->bmi[i].mv.as_mv.row - best_ref_mv->as_mv.row);
          mv.col = (pi->bmi[i].mv.as_mv.col - best_ref_mv->as_mv.col);
          vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
593
                            x->e_mbd.allow_high_precision_mv);
594
595
596
597
598
599
600
601
          if (x->e_mbd.mode_info_context->mbmi.second_ref_frame > 0) {
            mv.row = pi->bmi[i].second_mv.as_mv.row -
                         second_best_ref_mv->as_mv.row;
            mv.col = pi->bmi[i].second_mv.as_mv.col -
                         second_best_ref_mv->as_mv.col;
            vp9_increment_nmv(&mv, &second_best_ref_mv->as_mv, &cpi->NMVcount,
                              x->e_mbd.allow_high_precision_mv);
          }
Deb Mukherjee's avatar
Deb Mukherjee committed
602
603
604
605
        }
      }
    }
  } else if (mbmi->mode == NEWMV) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
606
607
608
609
610
611
612
613
614
    mv.row = (mbmi->mv[0].as_mv.row - best_ref_mv->as_mv.row);
    mv.col = (mbmi->mv[0].as_mv.col - best_ref_mv->as_mv.col);
    vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount,
                      x->e_mbd.allow_high_precision_mv);
    if (mbmi->second_ref_frame > 0) {
      mv.row = (mbmi->mv[1].as_mv.row - second_best_ref_mv->as_mv.row);
      mv.col = (mbmi->mv[1].as_mv.col - second_best_ref_mv->as_mv.col);
      vp9_increment_nmv(&mv, &second_best_ref_mv->as_mv, &cpi->NMVcount,
                        x->e_mbd.allow_high_precision_mv);
Deb Mukherjee's avatar
Deb Mukherjee committed
615
616
617
    }
  }
}