]> granicus.if.org Git - libvpx/blob - vp10/encoder/temporal_filter.c
VP9_COMP -> VP10_COMP
[libvpx] / vp10 / encoder / temporal_filter.c
1 /*
2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  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.
9  */
10
11 #include <math.h>
12 #include <limits.h>
13
14 #include "vp10/common/alloccommon.h"
15 #include "vp10/common/onyxc_int.h"
16 #include "vp10/common/quant_common.h"
17 #include "vp10/common/reconinter.h"
18 #include "vp10/encoder/extend.h"
19 #include "vp10/encoder/firstpass.h"
20 #include "vp10/encoder/mcomp.h"
21 #include "vp10/encoder/encoder.h"
22 #include "vp10/encoder/quantize.h"
23 #include "vp10/encoder/ratectrl.h"
24 #include "vp10/encoder/segmentation.h"
25 #include "vp10/encoder/temporal_filter.h"
26 #include "vpx_mem/vpx_mem.h"
27 #include "vpx_ports/mem.h"
28 #include "vpx_ports/vpx_timer.h"
29 #include "vpx_scale/vpx_scale.h"
30
31 static int fixed_divide[512];
32
33 static void temporal_filter_predictors_mb_c(MACROBLOCKD *xd,
34                                             uint8_t *y_mb_ptr,
35                                             uint8_t *u_mb_ptr,
36                                             uint8_t *v_mb_ptr,
37                                             int stride,
38                                             int uv_block_width,
39                                             int uv_block_height,
40                                             int mv_row,
41                                             int mv_col,
42                                             uint8_t *pred,
43                                             struct scale_factors *scale,
44                                             int x, int y) {
45   const int which_mv = 0;
46   const MV mv = { mv_row, mv_col };
47   const InterpKernel *const kernel =
48     vp10_filter_kernels[xd->mi[0]->mbmi.interp_filter];
49
50   enum mv_precision mv_precision_uv;
51   int uv_stride;
52   if (uv_block_width == 8) {
53     uv_stride = (stride + 1) >> 1;
54     mv_precision_uv = MV_PRECISION_Q4;
55   } else {
56     uv_stride = stride;
57     mv_precision_uv = MV_PRECISION_Q3;
58   }
59
60 #if CONFIG_VP9_HIGHBITDEPTH
61   if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
62     vp10_highbd_build_inter_predictor(y_mb_ptr, stride,
63                                      &pred[0], 16,
64                                      &mv,
65                                      scale,
66                                      16, 16,
67                                      which_mv,
68                                      kernel, MV_PRECISION_Q3, x, y, xd->bd);
69
70     vp10_highbd_build_inter_predictor(u_mb_ptr, uv_stride,
71                                      &pred[256], uv_block_width,
72                                      &mv,
73                                      scale,
74                                      uv_block_width, uv_block_height,
75                                      which_mv,
76                                      kernel, mv_precision_uv, x, y, xd->bd);
77
78     vp10_highbd_build_inter_predictor(v_mb_ptr, uv_stride,
79                                      &pred[512], uv_block_width,
80                                      &mv,
81                                      scale,
82                                      uv_block_width, uv_block_height,
83                                      which_mv,
84                                      kernel, mv_precision_uv, x, y, xd->bd);
85     return;
86   }
87 #endif  // CONFIG_VP9_HIGHBITDEPTH
88   vp10_build_inter_predictor(y_mb_ptr, stride,
89                             &pred[0], 16,
90                             &mv,
91                             scale,
92                             16, 16,
93                             which_mv,
94                             kernel, MV_PRECISION_Q3, x, y);
95
96   vp10_build_inter_predictor(u_mb_ptr, uv_stride,
97                             &pred[256], uv_block_width,
98                             &mv,
99                             scale,
100                             uv_block_width, uv_block_height,
101                             which_mv,
102                             kernel, mv_precision_uv, x, y);
103
104   vp10_build_inter_predictor(v_mb_ptr, uv_stride,
105                             &pred[512], uv_block_width,
106                             &mv,
107                             scale,
108                             uv_block_width, uv_block_height,
109                             which_mv,
110                             kernel, mv_precision_uv, x, y);
111 }
112
113 void vp10_temporal_filter_init(void) {
114   int i;
115
116   fixed_divide[0] = 0;
117   for (i = 1; i < 512; ++i)
118     fixed_divide[i] = 0x80000 / i;
119 }
120
121 void vp10_temporal_filter_apply_c(uint8_t *frame1,
122                                  unsigned int stride,
123                                  uint8_t *frame2,
124                                  unsigned int block_width,
125                                  unsigned int block_height,
126                                  int strength,
127                                  int filter_weight,
128                                  unsigned int *accumulator,
129                                  uint16_t *count) {
130   unsigned int i, j, k;
131   int modifier;
132   int byte = 0;
133   const int rounding = strength > 0 ? 1 << (strength - 1) : 0;
134
135   for (i = 0, k = 0; i < block_height; i++) {
136     for (j = 0; j < block_width; j++, k++) {
137       int src_byte = frame1[byte];
138       int pixel_value = *frame2++;
139
140       modifier   = src_byte - pixel_value;
141       // This is an integer approximation of:
142       // float coeff = (3.0 * modifer * modifier) / pow(2, strength);
143       // modifier =  (int)roundf(coeff > 16 ? 0 : 16-coeff);
144       modifier  *= modifier;
145       modifier  *= 3;
146       modifier  += rounding;
147       modifier >>= strength;
148
149       if (modifier > 16)
150         modifier = 16;
151
152       modifier = 16 - modifier;
153       modifier *= filter_weight;
154
155       count[k] += modifier;
156       accumulator[k] += modifier * pixel_value;
157
158       byte++;
159     }
160
161     byte += stride - block_width;
162   }
163 }
164
165 #if CONFIG_VP9_HIGHBITDEPTH
166 void vp10_highbd_temporal_filter_apply_c(uint8_t *frame1_8,
167                                         unsigned int stride,
168                                         uint8_t *frame2_8,
169                                         unsigned int block_width,
170                                         unsigned int block_height,
171                                         int strength,
172                                         int filter_weight,
173                                         unsigned int *accumulator,
174                                         uint16_t *count) {
175   uint16_t *frame1 = CONVERT_TO_SHORTPTR(frame1_8);
176   uint16_t *frame2 = CONVERT_TO_SHORTPTR(frame2_8);
177   unsigned int i, j, k;
178   int modifier;
179   int byte = 0;
180   const int rounding = strength > 0 ? 1 << (strength - 1) : 0;
181
182   for (i = 0, k = 0; i < block_height; i++) {
183     for (j = 0; j < block_width; j++, k++) {
184       int src_byte = frame1[byte];
185       int pixel_value = *frame2++;
186
187       modifier   = src_byte - pixel_value;
188       // This is an integer approximation of:
189       // float coeff = (3.0 * modifer * modifier) / pow(2, strength);
190       // modifier =  (int)roundf(coeff > 16 ? 0 : 16-coeff);
191       modifier *= modifier;
192       modifier *= 3;
193       modifier += rounding;
194       modifier >>= strength;
195
196       if (modifier > 16)
197         modifier = 16;
198
199       modifier = 16 - modifier;
200       modifier *= filter_weight;
201
202       count[k] += modifier;
203       accumulator[k] += modifier * pixel_value;
204
205       byte++;
206     }
207
208     byte += stride - block_width;
209   }
210 }
211 #endif  // CONFIG_VP9_HIGHBITDEPTH
212
213 static int temporal_filter_find_matching_mb_c(VP10_COMP *cpi,
214                                               uint8_t *arf_frame_buf,
215                                               uint8_t *frame_ptr_buf,
216                                               int stride) {
217   MACROBLOCK *const x = &cpi->td.mb;
218   MACROBLOCKD *const xd = &x->e_mbd;
219   const MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv;
220   int step_param;
221   int sadpb = x->sadperbit16;
222   int bestsme = INT_MAX;
223   int distortion;
224   unsigned int sse;
225   int cost_list[5];
226
227   MV best_ref_mv1 = {0, 0};
228   MV best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */
229   MV *ref_mv = &x->e_mbd.mi[0]->bmi[0].as_mv[0].as_mv;
230
231   // Save input state
232   struct buf_2d src = x->plane[0].src;
233   struct buf_2d pre = xd->plane[0].pre[0];
234
235   best_ref_mv1_full.col = best_ref_mv1.col >> 3;
236   best_ref_mv1_full.row = best_ref_mv1.row >> 3;
237
238   // Setup frame pointers
239   x->plane[0].src.buf = arf_frame_buf;
240   x->plane[0].src.stride = stride;
241   xd->plane[0].pre[0].buf = frame_ptr_buf;
242   xd->plane[0].pre[0].stride = stride;
243
244   step_param = mv_sf->reduce_first_step_size;
245   step_param = MIN(step_param, MAX_MVSEARCH_STEPS - 2);
246
247   // Ignore mv costing by sending NULL pointer instead of cost arrays
248   vp10_hex_search(x, &best_ref_mv1_full, step_param, sadpb, 1,
249                  cond_cost_list(cpi, cost_list),
250                  &cpi->fn_ptr[BLOCK_16X16], 0, &best_ref_mv1, ref_mv);
251
252   // Ignore mv costing by sending NULL pointer instead of cost array
253   bestsme = cpi->find_fractional_mv_step(x, ref_mv,
254                                          &best_ref_mv1,
255                                          cpi->common.allow_high_precision_mv,
256                                          x->errorperbit,
257                                          &cpi->fn_ptr[BLOCK_16X16],
258                                          0, mv_sf->subpel_iters_per_step,
259                                          cond_cost_list(cpi, cost_list),
260                                          NULL, NULL,
261                                          &distortion, &sse, NULL, 0, 0);
262
263   // Restore input state
264   x->plane[0].src = src;
265   xd->plane[0].pre[0] = pre;
266
267   return bestsme;
268 }
269
270 static void temporal_filter_iterate_c(VP10_COMP *cpi,
271                                       YV12_BUFFER_CONFIG **frames,
272                                       int frame_count,
273                                       int alt_ref_index,
274                                       int strength,
275                                       struct scale_factors *scale) {
276   int byte;
277   int frame;
278   int mb_col, mb_row;
279   unsigned int filter_weight;
280   int mb_cols = (frames[alt_ref_index]->y_crop_width + 15) >> 4;
281   int mb_rows = (frames[alt_ref_index]->y_crop_height + 15) >> 4;
282   int mb_y_offset = 0;
283   int mb_uv_offset = 0;
284   DECLARE_ALIGNED(16, unsigned int, accumulator[16 * 16 * 3]);
285   DECLARE_ALIGNED(16, uint16_t, count[16 * 16 * 3]);
286   MACROBLOCKD *mbd = &cpi->td.mb.e_mbd;
287   YV12_BUFFER_CONFIG *f = frames[alt_ref_index];
288   uint8_t *dst1, *dst2;
289 #if CONFIG_VP9_HIGHBITDEPTH
290   DECLARE_ALIGNED(16, uint16_t,  predictor16[16 * 16 * 3]);
291   DECLARE_ALIGNED(16, uint8_t,  predictor8[16 * 16 * 3]);
292   uint8_t *predictor;
293 #else
294   DECLARE_ALIGNED(16, uint8_t,  predictor[16 * 16 * 3]);
295 #endif
296   const int mb_uv_height = 16 >> mbd->plane[1].subsampling_y;
297   const int mb_uv_width  = 16 >> mbd->plane[1].subsampling_x;
298
299   // Save input state
300   uint8_t* input_buffer[MAX_MB_PLANE];
301   int i;
302 #if CONFIG_VP9_HIGHBITDEPTH
303   if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
304     predictor = CONVERT_TO_BYTEPTR(predictor16);
305   } else {
306     predictor = predictor8;
307   }
308 #endif
309
310   for (i = 0; i < MAX_MB_PLANE; i++)
311     input_buffer[i] = mbd->plane[i].pre[0].buf;
312
313   for (mb_row = 0; mb_row < mb_rows; mb_row++) {
314     // Source frames are extended to 16 pixels. This is different than
315     //  L/A/G reference frames that have a border of 32 (VP9ENCBORDERINPIXELS)
316     // A 6/8 tap filter is used for motion search.  This requires 2 pixels
317     //  before and 3 pixels after.  So the largest Y mv on a border would
318     //  then be 16 - VP9_INTERP_EXTEND. The UV blocks are half the size of the
319     //  Y and therefore only extended by 8.  The largest mv that a UV block
320     //  can support is 8 - VP9_INTERP_EXTEND.  A UV mv is half of a Y mv.
321     //  (16 - VP9_INTERP_EXTEND) >> 1 which is greater than
322     //  8 - VP9_INTERP_EXTEND.
323     // To keep the mv in play for both Y and UV planes the max that it
324     //  can be on a border is therefore 16 - (2*VP9_INTERP_EXTEND+1).
325     cpi->td.mb.mv_row_min = -((mb_row * 16) + (17 - 2 * VP9_INTERP_EXTEND));
326     cpi->td.mb.mv_row_max = ((mb_rows - 1 - mb_row) * 16)
327                          + (17 - 2 * VP9_INTERP_EXTEND);
328
329     for (mb_col = 0; mb_col < mb_cols; mb_col++) {
330       int i, j, k;
331       int stride;
332
333       memset(accumulator, 0, 16 * 16 * 3 * sizeof(accumulator[0]));
334       memset(count, 0, 16 * 16 * 3 * sizeof(count[0]));
335
336       cpi->td.mb.mv_col_min = -((mb_col * 16) + (17 - 2 * VP9_INTERP_EXTEND));
337       cpi->td.mb.mv_col_max = ((mb_cols - 1 - mb_col) * 16)
338                            + (17 - 2 * VP9_INTERP_EXTEND);
339
340       for (frame = 0; frame < frame_count; frame++) {
341         const int thresh_low  = 10000;
342         const int thresh_high = 20000;
343
344         if (frames[frame] == NULL)
345           continue;
346
347         mbd->mi[0]->bmi[0].as_mv[0].as_mv.row = 0;
348         mbd->mi[0]->bmi[0].as_mv[0].as_mv.col = 0;
349
350         if (frame == alt_ref_index) {
351           filter_weight = 2;
352         } else {
353           // Find best match in this frame by MC
354           int err = temporal_filter_find_matching_mb_c(cpi,
355               frames[alt_ref_index]->y_buffer + mb_y_offset,
356               frames[frame]->y_buffer + mb_y_offset,
357               frames[frame]->y_stride);
358
359           // Assign higher weight to matching MB if it's error
360           // score is lower. If not applying MC default behavior
361           // is to weight all MBs equal.
362           filter_weight = err < thresh_low
363                           ? 2 : err < thresh_high ? 1 : 0;
364         }
365
366         if (filter_weight != 0) {
367           // Construct the predictors
368           temporal_filter_predictors_mb_c(mbd,
369               frames[frame]->y_buffer + mb_y_offset,
370               frames[frame]->u_buffer + mb_uv_offset,
371               frames[frame]->v_buffer + mb_uv_offset,
372               frames[frame]->y_stride,
373               mb_uv_width, mb_uv_height,
374               mbd->mi[0]->bmi[0].as_mv[0].as_mv.row,
375               mbd->mi[0]->bmi[0].as_mv[0].as_mv.col,
376               predictor, scale,
377               mb_col * 16, mb_row * 16);
378
379 #if CONFIG_VP9_HIGHBITDEPTH
380           if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
381             int adj_strength = strength + 2 * (mbd->bd - 8);
382             // Apply the filter (YUV)
383             vp10_highbd_temporal_filter_apply(f->y_buffer + mb_y_offset,
384                                              f->y_stride,
385                                              predictor, 16, 16, adj_strength,
386                                              filter_weight,
387                                              accumulator, count);
388             vp10_highbd_temporal_filter_apply(f->u_buffer + mb_uv_offset,
389                                              f->uv_stride, predictor + 256,
390                                              mb_uv_width, mb_uv_height,
391                                              adj_strength,
392                                              filter_weight, accumulator + 256,
393                                              count + 256);
394             vp10_highbd_temporal_filter_apply(f->v_buffer + mb_uv_offset,
395                                              f->uv_stride, predictor + 512,
396                                              mb_uv_width, mb_uv_height,
397                                              adj_strength, filter_weight,
398                                              accumulator + 512, count + 512);
399           } else {
400             // Apply the filter (YUV)
401             vp10_temporal_filter_apply(f->y_buffer + mb_y_offset, f->y_stride,
402                                       predictor, 16, 16,
403                                       strength, filter_weight,
404                                       accumulator, count);
405             vp10_temporal_filter_apply(f->u_buffer + mb_uv_offset, f->uv_stride,
406                                       predictor + 256,
407                                       mb_uv_width, mb_uv_height, strength,
408                                       filter_weight, accumulator + 256,
409                                       count + 256);
410             vp10_temporal_filter_apply(f->v_buffer + mb_uv_offset, f->uv_stride,
411                                       predictor + 512,
412                                       mb_uv_width, mb_uv_height, strength,
413                                       filter_weight, accumulator + 512,
414                                       count + 512);
415           }
416 #else
417           // Apply the filter (YUV)
418           vp10_temporal_filter_apply(f->y_buffer + mb_y_offset, f->y_stride,
419                                     predictor, 16, 16,
420                                     strength, filter_weight,
421                                     accumulator, count);
422           vp10_temporal_filter_apply(f->u_buffer + mb_uv_offset, f->uv_stride,
423                                     predictor + 256,
424                                     mb_uv_width, mb_uv_height, strength,
425                                     filter_weight, accumulator + 256,
426                                     count + 256);
427           vp10_temporal_filter_apply(f->v_buffer + mb_uv_offset, f->uv_stride,
428                                     predictor + 512,
429                                     mb_uv_width, mb_uv_height, strength,
430                                     filter_weight, accumulator + 512,
431                                     count + 512);
432 #endif  // CONFIG_VP9_HIGHBITDEPTH
433         }
434       }
435
436 #if CONFIG_VP9_HIGHBITDEPTH
437       if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
438         uint16_t *dst1_16;
439         uint16_t *dst2_16;
440         // Normalize filter output to produce AltRef frame
441         dst1 = cpi->alt_ref_buffer.y_buffer;
442         dst1_16 = CONVERT_TO_SHORTPTR(dst1);
443         stride = cpi->alt_ref_buffer.y_stride;
444         byte = mb_y_offset;
445         for (i = 0, k = 0; i < 16; i++) {
446           for (j = 0; j < 16; j++, k++) {
447             unsigned int pval = accumulator[k] + (count[k] >> 1);
448             pval *= fixed_divide[count[k]];
449             pval >>= 19;
450
451             dst1_16[byte] = (uint16_t)pval;
452
453             // move to next pixel
454             byte++;
455           }
456
457           byte += stride - 16;
458         }
459
460         dst1 = cpi->alt_ref_buffer.u_buffer;
461         dst2 = cpi->alt_ref_buffer.v_buffer;
462         dst1_16 = CONVERT_TO_SHORTPTR(dst1);
463         dst2_16 = CONVERT_TO_SHORTPTR(dst2);
464         stride = cpi->alt_ref_buffer.uv_stride;
465         byte = mb_uv_offset;
466         for (i = 0, k = 256; i < mb_uv_height; i++) {
467           for (j = 0; j < mb_uv_width; j++, k++) {
468             int m = k + 256;
469
470             // U
471             unsigned int pval = accumulator[k] + (count[k] >> 1);
472             pval *= fixed_divide[count[k]];
473             pval >>= 19;
474             dst1_16[byte] = (uint16_t)pval;
475
476             // V
477             pval = accumulator[m] + (count[m] >> 1);
478             pval *= fixed_divide[count[m]];
479             pval >>= 19;
480             dst2_16[byte] = (uint16_t)pval;
481
482             // move to next pixel
483             byte++;
484           }
485
486           byte += stride - mb_uv_width;
487         }
488       } else {
489         // Normalize filter output to produce AltRef frame
490         dst1 = cpi->alt_ref_buffer.y_buffer;
491         stride = cpi->alt_ref_buffer.y_stride;
492         byte = mb_y_offset;
493         for (i = 0, k = 0; i < 16; i++) {
494           for (j = 0; j < 16; j++, k++) {
495             unsigned int pval = accumulator[k] + (count[k] >> 1);
496             pval *= fixed_divide[count[k]];
497             pval >>= 19;
498
499             dst1[byte] = (uint8_t)pval;
500
501             // move to next pixel
502             byte++;
503           }
504           byte += stride - 16;
505         }
506
507         dst1 = cpi->alt_ref_buffer.u_buffer;
508         dst2 = cpi->alt_ref_buffer.v_buffer;
509         stride = cpi->alt_ref_buffer.uv_stride;
510         byte = mb_uv_offset;
511         for (i = 0, k = 256; i < mb_uv_height; i++) {
512           for (j = 0; j < mb_uv_width; j++, k++) {
513             int m = k + 256;
514
515             // U
516             unsigned int pval = accumulator[k] + (count[k] >> 1);
517             pval *= fixed_divide[count[k]];
518             pval >>= 19;
519             dst1[byte] = (uint8_t)pval;
520
521             // V
522             pval = accumulator[m] + (count[m] >> 1);
523             pval *= fixed_divide[count[m]];
524             pval >>= 19;
525             dst2[byte] = (uint8_t)pval;
526
527             // move to next pixel
528             byte++;
529           }
530           byte += stride - mb_uv_width;
531         }
532       }
533 #else
534       // Normalize filter output to produce AltRef frame
535       dst1 = cpi->alt_ref_buffer.y_buffer;
536       stride = cpi->alt_ref_buffer.y_stride;
537       byte = mb_y_offset;
538       for (i = 0, k = 0; i < 16; i++) {
539         for (j = 0; j < 16; j++, k++) {
540           unsigned int pval = accumulator[k] + (count[k] >> 1);
541           pval *= fixed_divide[count[k]];
542           pval >>= 19;
543
544           dst1[byte] = (uint8_t)pval;
545
546           // move to next pixel
547           byte++;
548         }
549         byte += stride - 16;
550       }
551
552       dst1 = cpi->alt_ref_buffer.u_buffer;
553       dst2 = cpi->alt_ref_buffer.v_buffer;
554       stride = cpi->alt_ref_buffer.uv_stride;
555       byte = mb_uv_offset;
556       for (i = 0, k = 256; i < mb_uv_height; i++) {
557         for (j = 0; j < mb_uv_width; j++, k++) {
558           int m = k + 256;
559
560           // U
561           unsigned int pval = accumulator[k] + (count[k] >> 1);
562           pval *= fixed_divide[count[k]];
563           pval >>= 19;
564           dst1[byte] = (uint8_t)pval;
565
566           // V
567           pval = accumulator[m] + (count[m] >> 1);
568           pval *= fixed_divide[count[m]];
569           pval >>= 19;
570           dst2[byte] = (uint8_t)pval;
571
572           // move to next pixel
573           byte++;
574         }
575         byte += stride - mb_uv_width;
576       }
577 #endif  // CONFIG_VP9_HIGHBITDEPTH
578       mb_y_offset += 16;
579       mb_uv_offset += mb_uv_width;
580     }
581     mb_y_offset += 16 * (f->y_stride - mb_cols);
582     mb_uv_offset += mb_uv_height * f->uv_stride - mb_uv_width * mb_cols;
583   }
584
585   // Restore input state
586   for (i = 0; i < MAX_MB_PLANE; i++)
587     mbd->plane[i].pre[0].buf = input_buffer[i];
588 }
589
590 // Apply buffer limits and context specific adjustments to arnr filter.
591 static void adjust_arnr_filter(VP10_COMP *cpi,
592                                int distance, int group_boost,
593                                int *arnr_frames, int *arnr_strength) {
594   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
595   const int frames_after_arf =
596       vp10_lookahead_depth(cpi->lookahead) - distance - 1;
597   int frames_fwd = (cpi->oxcf.arnr_max_frames - 1) >> 1;
598   int frames_bwd;
599   int q, frames, strength;
600
601   // Define the forward and backwards filter limits for this arnr group.
602   if (frames_fwd > frames_after_arf)
603     frames_fwd = frames_after_arf;
604   if (frames_fwd > distance)
605     frames_fwd = distance;
606
607   frames_bwd = frames_fwd;
608
609   // For even length filter there is one more frame backward
610   // than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff.
611   if (frames_bwd < distance)
612     frames_bwd += (oxcf->arnr_max_frames + 1) & 0x1;
613
614   // Set the baseline active filter size.
615   frames = frames_bwd + 1 + frames_fwd;
616
617   // Adjust the strength based on active max q.
618   if (cpi->common.current_video_frame > 1)
619     q = ((int)vp10_convert_qindex_to_q(
620         cpi->rc.avg_frame_qindex[INTER_FRAME], cpi->common.bit_depth));
621   else
622     q = ((int)vp10_convert_qindex_to_q(
623         cpi->rc.avg_frame_qindex[KEY_FRAME], cpi->common.bit_depth));
624   if (q > 16) {
625     strength = oxcf->arnr_strength;
626   } else {
627     strength = oxcf->arnr_strength - ((16 - q) / 2);
628     if (strength < 0)
629       strength = 0;
630   }
631
632   // Adjust number of frames in filter and strength based on gf boost level.
633   if (frames > group_boost / 150) {
634     frames = group_boost / 150;
635     frames += !(frames & 1);
636   }
637
638   if (strength > group_boost / 300) {
639     strength = group_boost / 300;
640   }
641
642   // Adjustments for second level arf in multi arf case.
643   if (cpi->oxcf.pass == 2 && cpi->multi_arf_allowed) {
644     const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
645     if (gf_group->rf_level[gf_group->index] != GF_ARF_STD) {
646       strength >>= 1;
647     }
648   }
649
650   *arnr_frames = frames;
651   *arnr_strength = strength;
652 }
653
654 void vp10_temporal_filter(VP10_COMP *cpi, int distance) {
655   VP10_COMMON *const cm = &cpi->common;
656   RATE_CONTROL *const rc = &cpi->rc;
657   MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
658   int frame;
659   int frames_to_blur;
660   int start_frame;
661   int strength;
662   int frames_to_blur_backward;
663   int frames_to_blur_forward;
664   struct scale_factors sf;
665   YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS] = {NULL};
666
667   // Apply context specific adjustments to the arnr filter parameters.
668   adjust_arnr_filter(cpi, distance, rc->gfu_boost, &frames_to_blur, &strength);
669   frames_to_blur_backward = (frames_to_blur / 2);
670   frames_to_blur_forward = ((frames_to_blur - 1) / 2);
671   start_frame = distance + frames_to_blur_forward;
672
673   // Setup frame pointers, NULL indicates frame not included in filter.
674   for (frame = 0; frame < frames_to_blur; ++frame) {
675     const int which_buffer = start_frame - frame;
676     struct lookahead_entry *buf = vp10_lookahead_peek(cpi->lookahead,
677                                                      which_buffer);
678     frames[frames_to_blur - 1 - frame] = &buf->img;
679   }
680
681   if (frames_to_blur > 0) {
682     // Setup scaling factors. Scaling on each of the arnr frames is not
683     // supported.
684     if (cpi->use_svc) {
685       // In spatial svc the scaling factors might be less then 1/2.
686       // So we will use non-normative scaling.
687       int frame_used = 0;
688 #if CONFIG_VP9_HIGHBITDEPTH
689       vp10_setup_scale_factors_for_frame(
690           &sf,
691           get_frame_new_buffer(cm)->y_crop_width,
692           get_frame_new_buffer(cm)->y_crop_height,
693           get_frame_new_buffer(cm)->y_crop_width,
694           get_frame_new_buffer(cm)->y_crop_height,
695           cm->use_highbitdepth);
696 #else
697       vp10_setup_scale_factors_for_frame(
698           &sf,
699           get_frame_new_buffer(cm)->y_crop_width,
700           get_frame_new_buffer(cm)->y_crop_height,
701           get_frame_new_buffer(cm)->y_crop_width,
702           get_frame_new_buffer(cm)->y_crop_height);
703 #endif  // CONFIG_VP9_HIGHBITDEPTH
704
705       for (frame = 0; frame < frames_to_blur; ++frame) {
706         if (cm->mi_cols * MI_SIZE != frames[frame]->y_width ||
707             cm->mi_rows * MI_SIZE != frames[frame]->y_height) {
708           if (vp9_realloc_frame_buffer(&cpi->svc.scaled_frames[frame_used],
709                                        cm->width, cm->height,
710                                        cm->subsampling_x, cm->subsampling_y,
711 #if CONFIG_VP9_HIGHBITDEPTH
712                                        cm->use_highbitdepth,
713 #endif
714                                        VP9_ENC_BORDER_IN_PIXELS,
715                                        cm->byte_alignment,
716                                        NULL, NULL, NULL)) {
717             vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
718                                "Failed to reallocate alt_ref_buffer");
719           }
720           frames[frame] = vp10_scale_if_required(
721               cm, frames[frame], &cpi->svc.scaled_frames[frame_used]);
722           ++frame_used;
723         }
724       }
725       cm->mi = cm->mip + cm->mi_stride + 1;
726       xd->mi = cm->mi_grid_visible;
727       xd->mi[0] = cm->mi;
728     } else {
729       // ARF is produced at the native frame size and resized when coded.
730 #if CONFIG_VP9_HIGHBITDEPTH
731       vp10_setup_scale_factors_for_frame(&sf,
732                                         frames[0]->y_crop_width,
733                                         frames[0]->y_crop_height,
734                                         frames[0]->y_crop_width,
735                                         frames[0]->y_crop_height,
736                                         cm->use_highbitdepth);
737 #else
738       vp10_setup_scale_factors_for_frame(&sf,
739                                         frames[0]->y_crop_width,
740                                         frames[0]->y_crop_height,
741                                         frames[0]->y_crop_width,
742                                         frames[0]->y_crop_height);
743 #endif  // CONFIG_VP9_HIGHBITDEPTH
744     }
745   }
746
747   temporal_filter_iterate_c(cpi, frames, frames_to_blur,
748                             frames_to_blur_backward, strength, &sf);
749 }