vp9_mvref_common.c 13.9 KB
Newer Older
Paul Wilkins's avatar
Paul Wilkins committed
1
2
3
4
5
6
7
8
9
10
/*
 *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

11
#include "vp9/common/vp9_mvref_common.h"
Paul Wilkins's avatar
Paul Wilkins committed
12
13

#define MVREF_NEIGHBOURS 8
Dmitry Kovalev's avatar
Dmitry Kovalev committed
14

15
16
17
18
static int mb_mv_ref_search[MVREF_NEIGHBOURS][2] = {
    {0, -1}, {-1, 0}, {-1, -1}, {0, -2},
    {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}
};
Dmitry Kovalev's avatar
Dmitry Kovalev committed
19

20
21
static int mb_ref_distance_weight[MVREF_NEIGHBOURS] =
  { 3, 3, 2, 1, 1, 1, 1, 1 };
Dmitry Kovalev's avatar
Dmitry Kovalev committed
22

23
24
25
26
static int sb_mv_ref_search[MVREF_NEIGHBOURS][2] = {
    {0, -1}, {-1, 0}, {1, -1}, {-1, 1},
    {-1, -1}, {0, -2}, {-2, 0}, {-1, -2}
};
Dmitry Kovalev's avatar
Dmitry Kovalev committed
27

28
29
static int sb_ref_distance_weight[MVREF_NEIGHBOURS] =
  { 3, 3, 2, 2, 2, 1, 1, 1 };
30

Paul Wilkins's avatar
Paul Wilkins committed
31
// clamp_mv_ref
Paul Wilkins's avatar
Paul Wilkins committed
32
33
#define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units

Dmitry Kovalev's avatar
Dmitry Kovalev committed
34
static void clamp_mv_ref(const MACROBLOCKD *xd, int_mv *mv) {
Paul Wilkins's avatar
Paul Wilkins committed
35
36
37
38
39
40
41
42
43
44
45
  if (mv->as_mv.col < (xd->mb_to_left_edge - MV_BORDER))
    mv->as_mv.col = xd->mb_to_left_edge - MV_BORDER;
  else if (mv->as_mv.col > xd->mb_to_right_edge + MV_BORDER)
    mv->as_mv.col = xd->mb_to_right_edge + MV_BORDER;

  if (mv->as_mv.row < (xd->mb_to_top_edge - MV_BORDER))
    mv->as_mv.row = xd->mb_to_top_edge - MV_BORDER;
  else if (mv->as_mv.row > xd->mb_to_bottom_edge + MV_BORDER)
    mv->as_mv.row = xd->mb_to_bottom_edge + MV_BORDER;
}

46
47
// Gets a candidate refenence motion vector from the given mode info
// structure if one exists that matches the given reference frame.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
48
static int get_matching_candidate(const MODE_INFO *candidate_mi,
49
  MV_REFERENCE_FRAME ref_frame,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
50
  int_mv *c_mv) {
51
52
53
54
55
56
57
58
59
60
61
62
  int ret_val = TRUE;

  if (ref_frame == candidate_mi->mbmi.ref_frame) {
    c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
  } else if (ref_frame == candidate_mi->mbmi.second_ref_frame) {
    c_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
  } else {
    ret_val = FALSE;
  }

  return ret_val;
}
Paul Wilkins's avatar
Paul Wilkins committed
63

64
65
66
// Gets candidate refenence motion vector(s) from the given mode info
// structure if they exists and do NOT match the given reference frame.
static void get_non_matching_candidates(
Paul Wilkins's avatar
Paul Wilkins committed
67
68
  const MODE_INFO *candidate_mi,
  MV_REFERENCE_FRAME ref_frame,
Paul Wilkins's avatar
Paul Wilkins committed
69
70
71
72
  MV_REFERENCE_FRAME *c_ref_frame,
  int_mv *c_mv,
  MV_REFERENCE_FRAME *c2_ref_frame,
  int_mv *c2_mv
Paul Wilkins's avatar
Paul Wilkins committed
73
74
) {

75
  c_mv->as_int = 0;
Paul Wilkins's avatar
Paul Wilkins committed
76
  c2_mv->as_int = 0;
77
  *c_ref_frame = INTRA_FRAME;
Paul Wilkins's avatar
Paul Wilkins committed
78
  *c2_ref_frame = INTRA_FRAME;
Paul Wilkins's avatar
Paul Wilkins committed
79

80
81
82
83
84
85
  // If first candidate not valid neither will be.
  if (candidate_mi->mbmi.ref_frame > INTRA_FRAME) {
    // First candidate
    if (candidate_mi->mbmi.ref_frame != ref_frame) {
      *c_ref_frame = candidate_mi->mbmi.ref_frame;
      c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
Paul Wilkins's avatar
Paul Wilkins committed
86
87
    }

88
    // Second candidate
89
    if ((candidate_mi->mbmi.second_ref_frame > INTRA_FRAME) &&
Paul Wilkins's avatar
Paul Wilkins committed
90
91
92
        (candidate_mi->mbmi.second_ref_frame != ref_frame) &&
        (candidate_mi->mbmi.mv[1].as_int !=
         candidate_mi->mbmi.mv[0].as_int)) {
Paul Wilkins's avatar
Paul Wilkins committed
93
      *c2_ref_frame = candidate_mi->mbmi.second_ref_frame;
94
      c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
Paul Wilkins's avatar
Paul Wilkins committed
95
    }
Paul Wilkins's avatar
Paul Wilkins committed
96
97
98
  }
}

Paul Wilkins's avatar
Paul Wilkins committed
99
100

// Performs mv sign inversion if indicated by the reference frame combination.
Paul Wilkins's avatar
Paul Wilkins committed
101
static void scale_mv(
Paul Wilkins's avatar
Paul Wilkins committed
102
103
104
105
106
107
  MACROBLOCKD *xd,
  MV_REFERENCE_FRAME this_ref_frame,
  MV_REFERENCE_FRAME candidate_ref_frame,
  int_mv *candidate_mv,
  int *ref_sign_bias
) {
Paul Wilkins's avatar
Paul Wilkins committed
108
109
110
111
112
113
114
115
116
  // int frame_distances[MAX_REF_FRAMES];
  // int last_distance = 1;
  // int gf_distance = xd->frames_since_golden;
  // int arf_distance = xd->frames_till_alt_ref_frame;

  // Sign inversion where appropriate.
  if (ref_sign_bias[candidate_ref_frame] != ref_sign_bias[this_ref_frame]) {
    candidate_mv->as_mv.row = -candidate_mv->as_mv.row;
    candidate_mv->as_mv.col = -candidate_mv->as_mv.col;
Paul Wilkins's avatar
Paul Wilkins committed
117
118
  }

Paul Wilkins's avatar
Paul Wilkins committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
  /*
  // Scale based on frame distance if the reference frames not the same.
  frame_distances[INTRA_FRAME] = 1;   // should never be used
  frame_distances[LAST_FRAME] = 1;
  frame_distances[GOLDEN_FRAME] =
    (xd->frames_since_golden) ? xd->frames_si nce_golden : 1;
  frame_distances[ALTREF_FRAME] =
    (xd->frames_till_alt_ref_frame) ? xd->frames_till_alt_ref_frame : 1;

  if (frame_distances[this_ref_frame] &&
      frame_distances[candidate_ref_frame]) {
    candidate_mv->as_mv.row =
      (short)(((int)(candidate_mv->as_mv.row) *
               frame_distances[this_ref_frame]) /
              frame_distances[candidate_ref_frame]);

    candidate_mv->as_mv.col =
      (short)(((int)(candidate_mv->as_mv.col) *
               frame_distances[this_ref_frame]) /
              frame_distances[candidate_ref_frame]);
  }
  */
Paul Wilkins's avatar
Paul Wilkins committed
141
142
}

Paul Wilkins's avatar
Paul Wilkins committed
143
144
145
146
147
148
149
150
151
152
/*
// Adds a new candidate reference vector to the sorted list.
// If it is a repeat the weight of the existing entry is increased
// and the order of the list is resorted.
// This method of add plus sort has been deprecated for now as there is a
// further sort of the best candidates in vp9_find_best_ref_mvs() and the
// incremental benefit of both is small. If the decision is made to remove
// the sort in vp9_find_best_ref_mvs() for performance reasons then it may be
// worth re-instating some sort of list reordering by weight here.
//
Paul Wilkins's avatar
Paul Wilkins committed
153
static void addmv_and_shuffle(
Paul Wilkins's avatar
Paul Wilkins committed
154
155
  int_mv *mv_list,
  int *mv_scores,
Paul Wilkins's avatar
Paul Wilkins committed
156
  int *refmv_count,
Paul Wilkins's avatar
Paul Wilkins committed
157
158
159
160
  int_mv candidate_mv,
  int weight
) {

Paul Wilkins's avatar
Paul Wilkins committed
161
162
  int i;
  int insert_point;
Paul Wilkins's avatar
Paul Wilkins committed
163
164
  int duplicate_found = FALSE;

Paul Wilkins's avatar
Paul Wilkins committed
165
166
  // Check for duplicates. If there is one increase its score.
  // We only compare vs the current top candidates.
Paul Wilkins's avatar
Paul Wilkins committed
167
168
  insert_point = (*refmv_count < (MAX_MV_REF_CANDIDATES - 1))
                 ? *refmv_count : (MAX_MV_REF_CANDIDATES - 1);
Paul Wilkins's avatar
Paul Wilkins committed
169
170

  i = insert_point;
Paul Wilkins's avatar
Paul Wilkins committed
171
  if (*refmv_count > i)
Paul Wilkins's avatar
Paul Wilkins committed
172
    i++;
Paul Wilkins's avatar
Paul Wilkins committed
173
174
175
176
177
178
179
180
181
  while (i > 0) {
    i--;
    if (candidate_mv.as_int == mv_list[i].as_int) {
      duplicate_found = TRUE;
      mv_scores[i] += weight;
      break;
    }
  }

Paul Wilkins's avatar
Paul Wilkins committed
182
183
184
185
186
187
188
  // If no duplicate and the new candidate is good enough then add it.
  if (!duplicate_found ) {
    if (weight > mv_scores[insert_point]) {
      mv_list[insert_point].as_int = candidate_mv.as_int;
      mv_scores[insert_point] = weight;
      i = insert_point;
    }
Paul Wilkins's avatar
Paul Wilkins committed
189
    (*refmv_count)++;
Paul Wilkins's avatar
Paul Wilkins committed
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
  }

  // Reshuffle the list so that highest scoring mvs at the top.
  while (i > 0) {
    if (mv_scores[i] > mv_scores[i-1]) {
      int tmp_score = mv_scores[i-1];
      int_mv tmp_mv = mv_list[i-1];

      mv_scores[i-1] = mv_scores[i];
      mv_list[i-1] = mv_list[i];
      mv_scores[i] = tmp_score;
      mv_list[i] = tmp_mv;
      i--;
    } else
      break;
  }
}
Paul Wilkins's avatar
Paul Wilkins committed
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
239
240
241
242
*/

// Adds a new candidate reference vector to the list.
// The mv is thrown out if it is already in the list.
// Unlike the addmv_and_shuffle() this does not reorder the list
// but assumes that candidates are added in the order most likely to
// match distance and reference frame bias.
static void add_candidate_mv(
  int_mv *mv_list,
  int *mv_scores,
  int *candidate_count,
  int_mv candidate_mv,
  int weight
) {
  int i;
  int insert_point;

  // Make sure we dont insert off the end of the list
  insert_point = (*candidate_count < (MAX_MV_REF_CANDIDATES - 1))
                 ? *candidate_count : (MAX_MV_REF_CANDIDATES - 1);

  // Look for duplicates
  for (i = 0; i <= insert_point; ++i) {
    if (candidate_mv.as_int == mv_list[i].as_int)
      break;
  }

  // Add the candidate. If the list is already full it is only desirable that
  // it should overwrite if it has a higher weight than the last entry.
  if ((i >= insert_point) &&
      (weight > mv_scores[insert_point])) {
    mv_list[insert_point].as_int = candidate_mv.as_int;
    mv_scores[insert_point] = weight;
    *candidate_count += (*candidate_count < MAX_MV_REF_CANDIDATES);
  }
}
Paul Wilkins's avatar
Paul Wilkins committed
243
244
245
246

// This function searches the neighbourhood of a given MB/SB and populates a
// list of candidate reference vectors.
//
Paul Wilkins's avatar
Paul Wilkins committed
247
void vp9_find_mv_refs(
248
  VP9_COMMON *cm,
Paul Wilkins's avatar
Paul Wilkins committed
249
250
251
252
253
254
255
256
257
258
  MACROBLOCKD *xd,
  MODE_INFO *here,
  MODE_INFO *lf_here,
  MV_REFERENCE_FRAME ref_frame,
  int_mv *mv_ref_list,
  int *ref_sign_bias
) {

  int i;
  MODE_INFO *candidate_mi;
Paul Wilkins's avatar
Paul Wilkins committed
259
  MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
Paul Wilkins's avatar
Paul Wilkins committed
260
  int_mv candidate_mvs[MAX_MV_REF_CANDIDATES];
Paul Wilkins's avatar
Paul Wilkins committed
261
  int_mv c_refmv;
Paul Wilkins's avatar
Paul Wilkins committed
262
  int_mv c2_refmv;
Paul Wilkins's avatar
Paul Wilkins committed
263
  MV_REFERENCE_FRAME c_ref_frame;
Paul Wilkins's avatar
Paul Wilkins committed
264
  MV_REFERENCE_FRAME c2_ref_frame;
Paul Wilkins's avatar
Paul Wilkins committed
265
  int candidate_scores[MAX_MV_REF_CANDIDATES];
Paul Wilkins's avatar
Paul Wilkins committed
266
  int refmv_count = 0;
267
  int split_count = 0;
268
269
  int (*mv_ref_search)[2];
  int *ref_distance_weight;
Paul Wilkins's avatar
Paul Wilkins committed
270
  int zero_seen = FALSE;
271
  const int mb_col = (-xd->mb_to_left_edge) >> 7;
Paul Wilkins's avatar
Paul Wilkins committed
272
273

  // Blank the reference vector lists and other local structures.
Paul Wilkins's avatar
Paul Wilkins committed
274
275
  vpx_memset(mv_ref_list, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
  vpx_memset(candidate_mvs, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
Paul Wilkins's avatar
Paul Wilkins committed
276
277
  vpx_memset(candidate_scores, 0, sizeof(candidate_scores));

Ronald S. Bultje's avatar
Ronald S. Bultje committed
278
  if (mbmi->sb_type) {
279
280
281
282
283
284
    mv_ref_search = sb_mv_ref_search;
    ref_distance_weight = sb_ref_distance_weight;
  } else {
    mv_ref_search = mb_mv_ref_search;
    ref_distance_weight = mb_ref_distance_weight;
  }
285
286
287

  // We first scan for candidate vectors that match the current reference frame
  // Look at nearest neigbours
Paul Wilkins's avatar
Paul Wilkins committed
288
  for (i = 0; i < 2; ++i) {
289
290
291
292
    const int mb_search_col = mb_col + mv_ref_search[i][0];

    if ((mb_search_col >= cm->cur_tile_mb_col_start) &&
        (mb_search_col < cm->cur_tile_mb_col_end) &&
Paul Wilkins's avatar
Paul Wilkins committed
293
294
295
296
297
        ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {

      candidate_mi = here + mv_ref_search[i][0] +
                     (mv_ref_search[i][1] * xd->mode_info_stride);

298
      if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
Paul Wilkins's avatar
Paul Wilkins committed
299
300
        add_candidate_mv(candidate_mvs, candidate_scores,
                         &refmv_count, c_refmv, ref_distance_weight[i] + 16);
Paul Wilkins's avatar
Paul Wilkins committed
301
      }
302
      split_count += (candidate_mi->mbmi.mode == SPLITMV);
Paul Wilkins's avatar
Paul Wilkins committed
303
304
    }
  }
305
306
307
308
  // Look in the last frame if it exists
  if (lf_here) {
    candidate_mi = lf_here;
    if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
Paul Wilkins's avatar
Paul Wilkins committed
309
310
      add_candidate_mv(candidate_mvs, candidate_scores,
                       &refmv_count, c_refmv, 18);
311
    }
Paul Wilkins's avatar
Paul Wilkins committed
312
  }
313
314
  // More distant neigbours
  for (i = 2; (i < MVREF_NEIGHBOURS) &&
Paul Wilkins's avatar
Paul Wilkins committed
315
              (refmv_count < (MAX_MV_REF_CANDIDATES - 1)); ++i) {
316
317
318
319
    const int mb_search_col = mb_col + mv_ref_search[i][0];

    if ((mb_search_col >= cm->cur_tile_mb_col_start) &&
        (mb_search_col < cm->cur_tile_mb_col_end) &&
Paul Wilkins's avatar
Paul Wilkins committed
320
321
322
323
        ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {
      candidate_mi = here + mv_ref_search[i][0] +
                     (mv_ref_search[i][1] * xd->mode_info_stride);

324
      if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
Paul Wilkins's avatar
Paul Wilkins committed
325
326
        add_candidate_mv(candidate_mvs, candidate_scores,
                         &refmv_count, c_refmv, ref_distance_weight[i] + 16);
327
328
329
      }
    }
  }
Paul Wilkins's avatar
Paul Wilkins committed
330

331
332
333
334
  // If we have not found enough candidates consider ones where the
  // reference frame does not match. Break out when we have
  // MAX_MV_REF_CANDIDATES candidates.
  // Look first at spatial neighbours
Paul Wilkins's avatar
Paul Wilkins committed
335
  if (refmv_count < (MAX_MV_REF_CANDIDATES - 1)) {
336
    for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
337
338
339
340
      const int mb_search_col = mb_col + mv_ref_search[i][0];

      if ((mb_search_col >= cm->cur_tile_mb_col_start) &&
          (mb_search_col < cm->cur_tile_mb_col_end) &&
341
          ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {
Paul Wilkins's avatar
Paul Wilkins committed
342

343
344
        candidate_mi = here + mv_ref_search[i][0] +
                       (mv_ref_search[i][1] * xd->mode_info_stride);
Paul Wilkins's avatar
Paul Wilkins committed
345

346
347
348
        get_non_matching_candidates(candidate_mi, ref_frame,
                                    &c_ref_frame, &c_refmv,
                                    &c2_ref_frame, &c2_refmv);
Paul Wilkins's avatar
Paul Wilkins committed
349

350
351
        if (c_ref_frame != INTRA_FRAME) {
          scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias);
Paul Wilkins's avatar
Paul Wilkins committed
352
353
          add_candidate_mv(candidate_mvs, candidate_scores,
                           &refmv_count, c_refmv, ref_distance_weight[i]);
354
355
356
357
        }

        if (c2_ref_frame != INTRA_FRAME) {
          scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias);
Paul Wilkins's avatar
Paul Wilkins committed
358
359
          add_candidate_mv(candidate_mvs, candidate_scores,
                           &refmv_count, c2_refmv, ref_distance_weight[i]);
Paul Wilkins's avatar
Paul Wilkins committed
360
        }
Paul Wilkins's avatar
Paul Wilkins committed
361
      }
362

Paul Wilkins's avatar
Paul Wilkins committed
363
      if (refmv_count >= (MAX_MV_REF_CANDIDATES - 1)) {
364
365
366
367
        break;
      }
    }
  }
368
  // Look at the last frame if it exists
Paul Wilkins's avatar
Paul Wilkins committed
369
  if (refmv_count < (MAX_MV_REF_CANDIDATES - 1) && lf_here) {
370
371
372
373
374
375
376
    candidate_mi = lf_here;
    get_non_matching_candidates(candidate_mi, ref_frame,
                                &c_ref_frame, &c_refmv,
                                &c2_ref_frame, &c2_refmv);

    if (c_ref_frame != INTRA_FRAME) {
      scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias);
Paul Wilkins's avatar
Paul Wilkins committed
377
378
      add_candidate_mv(candidate_mvs, candidate_scores,
                       &refmv_count, c_refmv, 2);
379
380
381
382
    }

    if (c2_ref_frame != INTRA_FRAME) {
      scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias);
Paul Wilkins's avatar
Paul Wilkins committed
383
384
      add_candidate_mv(candidate_mvs, candidate_scores,
                       &refmv_count, c2_refmv, 2);
Paul Wilkins's avatar
Paul Wilkins committed
385
386
387
    }
  }

388
389
  // Define inter mode coding context.
  // 0,0 was best
Paul Wilkins's avatar
Paul Wilkins committed
390
  if (candidate_mvs[0].as_int == 0) {
391
    // 0,0 is only candidate
Paul Wilkins's avatar
Paul Wilkins committed
392
    if (refmv_count <= 1) {
Paul Wilkins's avatar
Paul Wilkins committed
393
      mbmi->mb_mode_context[ref_frame] = 0;
394
395
    // non zero candidates candidates available
    } else if (split_count == 0) {
Paul Wilkins's avatar
Paul Wilkins committed
396
397
398
399
      mbmi->mb_mode_context[ref_frame] = 1;
    } else {
      mbmi->mb_mode_context[ref_frame] = 2;
    }
400
401
  // Non zero best, No Split MV cases
  } else if (split_count == 0) {
Paul Wilkins's avatar
Paul Wilkins committed
402
    if (candidate_scores[0] >= 16) {
Paul Wilkins's avatar
Paul Wilkins committed
403
404
405
406
      mbmi->mb_mode_context[ref_frame] = 3;
    } else {
      mbmi->mb_mode_context[ref_frame] = 4;
    }
407
  // Non zero best, some split mv
Paul Wilkins's avatar
Paul Wilkins committed
408
  } else {
Paul Wilkins's avatar
Paul Wilkins committed
409
    if (candidate_scores[0] >= 16) {
410
411
412
413
      mbmi->mb_mode_context[ref_frame] = 5;
    } else {
      mbmi->mb_mode_context[ref_frame] = 6;
    }
Paul Wilkins's avatar
Paul Wilkins committed
414
415
  }

Paul Wilkins's avatar
Paul Wilkins committed
416
  // Scan for 0,0 case and clamp non zero choices
Paul Wilkins's avatar
Paul Wilkins committed
417
  for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
Paul Wilkins's avatar
Paul Wilkins committed
418
419
420
421
422
    if (candidate_mvs[i].as_int == 0) {
      zero_seen = TRUE;
    } else {
      clamp_mv_ref(xd, &candidate_mvs[i]);
    }
423
  }
Paul Wilkins's avatar
Paul Wilkins committed
424
425
  // 0,0 is always a valid reference. Add it if not already seen.
  if (!zero_seen) {
Paul Wilkins's avatar
Paul Wilkins committed
426
    candidate_mvs[MAX_MV_REF_CANDIDATES-1].as_int = 0;
Paul Wilkins's avatar
Paul Wilkins committed
427
428
429
430
431
  }

  // Copy over the candidate list.
  vpx_memcpy(mv_ref_list, candidate_mvs, sizeof(candidate_mvs));
}