]> granicus.if.org Git - libvpx/commitdiff
Refactor to separate restoration from loop filter
authorDebargha Mukherjee <debargha@google.com>
Fri, 29 Jan 2016 23:30:19 +0000 (15:30 -0800)
committerDebargha Mukherjee <debargha@google.com>
Fri, 29 Jan 2016 23:39:23 +0000 (15:39 -0800)
Change-Id: Iab517862d957f3aa2a664e9349d57bbf424febb3

vp10/common/loopfilter.c
vp10/common/loopfilter.h
vp10/common/onyxc_int.h
vp10/common/restoration.c [new file with mode: 0644]
vp10/common/restoration.h [new file with mode: 0644]
vp10/decoder/decodeframe.c
vp10/decoder/decoder.c
vp10/encoder/encoder.c
vp10/vp10_common.mk

index d4381f825aa14050b6675fd98ee4c386c0e2ad64..125b5bf0f8448b8fcfae23fca645626ac824383b 100644 (file)
@@ -15,6 +15,7 @@
 #include "vp10/common/loopfilter.h"
 #include "vp10/common/onyxc_int.h"
 #include "vp10/common/reconinter.h"
+#include "vp10/common/restoration.h"
 #include "vpx_dsp/vpx_dsp_common.h"
 #include "vpx_mem/vpx_mem.h"
 #include "vpx_ports/mem.h"
@@ -215,318 +216,6 @@ static const int mode_lf_lut[MB_MODE_COUNT] = {
 #endif  // CONFIG_EXT_INTER
 };
 
-#if CONFIG_LOOP_RESTORATION
-#define RESTORATION_RANGE  256
-#define RESTORATION_RANGE_SYM  (2 * RESTORATION_RANGE + 1)
-static double restoration_filters_r_kf[RESTORATION_LEVELS_KF + 1]
-                                    [RESTORATION_RANGE_SYM];
-static double restoration_filters_r[RESTORATION_LEVELS + 1]
-                                   [RESTORATION_RANGE_SYM];
-static double restoration_filters_s_kf[RESTORATION_LEVELS_KF + 1]
-                                      [RESTORATION_WIN][RESTORATION_WIN];
-static double restoration_filters_s[RESTORATION_LEVELS + 1]
-                                   [RESTORATION_WIN][RESTORATION_WIN];
-
-void vp10_loop_restoration_precal() {
-  int i;
-  for (i = 1; i < RESTORATION_LEVELS_KF + 1; i ++) {
-    const restoration_params_t param = vp10_restoration_level_to_params(i, 1);
-    const int sigma_x = param.sigma_x;
-    const int sigma_y = param.sigma_y;
-    const int sigma_r = param.sigma_r;
-    const double sigma_r_d = (double)sigma_r / RESTORATION_PRECISION;
-    const double sigma_x_d = (double)sigma_x / RESTORATION_PRECISION;
-    const double sigma_y_d = (double)sigma_y / RESTORATION_PRECISION;
-
-    double *fr = restoration_filters_r_kf[i] + RESTORATION_RANGE;
-    int j, x, y;
-    for (j = 0; j <= RESTORATION_RANGE; j++) {
-      fr[j] = exp(-(j * j) / (2 * sigma_r_d * sigma_r_d));
-      fr[-j] = fr[j];
-    }
-    for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; y++) {
-      for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; x++) {
-        restoration_filters_s_kf[i][y + RESTORATION_HALFWIN]
-                                 [x + RESTORATION_HALFWIN] =
-          exp(-(x * x) / (2 * sigma_x_d * sigma_x_d)
-              -(y * y) / (2 * sigma_y_d * sigma_y_d));
-      }
-    }
-  }
-  for (i = 1; i < RESTORATION_LEVELS + 1; i ++) {
-    const restoration_params_t param = vp10_restoration_level_to_params(i, 0);
-    const int sigma_x = param.sigma_x;
-    const int sigma_y = param.sigma_y;
-    const int sigma_r = param.sigma_r;
-    const double sigma_r_d = (double)sigma_r / RESTORATION_PRECISION;
-    const double sigma_x_d = (double)sigma_x / RESTORATION_PRECISION;
-    const double sigma_y_d = (double)sigma_y / RESTORATION_PRECISION;
-
-    double *fr = restoration_filters_r[i] + RESTORATION_RANGE;
-    int j, x, y;
-    for (j = 0; j <= RESTORATION_RANGE; j++) {
-      fr[j] = exp(-(j * j) / (2 * sigma_r_d * sigma_r_d));
-      fr[-j] = fr[j];
-    }
-    for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; y++) {
-      for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; x++) {
-        restoration_filters_s
-            [i][y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN] =
-            exp(-(x * x) / (2 * sigma_x_d * sigma_x_d)
-                -(y * y) / (2 * sigma_y_d * sigma_y_d));
-      }
-    }
-  }
-}
-
-int vp10_restoration_level_bits(const VP10_COMMON *const cm) {
-  return cm->frame_type == KEY_FRAME ?
-      RESTORATION_LEVEL_BITS_KF : RESTORATION_LEVEL_BITS;
-}
-
-int vp10_loop_restoration_used(int level, int kf) {
-  const restoration_params_t param =
-      vp10_restoration_level_to_params(level, kf);
-  return (param.sigma_x && param.sigma_y && param.sigma_r);
-}
-
-void vp10_loop_restoration_init(loop_filter_info_n *lfi, int level, int kf) {
-  lfi->restoration_used = vp10_loop_restoration_used(level, kf);
-
-  if (lfi->restoration_used) {
-    int i;
-    lfi->wr_lut = kf ? restoration_filters_r_kf[level] :
-                       restoration_filters_r[level];
-    for (i = 0; i < RESTORATION_WIN; i++)
-      lfi->wx_lut[i] = kf ? restoration_filters_s_kf[level][i] :
-                            restoration_filters_s[level][i];
-  }
-}
-
-static int is_in_image(int x, int y, int width, int height) {
-  return (x >= 0 && x < width && y >= 0 && y < height);
-}
-
-void loop_restoration_filter(uint8_t *data, int width, int height,
-                             int stride, loop_filter_info_n *lfi,
-                             uint8_t *tmpdata, int tmpstride) {
-  int i, j;
-  const double *wr_lut_ = lfi->wr_lut + RESTORATION_RANGE;
-
-  uint8_t *data_p = data;
-  uint8_t *tmpdata_p = tmpdata;
-  for (i = 0; i < height; ++i) {
-    for (j = 0; j < width; ++j) {
-      int x, y;
-      double flsum = 0, wtsum = 0, wt;
-      uint8_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
-      for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
-        for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
-          if (!is_in_image(j + x, i + y, width, height))
-            continue;
-          wt = lfi->wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN] *
-               wr_lut_[data_p2[x] - data_p[j]];
-          wtsum += wt;
-          flsum += wt * data_p2[x];
-        }
-        data_p2 += stride;
-      }
-      assert(wtsum > 0);
-      tmpdata_p[j] = clip_pixel((int)(flsum / wtsum + 0.5));
-    }
-    tmpdata_p += tmpstride;
-    data_p += stride;
-  }
-
-  for (i = 0; i < height; ++i) {
-    memcpy(data + i * stride, tmpdata + i * tmpstride,
-           width * sizeof(*data));
-  }
-}
-
-// Normalized non-separable filter where weights all sum to 1
-void loop_restoration_filter_norm(uint8_t *data, int width, int height,
-                                  int stride, loop_filter_info_n *lfi,
-                                  uint8_t *tmpdata, int tmpstride) {
-  int i, j;
-  uint8_t *data_p = data;
-  uint8_t *tmpdata_p = tmpdata;
-  for (i = RESTORATION_HALFWIN; i < height - RESTORATION_HALFWIN; ++i) {
-    for (j = RESTORATION_HALFWIN; j < width - RESTORATION_HALFWIN; ++j) {
-      int x, y;
-      double flsum = 0;
-      uint8_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
-      for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
-        for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
-          flsum += data_p2[x] *
-              lfi->wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN];
-        }
-        data_p2 += stride;
-      }
-      tmpdata_p[j] = clip_pixel((int)(flsum + 0.5));
-    }
-    tmpdata_p += tmpstride;
-    data_p += stride;
-  }
-  for (i = 0; i < height; ++i) {
-    memcpy(data + i * stride, tmpdata + i * tmpstride,
-           width * sizeof(*data));
-  }
-}
-
-#if CONFIG_VP9_HIGHBITDEPTH
-void loop_restoration_filter_highbd(uint8_t *data8, int width, int height,
-                                    int stride, loop_filter_info_n *lfi,
-                                    uint8_t *tmpdata8, int tmpstride,
-                                    int bit_depth) {
-  int i, j;
-  const double *wr_lut_ = lfi->wr_lut + RESTORATION_RANGE;
-
-  uint16_t *data = CONVERT_TO_SHORTPTR(data8);
-  uint16_t *tmpdata = CONVERT_TO_SHORTPTR(tmpdata8);
-  uint16_t *data_p = data;
-  uint16_t *tmpdata_p = tmpdata;
-  for (i = 0; i < height; ++i) {
-    for (j = 0; j < width; ++j) {
-      int x, y, diff_r;
-      double flsum = 0, wtsum = 0, wt;
-      uint16_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
-
-      for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
-        for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
-          if (!is_in_image(j + x, i + y, width, height))
-            continue;
-
-          diff_r = (data_p2[x] - data_p[j]) >> (bit_depth - 8);
-          assert(diff_r >= -RESTORATION_RANGE && diff_r <= RESTORATION_RANGE);
-
-          wt = lfi->wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN] *
-               wr_lut_[diff_r];
-          wtsum += wt;
-          flsum += wt * data_p2[x];
-        }
-        data_p2 += stride;
-      }
-
-      assert(wtsum > 0);
-      tmpdata_p[j] = (int)(flsum / wtsum + 0.5);
-    }
-    tmpdata_p += tmpstride;
-    data_p += stride;
-  }
-  for (i = 0; i < height; ++i) {
-    memcpy(data + i * stride, tmpdata + i * tmpstride,
-           width * sizeof(*data));
-  }
-}
-
-// Normalized non-separable filter where weights all sum to 1
-void loop_restoration_filter_norm(uint8_t *data8, int width, int height,
-                                  int stride, loop_filter_info_n *lfi,
-                                  uint8_t *tmpdata8, int tmpstride) {
-  int i, j;
-  uint16_t *data = CONVERT_TO_SHORTPTR(data8);
-  uint16_t *tmpdata = CONVERT_TO_SHORTPTR(tmpdata8);
-  uint16_t *data_p = data;
-  uint16_t *tmpdata_p = tmpdata;
-  for (i = RESTORATION_HALFWIN; i < height - RESTORATION_HALFWIN; ++i) {
-    for (j = RESTORATION_HALFWIN; j < width - RESTORATION_HALFWIN; ++j) {
-      int x, y;
-      double flsum = 0;
-      uint16_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
-      for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
-        for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
-          flsum += data_p2[x] *
-              lfi->wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN];
-        }
-        data_p2 += stride;
-      }
-      tmpdata_p[j] = (int)(flsum + 0.5);
-    }
-    tmpdata_p += tmpstride;
-    data_p += stride;
-  }
-  for (i = 0; i < height; ++i) {
-    memcpy(data + i * stride, tmpdata + i * tmpstride,
-           width * sizeof(*data));
-  }
-}
-#endif  // CONFIG_VP9_HIGHBITDEPTH
-
-void vp10_loop_restoration_rows(YV12_BUFFER_CONFIG *frame,
-                                VP10_COMMON *cm,
-                                int start_mi_row, int end_mi_row,
-                                int y_only) {
-  const int ywidth = frame->y_crop_width;
-  const int ystride = frame->y_stride;
-  const int uvwidth = frame->uv_crop_width;
-  const int uvstride = frame->uv_stride;
-  const int ystart = start_mi_row << MI_SIZE_LOG2;
-  const int uvstart = ystart >> cm->subsampling_y;
-  int yend = end_mi_row << MI_SIZE_LOG2;
-  int uvend = yend >> cm->subsampling_y;
-  YV12_BUFFER_CONFIG *tmp_buf;
-  yend = VPXMIN(yend, cm->height);
-  uvend = VPXMIN(uvend, cm->subsampling_y ? (cm->height + 1) >> 1 : cm->height);
-
-  if (vpx_realloc_frame_buffer(&cm->tmp_loop_buf, cm->width, cm->height,
-                               cm->subsampling_x, cm->subsampling_y,
-#if CONFIG_VP9_HIGHBITDEPTH
-                               cm->use_highbitdepth,
-#endif
-                               VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment,
-                               NULL, NULL, NULL) < 0)
-    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
-                       "Failed to allocate tmp restoration buffer");
-
-  tmp_buf = &cm->tmp_loop_buf;
-
-#if CONFIG_VP9_HIGHBITDEPTH
-  if (cm->use_highbitdepth)
-    loop_restoration_filter_highbd(
-        frame->y_buffer + ystart * ystride,
-        ywidth, yend - ystart, ystride, &cm->lf_info,
-        tmp_buf->y_buffer + ystart * tmp_buf->y_stride,
-        tmp_buf->y_stride, cm->bit_depth);
-  else
-#endif  // CONFIG_VP9_HIGHBITDEPTH
-  loop_restoration_filter(
-      frame->y_buffer + ystart * ystride,
-      ywidth, yend - ystart, ystride, &cm->lf_info,
-      tmp_buf->y_buffer + ystart * tmp_buf->y_stride,
-      tmp_buf->y_stride);
-  if (!y_only) {
-#if CONFIG_VP9_HIGHBITDEPTH
-    if (cm->use_highbitdepth) {
-      loop_restoration_filter_highbd(
-          frame->u_buffer + uvstart * uvstride,
-          uvwidth, uvend - uvstart, uvstride, &cm->lf_info,
-          tmp_buf->u_buffer + uvstart * tmp_buf->uv_stride,
-          tmp_buf->uv_stride, cm->bit_depth);
-      loop_restoration_filter_highbd(
-          frame->v_buffer + uvstart * uvstride,
-          uvwidth, uvend - uvstart, uvstride, &cm->lf_info,
-          tmp_buf->v_buffer + uvstart * tmp_buf->uv_stride,
-          tmp_buf->uv_stride, cm->bit_depth);
-    } else {
-#endif  // CONFIG_VP9_HIGHBITDEPTH
-      loop_restoration_filter(
-          frame->u_buffer + uvstart * uvstride,
-          uvwidth, uvend - uvstart, uvstride, &cm->lf_info,
-          tmp_buf->u_buffer + uvstart * tmp_buf->uv_stride,
-          tmp_buf->uv_stride);
-      loop_restoration_filter(
-          frame->v_buffer + uvstart * uvstride,
-          uvwidth, uvend - uvstart, uvstride, &cm->lf_info,
-          tmp_buf->v_buffer + uvstart * tmp_buf->uv_stride,
-          tmp_buf->uv_stride);
-#if CONFIG_VP9_HIGHBITDEPTH
-    }
-#endif  // CONFIG_VP9_HIGHBITDEPTH
-  }
-}
-#endif  // CONFIG_LOOP_RESTORATION
-
 static void update_sharpness(loop_filter_info_n *lfi, int sharpness_lvl) {
   int lvl;
 
@@ -567,10 +256,6 @@ void vp10_loop_filter_init(VP10_COMMON *cm) {
   // init hev threshold const vectors
   for (lvl = 0; lvl <= MAX_LOOP_FILTER; lvl++)
     memset(lfi->lfthr[lvl].hev_thr, (lvl >> 4), SIMD_WIDTH);
-
-#if CONFIG_LOOP_RESTORATION
-  vp10_loop_restoration_precal();
-#endif  // CONFIG_LOOP_RESTORATION
 }
 
 void vp10_loop_filter_frame_init(VP10_COMMON *cm, int default_filt_lvl) {
@@ -2040,30 +1725,6 @@ void vp10_loop_filter_data_reset(
   memcpy(lf_data->planes, planes, sizeof(lf_data->planes));
 }
 
-#if CONFIG_LOOP_RESTORATION
-void vp10_loop_restoration_frame(YV12_BUFFER_CONFIG *frame,
-                               VP10_COMMON *cm,
-                               int restoration_level,
-                               int y_only, int partial_frame) {
-  int start_mi_row, end_mi_row, mi_rows_to_filter;
-  // const int loop_restoration_used = vp10_loop_restoration_used(
-  //     restoration_level, cm->frame_type == KEY_FRAME);
-  vp10_loop_restoration_init(&cm->lf_info, restoration_level,
-                           cm->frame_type == KEY_FRAME);
-  if (!cm->lf_info.restoration_used)
-    return;
-  start_mi_row = 0;
-  mi_rows_to_filter = cm->mi_rows;
-  if (partial_frame && cm->mi_rows > 8) {
-    start_mi_row = cm->mi_rows >> 1;
-    start_mi_row &= 0xfffffff8;
-    mi_rows_to_filter = VPXMAX(cm->mi_rows / 8, 8);
-  }
-  end_mi_row = start_mi_row + mi_rows_to_filter;
-  vp10_loop_restoration_rows(frame, cm, start_mi_row, end_mi_row, y_only);
-}
-#endif  // CONFIG_LOOP_RESTORATION
-
 int vp10_loop_filter_worker(LFWorkerData *const lf_data, void *unused) {
   (void)unused;
   vp10_loop_filter_rows(lf_data->frame_buffer, lf_data->cm, lf_data->planes,
index 953a6b8426d353ce9f7a1a968a82e9826a4f9378..5a16baa25a706ab9b711d64aa0f6811ee2ac871b 100644 (file)
@@ -15,6 +15,7 @@
 #include "./vpx_config.h"
 
 #include "vp10/common/blockd.h"
+#include "vp10/common/restoration.h"
 #include "vp10/common/seg_common.h"
 
 #ifdef __cplusplus
@@ -28,69 +29,6 @@ extern "C" {
 
 #define MAX_MODE_LF_DELTAS      2
 
-#if CONFIG_LOOP_RESTORATION
-#define RESTORATION_LEVEL_BITS_KF 4
-#define RESTORATION_LEVELS_KF     (1 << RESTORATION_LEVEL_BITS_KF)
-#define RESTORATION_LEVEL_BITS    3
-#define RESTORATION_LEVELS        (1 << RESTORATION_LEVEL_BITS)
-#define DEF_RESTORATION_LEVEL     2
-
-#define RESTORATION_PRECISION     16
-#define RESTORATION_HALFWIN       3
-#define RESTORATION_WIN           (2 * RESTORATION_HALFWIN + 1)
-
-typedef struct restoration_params {
-  int sigma_x;  // spatial variance x
-  int sigma_y;  // spatial variance y
-  int sigma_r;  // range variance
-} restoration_params_t;
-
-static restoration_params_t
-    restoration_level_to_params_arr[RESTORATION_LEVELS + 1] = {
-  // Values are rounded to 1/16 th precision
-  {0, 0, 0},    // 0 - default
-  {8, 9, 30},
-  {9, 8, 30},
-  {9, 11, 32},
-  {11, 9, 32},
-  {14, 14, 32},
-  {18, 18, 36},
-  {24, 24, 40},
-  {32, 32, 40},
-};
-
-static restoration_params_t
-    restoration_level_to_params_arr_kf[RESTORATION_LEVELS_KF + 1] = {
-  // Values are rounded to 1/16 th precision
-  {0, 0, 0},    // 0 - default
-  {8, 8, 30},
-  {9, 9, 32},
-  {10, 10, 32},
-  {12, 12, 32},
-  {14, 14, 32},
-  {18, 18, 36},
-  {24, 24, 40},
-  {30, 30, 44},
-  {36, 36, 48},
-  {42, 42, 48},
-  {48, 48, 48},
-  {48, 48, 56},
-  {56, 56, 48},
-  {56, 56, 56},
-  {56, 56, 64},
-  {64, 64, 48},
-};
-
-int vp10_restoration_level_bits(const struct VP10Common *const cm);
-int vp10_loop_restoration_used(int level, int kf);
-
-static INLINE restoration_params_t vp10_restoration_level_to_params(
-    int index, int kf) {
-  return kf ? restoration_level_to_params_arr_kf[index] :
-              restoration_level_to_params_arr[index];
-}
-#endif  // CONFIG_LOOP_RESTORATION
-
 enum lf_path {
   LF_PATH_420,
   LF_PATH_444,
@@ -132,14 +70,6 @@ typedef struct {
 typedef struct {
   loop_filter_thresh lfthr[MAX_LOOP_FILTER + 1];
   uint8_t lvl[MAX_SEGMENTS][MAX_REF_FRAMES][MAX_MODE_LF_DELTAS];
-#if CONFIG_LOOP_RESTORATION
-  double *wx_lut[RESTORATION_WIN];
-  double *wr_lut;
-  int restoration_sigma_x_set;
-  int restoration_sigma_y_set;
-  int restoration_sigma_r_set;
-  int restoration_used;
-#endif  // CONFIG_LOOP_RESTORATION
 } loop_filter_info_n;
 
 // This structure holds bit masks for all 8x8 blocks in a 64x64 region.
@@ -209,24 +139,6 @@ void vp10_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer,
                            struct macroblockd_plane planes[MAX_MB_PLANE],
                            int start, int stop, int y_only);
 
-#if CONFIG_LOOP_RESTORATION
-void vp10_loop_restoration_frame(YV12_BUFFER_CONFIG *frame,
-                                 struct VP10Common *cm,
-                                 int restoration_level,
-                                 int y_only, int partial_frame);
-void vp10_loop_filter_restoration_frame(YV12_BUFFER_CONFIG *frame,
-                                        struct VP10Common *cm,
-                                        struct macroblockd *mbd,
-                                        int frame_filter_level,
-                                        int restoration_level,
-                                        int y_only, int partial_frame);
-void vp10_loop_restoration_init(loop_filter_info_n *lfi, int T, int kf);
-void vp10_loop_restoration_rows(YV12_BUFFER_CONFIG *frame,
-                                struct VP10Common *cm,
-                                int start_mi_row, int end_mi_row,
-                                int y_only);
-#endif  // CONFIG_LOOP_RESTORATION
-
 typedef struct LoopFilterWorkerData {
   YV12_BUFFER_CONFIG *frame_buffer;
   struct VP10Common *cm;
index b6509cb484dad9c2d46956c16d0c5ee8999715b2..53de852d190d734eaacd519c741e4ea655090ce1 100644 (file)
@@ -24,6 +24,7 @@
 #include "vp10/common/frame_buffers.h"
 #include "vp10/common/quant_common.h"
 #include "vp10/common/tile_common.h"
+#include "vp10/common/restoration.h"
 
 #if CONFIG_VP9_POSTPROC
 #include "vp10/common/postproc.h"
@@ -255,6 +256,9 @@ typedef struct VP10Common {
   INTERP_FILTER interp_filter;
 
   loop_filter_info_n lf_info;
+#if CONFIG_LOOP_RESTORATION
+  restoration_info_n rst_info;
+#endif  // CONFIG_LOOP_RESTORATION
 
   // Flag signaling how frame contexts should be updated at the end of
   // a frame decode
diff --git a/vp10/common/restoration.c b/vp10/common/restoration.c
new file mode 100644 (file)
index 0000000..ee720c4
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ *  Copyright (c) 2016 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.
+ */
+
+#include <math.h>
+
+#include "./vpx_config.h"
+#include "./vpx_dsp_rtcd.h"
+#include "vp10/common/onyxc_int.h"
+#include "vp10/common/restoration.h"
+#include "vpx_dsp/vpx_dsp_common.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vpx_ports/mem.h"
+
+#define RESTORATION_RANGE  256
+#define RESTORATION_RANGE_SYM  (2 * RESTORATION_RANGE + 1)
+static double restoration_filters_r_kf[RESTORATION_LEVELS_KF + 1]
+                                    [RESTORATION_RANGE_SYM];
+static double restoration_filters_r[RESTORATION_LEVELS + 1]
+                                   [RESTORATION_RANGE_SYM];
+static double restoration_filters_s_kf[RESTORATION_LEVELS_KF + 1]
+                                      [RESTORATION_WIN][RESTORATION_WIN];
+static double restoration_filters_s[RESTORATION_LEVELS + 1]
+                                   [RESTORATION_WIN][RESTORATION_WIN];
+
+void vp10_loop_restoration_precal() {
+  int i;
+  for (i = 1; i < RESTORATION_LEVELS_KF + 1; i ++) {
+    const restoration_params_t param = vp10_restoration_level_to_params(i, 1);
+    const int sigma_x = param.sigma_x;
+    const int sigma_y = param.sigma_y;
+    const int sigma_r = param.sigma_r;
+    const double sigma_r_d = (double)sigma_r / RESTORATION_PRECISION;
+    const double sigma_x_d = (double)sigma_x / RESTORATION_PRECISION;
+    const double sigma_y_d = (double)sigma_y / RESTORATION_PRECISION;
+
+    double *fr = restoration_filters_r_kf[i] + RESTORATION_RANGE;
+    int j, x, y;
+    for (j = 0; j <= RESTORATION_RANGE; j++) {
+      fr[j] = exp(-(j * j) / (2 * sigma_r_d * sigma_r_d));
+      fr[-j] = fr[j];
+    }
+    for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; y++) {
+      for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; x++) {
+        restoration_filters_s_kf[i][y + RESTORATION_HALFWIN]
+                                 [x + RESTORATION_HALFWIN] =
+          exp(-(x * x) / (2 * sigma_x_d * sigma_x_d)
+              -(y * y) / (2 * sigma_y_d * sigma_y_d));
+      }
+    }
+  }
+  for (i = 1; i < RESTORATION_LEVELS + 1; i ++) {
+    const restoration_params_t param = vp10_restoration_level_to_params(i, 0);
+    const int sigma_x = param.sigma_x;
+    const int sigma_y = param.sigma_y;
+    const int sigma_r = param.sigma_r;
+    const double sigma_r_d = (double)sigma_r / RESTORATION_PRECISION;
+    const double sigma_x_d = (double)sigma_x / RESTORATION_PRECISION;
+    const double sigma_y_d = (double)sigma_y / RESTORATION_PRECISION;
+
+    double *fr = restoration_filters_r[i] + RESTORATION_RANGE;
+    int j, x, y;
+    for (j = 0; j <= RESTORATION_RANGE; j++) {
+      fr[j] = exp(-(j * j) / (2 * sigma_r_d * sigma_r_d));
+      fr[-j] = fr[j];
+    }
+    for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; y++) {
+      for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; x++) {
+        restoration_filters_s
+            [i][y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN] =
+            exp(-(x * x) / (2 * sigma_x_d * sigma_x_d)
+                -(y * y) / (2 * sigma_y_d * sigma_y_d));
+      }
+    }
+  }
+}
+
+int vp10_restoration_level_bits(const VP10_COMMON *const cm) {
+  return cm->frame_type == KEY_FRAME ?
+      RESTORATION_LEVEL_BITS_KF : RESTORATION_LEVEL_BITS;
+}
+
+int vp10_loop_restoration_used(int level, int kf) {
+  const restoration_params_t param =
+      vp10_restoration_level_to_params(level, kf);
+  return (param.sigma_x && param.sigma_y && param.sigma_r);
+}
+
+void vp10_loop_restoration_init(restoration_info_n *rst,
+                                int level, int kf) {
+  rst->restoration_used = vp10_loop_restoration_used(level, kf);
+
+  if (rst->restoration_used) {
+    int i;
+    rst->wr_lut = kf ? restoration_filters_r_kf[level] :
+                       restoration_filters_r[level];
+    for (i = 0; i < RESTORATION_WIN; i++)
+      rst->wx_lut[i] = kf ? restoration_filters_s_kf[level][i] :
+                            restoration_filters_s[level][i];
+  }
+}
+
+static int is_in_image(int x, int y, int width, int height) {
+  return (x >= 0 && x < width && y >= 0 && y < height);
+}
+
+static void loop_restoration_filter(uint8_t *data, int width, int height,
+                                    int stride, restoration_info_n *rst,
+                                    uint8_t *tmpdata, int tmpstride) {
+  int i, j;
+  const double *wr_lut_ = rst->wr_lut + RESTORATION_RANGE;
+
+  uint8_t *data_p = data;
+  uint8_t *tmpdata_p = tmpdata;
+  for (i = 0; i < height; ++i) {
+    for (j = 0; j < width; ++j) {
+      int x, y;
+      double flsum = 0, wtsum = 0, wt;
+      uint8_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
+      for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
+        for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
+          if (!is_in_image(j + x, i + y, width, height))
+            continue;
+          wt = rst->wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN] *
+               wr_lut_[data_p2[x] - data_p[j]];
+          wtsum += wt;
+          flsum += wt * data_p2[x];
+        }
+        data_p2 += stride;
+      }
+      assert(wtsum > 0);
+      tmpdata_p[j] = clip_pixel((int)(flsum / wtsum + 0.5));
+    }
+    tmpdata_p += tmpstride;
+    data_p += stride;
+  }
+
+  for (i = 0; i < height; ++i) {
+    memcpy(data + i * stride, tmpdata + i * tmpstride,
+           width * sizeof(*data));
+  }
+}
+
+// Normalized non-separable filter where weights all sum to 1
+static void loop_restoration_filter_norm(uint8_t *data, int width, int height,
+                                         int stride, restoration_info_n *rst,
+                                         uint8_t *tmpdata, int tmpstride) {
+  int i, j;
+  uint8_t *data_p = data;
+  uint8_t *tmpdata_p = tmpdata;
+  for (i = RESTORATION_HALFWIN; i < height - RESTORATION_HALFWIN; ++i) {
+    for (j = RESTORATION_HALFWIN; j < width - RESTORATION_HALFWIN; ++j) {
+      int x, y;
+      double flsum = 0;
+      uint8_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
+      for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
+        for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
+          flsum += data_p2[x] *
+              rst->wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN];
+        }
+        data_p2 += stride;
+      }
+      tmpdata_p[j] = clip_pixel((int)(flsum + 0.5));
+    }
+    tmpdata_p += tmpstride;
+    data_p += stride;
+  }
+  for (i = 0; i < height; ++i) {
+    memcpy(data + i * stride, tmpdata + i * tmpstride,
+           width * sizeof(*data));
+  }
+}
+
+#if CONFIG_VP9_HIGHBITDEPTH
+static void loop_restoration_filter_highbd(
+    uint8_t *data8, int width, int height,
+    int stride, restoration_info_n *rst,
+    uint8_t *tmpdata8, int tmpstride, int bit_depth) {
+  int i, j;
+  const double *wr_lut_ = rst->wr_lut + RESTORATION_RANGE;
+
+  uint16_t *data = CONVERT_TO_SHORTPTR(data8);
+  uint16_t *tmpdata = CONVERT_TO_SHORTPTR(tmpdata8);
+  uint16_t *data_p = data;
+  uint16_t *tmpdata_p = tmpdata;
+  for (i = 0; i < height; ++i) {
+    for (j = 0; j < width; ++j) {
+      int x, y, diff_r;
+      double flsum = 0, wtsum = 0, wt;
+      uint16_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
+
+      for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
+        for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
+          if (!is_in_image(j + x, i + y, width, height))
+            continue;
+
+          diff_r = (data_p2[x] - data_p[j]) >> (bit_depth - 8);
+          assert(diff_r >= -RESTORATION_RANGE && diff_r <= RESTORATION_RANGE);
+
+          wt = rst->wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN] *
+               wr_lut_[diff_r];
+          wtsum += wt;
+          flsum += wt * data_p2[x];
+        }
+        data_p2 += stride;
+      }
+
+      assert(wtsum > 0);
+      tmpdata_p[j] = (int)(flsum / wtsum + 0.5);
+    }
+    tmpdata_p += tmpstride;
+    data_p += stride;
+  }
+  for (i = 0; i < height; ++i) {
+    memcpy(data + i * stride, tmpdata + i * tmpstride,
+           width * sizeof(*data));
+  }
+}
+
+// Normalized non-separable filter where weights all sum to 1
+static void loop_restoration_filter_norm_highbd(
+    uint8_t *data8, int width, int height,
+    int stride, restoration_info_n *rst,
+    uint8_t *tmpdata8, int tmpstride) {
+  int i, j;
+  uint16_t *data = CONVERT_TO_SHORTPTR(data8);
+  uint16_t *tmpdata = CONVERT_TO_SHORTPTR(tmpdata8);
+  uint16_t *data_p = data;
+  uint16_t *tmpdata_p = tmpdata;
+  for (i = RESTORATION_HALFWIN; i < height - RESTORATION_HALFWIN; ++i) {
+    for (j = RESTORATION_HALFWIN; j < width - RESTORATION_HALFWIN; ++j) {
+      int x, y;
+      double flsum = 0;
+      uint16_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
+      for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
+        for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
+          flsum += data_p2[x] *
+              rst->wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN];
+        }
+        data_p2 += stride;
+      }
+      tmpdata_p[j] = (int)(flsum + 0.5);
+    }
+    tmpdata_p += tmpstride;
+    data_p += stride;
+  }
+  for (i = 0; i < height; ++i) {
+    memcpy(data + i * stride, tmpdata + i * tmpstride,
+           width * sizeof(*data));
+  }
+}
+#endif  // CONFIG_VP9_HIGHBITDEPTH
+
+void vp10_loop_restoration_rows(YV12_BUFFER_CONFIG *frame,
+                                VP10_COMMON *cm,
+                                int start_mi_row, int end_mi_row,
+                                int y_only) {
+  const int ywidth = frame->y_crop_width;
+  const int ystride = frame->y_stride;
+  const int uvwidth = frame->uv_crop_width;
+  const int uvstride = frame->uv_stride;
+  const int ystart = start_mi_row << MI_SIZE_LOG2;
+  const int uvstart = ystart >> cm->subsampling_y;
+  int yend = end_mi_row << MI_SIZE_LOG2;
+  int uvend = yend >> cm->subsampling_y;
+  YV12_BUFFER_CONFIG *tmp_buf;
+  yend = VPXMIN(yend, cm->height);
+  uvend = VPXMIN(uvend, cm->subsampling_y ? (cm->height + 1) >> 1 : cm->height);
+
+  if (vpx_realloc_frame_buffer(&cm->tmp_loop_buf, cm->width, cm->height,
+                               cm->subsampling_x, cm->subsampling_y,
+#if CONFIG_VP9_HIGHBITDEPTH
+                               cm->use_highbitdepth,
+#endif
+                               VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment,
+                               NULL, NULL, NULL) < 0)
+    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
+                       "Failed to allocate tmp restoration buffer");
+
+  tmp_buf = &cm->tmp_loop_buf;
+
+#if CONFIG_VP9_HIGHBITDEPTH
+  if (cm->use_highbitdepth)
+    loop_restoration_filter_highbd(
+        frame->y_buffer + ystart * ystride,
+        ywidth, yend - ystart, ystride, &cm->rst_info,
+        tmp_buf->y_buffer + ystart * tmp_buf->y_stride,
+        tmp_buf->y_stride, cm->bit_depth);
+  else
+#endif  // CONFIG_VP9_HIGHBITDEPTH
+  loop_restoration_filter(
+      frame->y_buffer + ystart * ystride,
+      ywidth, yend - ystart, ystride, &cm->rst_info,
+      tmp_buf->y_buffer + ystart * tmp_buf->y_stride,
+      tmp_buf->y_stride);
+  if (!y_only) {
+#if CONFIG_VP9_HIGHBITDEPTH
+    if (cm->use_highbitdepth) {
+      loop_restoration_filter_highbd(
+          frame->u_buffer + uvstart * uvstride,
+          uvwidth, uvend - uvstart, uvstride, &cm->rst_info,
+          tmp_buf->u_buffer + uvstart * tmp_buf->uv_stride,
+          tmp_buf->uv_stride, cm->bit_depth);
+      loop_restoration_filter_highbd(
+          frame->v_buffer + uvstart * uvstride,
+          uvwidth, uvend - uvstart, uvstride, &cm->rst_info,
+          tmp_buf->v_buffer + uvstart * tmp_buf->uv_stride,
+          tmp_buf->uv_stride, cm->bit_depth);
+    } else {
+#endif  // CONFIG_VP9_HIGHBITDEPTH
+      loop_restoration_filter(
+          frame->u_buffer + uvstart * uvstride,
+          uvwidth, uvend - uvstart, uvstride, &cm->rst_info,
+          tmp_buf->u_buffer + uvstart * tmp_buf->uv_stride,
+          tmp_buf->uv_stride);
+      loop_restoration_filter(
+          frame->v_buffer + uvstart * uvstride,
+          uvwidth, uvend - uvstart, uvstride, &cm->rst_info,
+          tmp_buf->v_buffer + uvstart * tmp_buf->uv_stride,
+          tmp_buf->uv_stride);
+#if CONFIG_VP9_HIGHBITDEPTH
+    }
+#endif  // CONFIG_VP9_HIGHBITDEPTH
+  }
+}
+
+void vp10_loop_restoration_frame(YV12_BUFFER_CONFIG *frame,
+                               VP10_COMMON *cm,
+                               int restoration_level,
+                               int y_only, int partial_frame) {
+  int start_mi_row, end_mi_row, mi_rows_to_filter;
+  vp10_loop_restoration_init(&cm->rst_info, restoration_level,
+                             cm->frame_type == KEY_FRAME);
+  if (!cm->rst_info.restoration_used)
+    return;
+  start_mi_row = 0;
+  mi_rows_to_filter = cm->mi_rows;
+  if (partial_frame && cm->mi_rows > 8) {
+    start_mi_row = cm->mi_rows >> 1;
+    start_mi_row &= 0xfffffff8;
+    mi_rows_to_filter = VPXMAX(cm->mi_rows / 8, 8);
+  }
+  end_mi_row = start_mi_row + mi_rows_to_filter;
+  vp10_loop_restoration_rows(frame, cm, start_mi_row, end_mi_row, y_only);
+}
diff --git a/vp10/common/restoration.h b/vp10/common/restoration.h
new file mode 100644 (file)
index 0000000..3859191
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *  Copyright (c) 2016 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.
+ */
+
+#ifndef VP10_COMMON_RESTORATION_H_
+#define VP10_COMMON_RESTORATION_H_
+
+#include "vpx_ports/mem.h"
+#include "./vpx_config.h"
+
+#include "vp10/common/blockd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RESTORATION_LEVEL_BITS_KF 4
+#define RESTORATION_LEVELS_KF     (1 << RESTORATION_LEVEL_BITS_KF)
+#define RESTORATION_LEVEL_BITS    3
+#define RESTORATION_LEVELS        (1 << RESTORATION_LEVEL_BITS)
+#define DEF_RESTORATION_LEVEL     2
+
+#define RESTORATION_PRECISION     16
+#define RESTORATION_HALFWIN       3
+#define RESTORATION_WIN           (2 * RESTORATION_HALFWIN + 1)
+
+typedef struct restoration_params {
+  int sigma_x;  // spatial variance x
+  int sigma_y;  // spatial variance y
+  int sigma_r;  // range variance
+} restoration_params_t;
+
+static restoration_params_t
+    restoration_level_to_params_arr[RESTORATION_LEVELS + 1] = {
+  // Values are rounded to 1/16 th precision
+  {0, 0, 0},    // 0 - default
+  {8, 9, 30},
+  {9, 8, 30},
+  {9, 11, 32},
+  {11, 9, 32},
+  {14, 14, 32},
+  {18, 18, 36},
+  {24, 24, 40},
+  {32, 32, 40},
+};
+
+static restoration_params_t
+    restoration_level_to_params_arr_kf[RESTORATION_LEVELS_KF + 1] = {
+  // Values are rounded to 1/16 th precision
+  {0, 0, 0},    // 0 - default
+  {8, 8, 30},
+  {9, 9, 32},
+  {10, 10, 32},
+  {12, 12, 32},
+  {14, 14, 32},
+  {18, 18, 36},
+  {24, 24, 40},
+  {30, 30, 44},
+  {36, 36, 48},
+  {42, 42, 48},
+  {48, 48, 48},
+  {48, 48, 56},
+  {56, 56, 48},
+  {56, 56, 56},
+  {56, 56, 64},
+  {64, 64, 48},
+};
+
+typedef struct {
+  double *wx_lut[RESTORATION_WIN];
+  double *wr_lut;
+  int restoration_sigma_x_set;
+  int restoration_sigma_y_set;
+  int restoration_sigma_r_set;
+  int restoration_used;
+} restoration_info_n;
+
+int vp10_restoration_level_bits(const struct VP10Common *const cm);
+int vp10_loop_restoration_used(int level, int kf);
+
+static INLINE restoration_params_t vp10_restoration_level_to_params(
+    int index, int kf) {
+  return kf ? restoration_level_to_params_arr_kf[index] :
+              restoration_level_to_params_arr[index];
+}
+
+void vp10_loop_restoration_init(restoration_info_n *rst, int T, int kf);
+void vp10_loop_restoration_frame(YV12_BUFFER_CONFIG *frame,
+                                 struct VP10Common *cm,
+                                 int restoration_level,
+                                 int y_only, int partial_frame);
+void vp10_loop_restoration_rows(YV12_BUFFER_CONFIG *frame,
+                                struct VP10Common *cm,
+                                int start_mi_row, int end_mi_row,
+                                int y_only);
+void vp10_loop_restoration_precal();
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // VP10_COMMON_RESTORATION_H_
index d0c9ffbc24e4d9213ee2303ab0158f432549cff3..c8c8d8ae7cf8389632602abcfca30553e96f6bbe 100644 (file)
@@ -3481,9 +3481,9 @@ void vp10_decode_frame(VP10Decoder *pbi,
     *p_data_end = decode_tiles(pbi, data + first_partition_size, data_end);
   }
 #if CONFIG_LOOP_RESTORATION
-  vp10_loop_restoration_init(&cm->lf_info, cm->lf.restoration_level,
+  vp10_loop_restoration_init(&cm->rst_info, cm->lf.restoration_level,
                              cm->frame_type == KEY_FRAME);
-  if (cm->lf_info.restoration_used) {
+  if (cm->rst_info.restoration_used) {
     vp10_loop_restoration_rows(new_fb, cm, 0, cm->mi_rows, 0);
   }
 #endif  // CONFIG_LOOP_RESTORATION
index 329e54cc18b65644f520ea43dffb29db9eb4ede9..90365a819913a15d23a4dadfcb6817fb99105268 100644 (file)
@@ -115,6 +115,9 @@ VP10Decoder *vp10_decoder_create(BufferPool *const pool) {
   cm->setup_mi = vp10_dec_setup_mi;
 
   vp10_loop_filter_init(cm);
+#if CONFIG_LOOP_RESTORATION
+  vp10_loop_restoration_precal();
+#endif  // CONFIG_LOOP_RESTORATION
 #if CONFIG_ANS
   vp10_build_pareto8_dec_tab(vp10_pareto8_token_probs, pbi->token_tab);
 #endif  // CONFIG_ANS
index c3e2fcd72698153ffbe70a34a06c89dbba11dc2e..374a62e7f9db6b59de6f37d8fcd4e954dc851dd9 100644 (file)
@@ -1871,6 +1871,9 @@ VP10_COMP *vp10_create_compressor(VP10EncoderConfig *oxcf,
   vp10_init_quantizer(cpi);
 
   vp10_loop_filter_init(cm);
+#if CONFIG_LOOP_RESTORATION
+  vp10_loop_restoration_precal();
+#endif  // CONFIG_LOOP_RESTORATION
 
   cm->error.setjmp = 0;
 
@@ -2779,9 +2782,9 @@ static void loopfilter_frame(VP10_COMP *cpi, VP10_COMMON *cm) {
 #endif
   }
 #if CONFIG_LOOP_RESTORATION
-  vp10_loop_restoration_init(&cm->lf_info, cm->lf.restoration_level,
-                           cm->frame_type == KEY_FRAME);
-  if (cm->lf_info.restoration_used)
+  vp10_loop_restoration_init(&cm->rst_info, cm->lf.restoration_level,
+                             cm->frame_type == KEY_FRAME);
+  if (cm->rst_info.restoration_used)
     vp10_loop_restoration_rows(cm->frame_to_show, cm, 0, cm->mi_rows, 0);
 #endif  // CONFIG_LOOP_RESTORATION
 
index bc3d84aa15dc7463727d3dd4323bec2542268039..fab97eae394f6df630650fb9e73ba0865ad36905 100644 (file)
@@ -80,6 +80,8 @@ VP10_COMMON_SRCS-$(CONFIG_ANS) += common/divide.c
 
 VP10_COMMON_SRCS-$(CONFIG_VP9_POSTPROC) += common/postproc.h
 VP10_COMMON_SRCS-$(CONFIG_VP9_POSTPROC) += common/postproc.c
+VP10_COMMON_SRCS-$(CONFIG_LOOP_RESTORATION) += common/restoration.h
+VP10_COMMON_SRCS-$(CONFIG_LOOP_RESTORATION) += common/restoration.c
 VP10_COMMON_SRCS-$(CONFIG_VP9_POSTPROC) += common/mfqe.h
 VP10_COMMON_SRCS-$(CONFIG_VP9_POSTPROC) += common/mfqe.c
 ifeq ($(CONFIG_VP9_POSTPROC),yes)