vp9_encodemv.c 22 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
static void encode_nmv_component(vp9_writer* const bc,
28
29
                                 int v,
                                 int r,
John Koleszar's avatar
John Koleszar committed
30
                                 const nmv_component* const mvcomp) {
31
32
33
  int s, z, c, o, d;
  assert (v != 0);            /* should not be zero */
  s = v < 0;
34
  vp9_write(bc, s, mvcomp->sign);
35
36
  z = (s ? -v : v) - 1;       /* magnitude - 1 */

37
  c = vp9_get_mv_class(z, &o);
38

39
40
  write_token(bc, vp9_mv_class_tree, mvcomp->classes,
              vp9_mv_class_encodings + c);
41
42
43
44

  d = (o >> 3);               /* int mv data */

  if (c == MV_CLASS_0) {
45
46
    write_token(bc, vp9_mv_class0_tree, mvcomp->class0,
                vp9_mv_class0_encodings + d);
47
48
49
50
  } else {
    int i, b;
    b = c + CLASS0_BITS - 1;  /* number of bits */
    for (i = 0; i < b; ++i)
51
      vp9_write(bc, ((d >> i) & 1), mvcomp->bits[i]);
52
53
54
  }
}

55
static void encode_nmv_component_fp(vp9_writer *bc,
56
57
                                    int v,
                                    int r,
John Koleszar's avatar
John Koleszar committed
58
                                    const nmv_component* const mvcomp,
59
60
61
62
63
64
                                    int usehp) {
  int s, z, c, o, d, f, e;
  assert (v != 0);            /* should not be zero */
  s = v < 0;
  z = (s ? -v : v) - 1;       /* magnitude - 1 */

65
  c = vp9_get_mv_class(z, &o);
66
67
68
69
70
71
72

  d = (o >> 3);               /* int mv data */
  f = (o >> 1) & 3;           /* fractional pel mv data */
  e = (o & 1);                /* high precision mv data */

  /* Code the fractional pel bits */
  if (c == MV_CLASS_0) {
73
74
    write_token(bc, vp9_mv_fp_tree, mvcomp->class0_fp[d],
                vp9_mv_fp_encodings + f);
75
  } else {
76
77
    write_token(bc, vp9_mv_fp_tree, mvcomp->fp,
                vp9_mv_fp_encodings + f);
78
79
80
81
  }
  /* Code the high precision bit */
  if (usehp) {
    if (c == MV_CLASS_0) {
82
      vp9_write(bc, e, mvcomp->class0_hp);
83
    } else {
84
      vp9_write(bc, e, mvcomp->hp);
85
86
87
88
89
    }
  }
}

static void build_nmv_component_cost_table(int *mvcost,
John Koleszar's avatar
John Koleszar committed
90
                                           const nmv_component* const mvcomp,
91
92
93
94
95
96
97
                                           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];

98
99
  sign_cost[0] = vp9_cost_zero(mvcomp->sign);
  sign_cost[1] = vp9_cost_one(mvcomp->sign);
100
101
  vp9_cost_tokens(class_cost, mvcomp->classes, vp9_mv_class_tree);
  vp9_cost_tokens(class0_cost, mvcomp->class0, vp9_mv_class0_tree);
102
  for (i = 0; i < MV_OFFSET_BITS; ++i) {
103
104
    bits_cost[i][0] = vp9_cost_zero(mvcomp->bits[i]);
    bits_cost[i][1] = vp9_cost_one(mvcomp->bits[i]);
105
106
107
  }

  for (i = 0; i < CLASS0_SIZE; ++i)
108
109
    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);
110
111

  if (usehp) {
112
113
114
115
    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);
116
117
118
119
120
  }
  mvcost[0] = 0;
  for (v = 1; v <= MV_MAX; ++v) {
    int z, c, o, d, e, f, cost = 0;
    z = v - 1;
121
    c = vp9_get_mv_class(z, &o);
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
    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],
152
153
154
                              const vp9_prob cur_p,
                              const vp9_prob new_p,
                              const vp9_prob upd_p) {
155
156

#ifdef LOW_PRECISION_MV_UPDATE
157
  vp9_prob mod_p = new_p | 1;
158
#else
159
  vp9_prob mod_p = new_p;
160
#endif
161
162
  const int cur_b = cost_branch256(ct, cur_p);
  const int mod_b = cost_branch256(ct, mod_p);
163
164
165
166
  const int cost = 7 * 256 +
#ifndef LOW_PRECISION_MV_UPDATE
      256 +
#endif
167
      (vp9_cost_one(upd_p) - vp9_cost_zero(upd_p));
168
169
170
  if (cur_b - mod_b - cost > 0) {
    return cur_b - mod_b - cost;
  } else {
171
    return 0 - vp9_cost_zero(upd_p);
172
173
174
175
  }
}

static int update_nmv(
176
  vp9_writer *const bc,
177
  const unsigned int ct[2],
178
179
180
  vp9_prob *const cur_p,
  const vp9_prob new_p,
  const vp9_prob upd_p) {
181
182

#ifdef LOW_PRECISION_MV_UPDATE
183
  vp9_prob mod_p = new_p | 1;
184
#else
185
  vp9_prob mod_p = new_p;
186
187
#endif

188
189
  const int cur_b = cost_branch256(ct, *cur_p);
  const int mod_b = cost_branch256(ct, mod_p);
190
191
192
193
  const int cost = 7 * 256 +
#ifndef LOW_PRECISION_MV_UPDATE
      256 +
#endif
194
      (vp9_cost_one(upd_p) - vp9_cost_zero(upd_p));
195
196
197

  if (cur_b - mod_b > cost) {
    *cur_p = mod_p;
198
    vp9_write(bc, 1, upd_p);
199
#ifdef LOW_PRECISION_MV_UPDATE
200
    vp9_write_literal(bc, mod_p >> 1, 7);
201
#else
202
    vp9_write_literal(bc, mod_p, 8);
203
204
205
#endif
    return 1;
  } else {
206
    vp9_write(bc, 0, upd_p);
207
208
209
210
    return 0;
  }
}

Deb Mukherjee's avatar
Deb Mukherjee committed
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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
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");
  }
}

259
260
#ifdef NMV_STATS
void init_nmvstats() {
261
  vp9_zero(tnmvcounts);
262
263
264
265
266
267
268
269
270
271
272
273
274
275
}

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;
276
  vp9_counts_to_nmv_context(&tnmvcounts, &prob, 1,
277
278
279
280
281
282
283
284
285
                            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
286
  for (i = 0; i < 2; ++i) {
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
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
    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
365
366
static void add_nmvcount(nmv_context_counts* const dst,
                         const nmv_context_counts* const src) {
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
  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
405
void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer* const bc) {
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
  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];
  int savings = 0;

#ifdef NMV_STATS
  if (!cpi->dummy_packing)
    add_nmvcount(&tnmvcounts, &cpi->NMVcount);
#endif
423
  vp9_counts_to_nmv_context(&cpi->NMVcount, &prob, usehp,
424
425
426
427
428
429
430
431
432
433
                            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],
434
                                  VP9_NMV_UPDATE_PROB);
435
436
437
438
439
  }
  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,
440
                                  VP9_NMV_UPDATE_PROB);
441
442
443
444
    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],
445
                                    VP9_NMV_UPDATE_PROB);
446
447
448
449
450
    }
    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],
451
                                    VP9_NMV_UPDATE_PROB);
452
453
454
455
456
    }
    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],
457
                                    VP9_NMV_UPDATE_PROB);
458
459
460
461
462
463
464
465
466
    }
  }
  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],
467
                                      VP9_NMV_UPDATE_PROB);
468
469
470
471
472
473
      }
    }
    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],
474
                                    VP9_NMV_UPDATE_PROB);
475
476
477
478
479
480
481
    }
  }
  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,
482
                                    VP9_NMV_UPDATE_PROB);
483
484
485
      savings += update_nmv_savings(branch_ct_hp[i],
                                    cpi->common.fc.nmvc.comps[i].hp,
                                    prob.comps[i].hp,
486
                                    VP9_NMV_UPDATE_PROB);
487
488
489
    }
  }
  if (savings <= 0) {
490
    vp9_write_bit(bc, 0);
491
492
    return;
  }
493
  vp9_write_bit(bc, 1);
494
495
496
#endif

  for (j = 0; j < MV_JOINTS - 1; ++j) {
John Koleszar's avatar
John Koleszar committed
497
    update_nmv(bc, branch_ct_joint[j],
498
499
               &cpi->common.fc.nmvc.joints[j],
               prob.joints[j],
500
               VP9_NMV_UPDATE_PROB);
501
502
  }
  for (i = 0; i < 2; ++i) {
John Koleszar's avatar
John Koleszar committed
503
    update_nmv(bc, branch_ct_sign[i],
504
505
               &cpi->common.fc.nmvc.comps[i].sign,
               prob.comps[i].sign,
506
               VP9_NMV_UPDATE_PROB);
507
    for (j = 0; j < MV_CLASSES - 1; ++j) {
John Koleszar's avatar
John Koleszar committed
508
      update_nmv(bc, branch_ct_classes[i][j],
509
510
                 &cpi->common.fc.nmvc.comps[i].classes[j],
                 prob.comps[i].classes[j],
511
                 VP9_NMV_UPDATE_PROB);
512
513
    }
    for (j = 0; j < CLASS0_SIZE - 1; ++j) {
John Koleszar's avatar
John Koleszar committed
514
      update_nmv(bc, branch_ct_class0[i][j],
515
516
                 &cpi->common.fc.nmvc.comps[i].class0[j],
                 prob.comps[i].class0[j],
517
                 VP9_NMV_UPDATE_PROB);
518
519
    }
    for (j = 0; j < MV_OFFSET_BITS; ++j) {
John Koleszar's avatar
John Koleszar committed
520
      update_nmv(bc, branch_ct_bits[i][j],
521
522
                 &cpi->common.fc.nmvc.comps[i].bits[j],
                 prob.comps[i].bits[j],
523
                 VP9_NMV_UPDATE_PROB);
524
525
526
527
528
529
    }
  }
  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
530
        update_nmv(bc, branch_ct_class0_fp[i][j][k],
531
532
                   &cpi->common.fc.nmvc.comps[i].class0_fp[j][k],
                   prob.comps[i].class0_fp[j][k],
533
                   VP9_NMV_UPDATE_PROB);
534
535
536
      }
    }
    for (j = 0; j < 3; ++j) {
John Koleszar's avatar
John Koleszar committed
537
      update_nmv(bc, branch_ct_fp[i][j],
538
539
                 &cpi->common.fc.nmvc.comps[i].fp[j],
                 prob.comps[i].fp[j],
540
                 VP9_NMV_UPDATE_PROB);
541
542
543
544
    }
  }
  if (usehp) {
    for (i = 0; i < 2; ++i) {
John Koleszar's avatar
John Koleszar committed
545
      update_nmv(bc, branch_ct_class0_hp[i],
546
547
                 &cpi->common.fc.nmvc.comps[i].class0_hp,
                 prob.comps[i].class0_hp,
548
                 VP9_NMV_UPDATE_PROB);
John Koleszar's avatar
John Koleszar committed
549
      update_nmv(bc, branch_ct_hp[i],
550
551
                 &cpi->common.fc.nmvc.comps[i].hp,
                 prob.comps[i].hp,
552
                 VP9_NMV_UPDATE_PROB);
553
554
555
556
    }
  }
}

557
void vp9_encode_nmv(vp9_writer* const bc, const MV* const mv,
John Koleszar's avatar
John Koleszar committed
558
                    const MV* const ref, const nmv_context* const mvctx) {
559
  MV_JOINT_TYPE j = vp9_get_mv_joint(*mv);
560
561
  write_token(bc, vp9_mv_joint_tree, mvctx->joints,
              vp9_mv_joint_encodings + j);
562
  if (j == MV_JOINT_HZVNZ || j == MV_JOINT_HNZVNZ) {
John Koleszar's avatar
John Koleszar committed
563
    encode_nmv_component(bc, mv->row, ref->col, &mvctx->comps[0]);
564
565
  }
  if (j == MV_JOINT_HNZVZ || j == MV_JOINT_HNZVNZ) {
John Koleszar's avatar
John Koleszar committed
566
    encode_nmv_component(bc, mv->col, ref->col, &mvctx->comps[1]);
567
568
569
  }
}

570
void vp9_encode_nmv_fp(vp9_writer* const bc, const MV* const mv,
John Koleszar's avatar
John Koleszar committed
571
572
                       const MV* const ref, const nmv_context* const mvctx,
                       int usehp) {
573
574
  MV_JOINT_TYPE j = vp9_get_mv_joint(*mv);
  usehp = usehp && vp9_use_nmv_hp(ref);
575
  if (j == MV_JOINT_HZVNZ || j == MV_JOINT_HNZVNZ) {
John Koleszar's avatar
John Koleszar committed
576
    encode_nmv_component_fp(bc, mv->row, ref->row, &mvctx->comps[0], usehp);
577
578
  }
  if (j == MV_JOINT_HNZVZ || j == MV_JOINT_HNZVNZ) {
John Koleszar's avatar
John Koleszar committed
579
    encode_nmv_component_fp(bc, mv->col, ref->col, &mvctx->comps[1], usehp);
580
581
582
  }
}

583
void vp9_build_nmv_cost_table(int *mvjoint,
584
                              int *mvcost[2],
John Koleszar's avatar
John Koleszar committed
585
                              const nmv_context* const mvctx,
586
587
588
                              int usehp,
                              int mvc_flag_v,
                              int mvc_flag_h) {
589
  vp9_clear_system_state();
590
  vp9_cost_tokens(mvjoint, mvctx->joints, vp9_mv_joint_tree);
591
592
593
594
595
  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
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612

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;

  if (mbmi->mode == SPLITMV) {
    int i;

    for (i = 0; i < x->partition_info->count; i++) {
      if (x->partition_info->bmi[i].mode == NEW4X4) {
        if (x->e_mbd.allow_high_precision_mv) {
          mv.row = (x->partition_info->bmi[i].mv.as_mv.row
                    - best_ref_mv->as_mv.row);
          mv.col = (x->partition_info->bmi[i].mv.as_mv.col
                    - best_ref_mv->as_mv.col);
          vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount, 1);
613
          if (x->e_mbd.mode_info_context->mbmi.second_ref_frame > 0) {
Deb Mukherjee's avatar
Deb Mukherjee committed
614
615
616
617
618
619
620
621
622
623
624
625
626
            mv.row = (x->partition_info->bmi[i].second_mv.as_mv.row
                      - second_best_ref_mv->as_mv.row);
            mv.col = (x->partition_info->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, 1);
          }
        } else {
          mv.row = (x->partition_info->bmi[i].mv.as_mv.row
                    - best_ref_mv->as_mv.row);
          mv.col = (x->partition_info->bmi[i].mv.as_mv.col
                    - best_ref_mv->as_mv.col);
          vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount, 0);
627
          if (x->e_mbd.mode_info_context->mbmi.second_ref_frame > 0) {
Deb Mukherjee's avatar
Deb Mukherjee committed
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
            mv.row = (x->partition_info->bmi[i].second_mv.as_mv.row
                      - second_best_ref_mv->as_mv.row);
            mv.col = (x->partition_info->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, 0);
          }
        }
      }
    }
  } else if (mbmi->mode == NEWMV) {
    if (x->e_mbd.allow_high_precision_mv) {
      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, 1);
643
      if (mbmi->second_ref_frame > 0) {
Deb Mukherjee's avatar
Deb Mukherjee committed
644
645
646
647
648
649
650
651
        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, 1);
      }
    } else {
      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, 0);
652
      if (mbmi->second_ref_frame > 0) {
Deb Mukherjee's avatar
Deb Mukherjee committed
653
654
655
656
657
658
659
        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, 0);
      }
    }
  }
}