vp9_encodemv.c 20.8 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
  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
417
#ifdef MV_GROUP_UPDATE
418
  int savings = 0;
Jim Bankoski's avatar
Jim Bankoski committed
419
#endif
420
421
422
423
424

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

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

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

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

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

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;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
606
607
608
609
610
611
612
613
614
615
616
617
618
619
    PARTITION_INFO *pi = x->partition_info;
    for (i = 0; i < pi->count; i++) {
      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,
                          x->e_mbd.allow_high_precision_mv);
        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
620
621
622
623
        }
      }
    }
  } else if (mbmi->mode == NEWMV) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
624
625
626
627
628
629
630
631
632
    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
633
634
635
    }
  }
}