shithub: libvpx

Download patch

ref: 92a9eaef5078dde1bc4fc35eabca4d987dc6fddb
parent: 204d1b70587ef3698bcce1e337da934532dd65b5
author: Dmitry Kovalev <dkovalev@google.com>
date: Tue Jul 9 07:17:36 EDT 2013

Loop filter code cleanup.

Using MAX_LOOP_FILTER constant instead of number 63.

Change-Id: If91e0c198331b3041e7cd0707a5948479e9209d8

--- a/vp9/common/vp9_loopfilter.c
+++ b/vp9/common/vp9_loopfilter.c
@@ -35,17 +35,13 @@
 
 void vp9_loop_filter_update_sharpness(loop_filter_info_n *lfi,
                                       int sharpness_lvl) {
-  int i;
+  int lvl;
 
-  /* For each possible value for the loop filter fill out limits */
-  for (i = 0; i <= MAX_LOOP_FILTER; i++) {
-    int filt_lvl = i;
-    int block_inside_limit = 0;
+  // For each possible value for the loop filter fill out limits
+  for (lvl = 0; lvl <= MAX_LOOP_FILTER; lvl++) {
+    // Set loop filter paramaeters that control sharpness.
+    int block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4));
 
-    /* Set loop filter paramaeters that control sharpness. */
-    block_inside_limit = filt_lvl >> (sharpness_lvl > 0);
-    block_inside_limit = block_inside_limit >> (sharpness_lvl > 4);
-
     if (sharpness_lvl > 0) {
       if (block_inside_limit > (9 - sharpness_lvl))
         block_inside_limit = (9 - sharpness_lvl);
@@ -54,11 +50,10 @@
     if (block_inside_limit < 1)
       block_inside_limit = 1;
 
-    vpx_memset(lfi->lim[i], block_inside_limit, SIMD_WIDTH);
-    vpx_memset(lfi->blim[i], (2 * filt_lvl + block_inside_limit),
+    vpx_memset(lfi->lim[lvl], block_inside_limit, SIMD_WIDTH);
+    vpx_memset(lfi->blim[lvl], (2 * lvl + block_inside_limit), SIMD_WIDTH);
+    vpx_memset(lfi->mblim[lvl], (2 * (lvl + 2) + block_inside_limit),
                SIMD_WIDTH);
-    vpx_memset(lfi->mblim[i], (2 * (filt_lvl + 2) + block_inside_limit),
-               SIMD_WIDTH);
   }
 }
 
@@ -78,23 +73,16 @@
     vpx_memset(lfi->hev_thr[i], i, SIMD_WIDTH);
 }
 
-void vp9_loop_filter_frame_init(VP9_COMMON *cm,
-                                MACROBLOCKD *xd,
+void vp9_loop_filter_frame_init(VP9_COMMON *cm, MACROBLOCKD *xd,
                                 int default_filt_lvl) {
-  int seg,    // segment number
-      ref,    // index in ref_lf_deltas
-      mode;   // index in mode_lf_deltas
+  int seg;
   // n_shift is the a multiplier for lf_deltas
   // the multiplier is 1 for when filter_lvl is between 0 and 31;
   // 2 when filter_lvl is between 32 and 63
-  int n_shift = default_filt_lvl >> 5;
+  const int n_shift = default_filt_lvl >> 5;
+  loop_filter_info_n *const lfi = &cm->lf_info;
 
-  loop_filter_info_n *lfi = &cm->lf_info;
-
-  /* update limits if sharpness has changed */
-  // printf("vp9_loop_filter_frame_init %d\n", default_filt_lvl);
-  // printf("sharpness level: %d [%d]\n",
-  //        cm->sharpness_level, cm->last_sharpness_level);
+  // update limits if sharpness has changed
   if (cm->last_sharpness_level != cm->sharpness_level) {
     vp9_loop_filter_update_sharpness(lfi, cm->sharpness_level);
     cm->last_sharpness_level = cm->sharpness_level;
@@ -101,75 +89,52 @@
   }
 
   for (seg = 0; seg < MAX_MB_SEGMENTS; seg++) {
-    int lvl_seg = default_filt_lvl;
-    int lvl_ref, lvl_mode;
+    int lvl_seg = default_filt_lvl, ref, mode, intra_lvl;
 
-
     // Set the baseline filter values for each segment
     if (vp9_segfeature_active(xd, seg, SEG_LVL_ALT_LF)) {
-      /* Abs value */
-      if (xd->mb_segment_abs_delta == SEGMENT_ABSDATA) {
-        lvl_seg = vp9_get_segdata(xd, seg, SEG_LVL_ALT_LF);
-      } else { /* Delta Value */
-        lvl_seg += vp9_get_segdata(xd, seg, SEG_LVL_ALT_LF);
-        lvl_seg = clamp(lvl_seg, 0, 63);
-      }
+      const int data = vp9_get_segdata(xd, seg, SEG_LVL_ALT_LF);
+      lvl_seg = xd->mb_segment_abs_delta == SEGMENT_ABSDATA
+                  ? data
+                  : clamp(default_filt_lvl + data, 0, MAX_LOOP_FILTER);
     }
 
     if (!xd->mode_ref_lf_delta_enabled) {
-      /* we could get rid of this if we assume that deltas are set to
-       * zero when not in use; encoder always uses deltas
-       */
+      // we could get rid of this if we assume that deltas are set to
+      // zero when not in use; encoder always uses deltas
       vpx_memset(lfi->lvl[seg][0], lvl_seg, 4 * 4);
       continue;
     }
 
-    lvl_ref = lvl_seg;
+    intra_lvl = lvl_seg + (xd->ref_lf_deltas[INTRA_FRAME] << n_shift);
+    lfi->lvl[seg][INTRA_FRAME][0] = clamp(intra_lvl, 0, MAX_LOOP_FILTER);
 
-    /* INTRA_FRAME */
-    ref = INTRA_FRAME;
-
-    /* Apply delta for reference frame */
-    lvl_ref += xd->ref_lf_deltas[ref] << n_shift;
-
-    mode = 0; /* all the rest of Intra modes */
-    lvl_mode = lvl_ref;
-    lfi->lvl[seg][ref][mode] = clamp(lvl_mode, 0, 63);
-
-    /* LAST, GOLDEN, ALT */
-    for (ref = 1; ref < MAX_REF_FRAMES; ref++) {
-      int lvl_ref = lvl_seg;
-
-      /* Apply delta for reference frame */
-      lvl_ref += xd->ref_lf_deltas[ref] << n_shift;
-
-      /* Apply delta for Inter modes */
-      for (mode = 0; mode < MAX_MODE_LF_DELTAS; mode++) {
-        lvl_mode = lvl_ref + (xd->mode_lf_deltas[mode] << n_shift);
-        lfi->lvl[seg][ref][mode] = clamp(lvl_mode, 0, 63);
+    for (ref = LAST_FRAME; ref < MAX_REF_FRAMES; ++ref)
+      for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) {
+        const int inter_lvl = lvl_seg + (xd->ref_lf_deltas[ref] << n_shift)
+                                      + (xd->mode_lf_deltas[mode] << n_shift);
+        lfi->lvl[seg][ref][mode] = clamp(inter_lvl, 0, MAX_LOOP_FILTER);
       }
-    }
   }
 }
 
 static int build_lfi(const VP9_COMMON *cm, const MB_MODE_INFO *mbmi,
                       struct loop_filter_info *lfi) {
-  const loop_filter_info_n *lfi_n = &cm->lf_info;
-  int mode = mbmi->mode;
-  int mode_index = lfi_n->mode_lf_lut[mode];
-  int seg = mbmi->segment_id;
-  int ref_frame = mbmi->ref_frame[0];
-  int filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
+  const loop_filter_info_n *const lfi_n = &cm->lf_info;
+  const int seg = mbmi->segment_id;
+  const int ref = mbmi->ref_frame[0];
+  const int mode = lfi_n->mode_lf_lut[mbmi->mode];
+  const int filter_level = lfi_n->lvl[seg][ref][mode];
 
-  if (filter_level) {
-    const int hev_index = filter_level >> 4;
+  if (filter_level > 0) {
     lfi->mblim = lfi_n->mblim[filter_level];
     lfi->blim = lfi_n->blim[filter_level];
     lfi->lim = lfi_n->lim[filter_level];
-    lfi->hev_thr = lfi_n->hev_thr[hev_index];
+    lfi->hev_thr = lfi_n->hev_thr[filter_level >> 4];
     return 1;
+  } else {
+    return 0;
   }
-  return 0;
 }
 
 static void filter_selectively_vert(uint8_t *s, int pitch,
--- a/vp9/common/vp9_loopfilter.h
+++ b/vp9/common/vp9_loopfilter.h
@@ -16,34 +16,35 @@
 #include "vp9/common/vp9_blockd.h"
 
 #define MAX_LOOP_FILTER 63
+#define MAX_SHARPNESS 7
+
 #define SIMD_WIDTH 16
 
-/* Need to align this structure so when it is declared and
- * passed it can be loaded into vector registers.
- */
+// Need to align this structure so when it is declared and
+// passed it can be loaded into vector registers.
 typedef struct {
-  DECLARE_ALIGNED(SIMD_WIDTH, unsigned char,
+  DECLARE_ALIGNED(SIMD_WIDTH, uint8_t,
                   mblim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]);
-  DECLARE_ALIGNED(SIMD_WIDTH, unsigned char,
+  DECLARE_ALIGNED(SIMD_WIDTH, uint8_t,
                   blim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]);
-  DECLARE_ALIGNED(SIMD_WIDTH, unsigned char,
+  DECLARE_ALIGNED(SIMD_WIDTH, uint8_t,
                   lim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]);
-  DECLARE_ALIGNED(SIMD_WIDTH, unsigned char,
+  DECLARE_ALIGNED(SIMD_WIDTH, uint8_t,
                   hev_thr[4][SIMD_WIDTH]);
-  unsigned char lvl[MAX_MB_SEGMENTS][4][4];
-  unsigned char mode_lf_lut[MB_MODE_COUNT];
+  uint8_t lvl[MAX_MB_SEGMENTS][MAX_REF_FRAMES][MAX_MODE_LF_DELTAS];
+  uint8_t mode_lf_lut[MB_MODE_COUNT];
 } loop_filter_info_n;
 
 struct loop_filter_info {
-  const unsigned char *mblim;
-  const unsigned char *blim;
-  const unsigned char *lim;
-  const unsigned char *hev_thr;
+  const uint8_t *mblim;
+  const uint8_t *blim;
+  const uint8_t *lim;
+  const uint8_t *hev_thr;
 };
 
 #define prototype_loopfilter(sym) \
-  void sym(uint8_t *src, int pitch, const unsigned char *blimit, \
-           const unsigned char *limit, const unsigned char *thresh, int count)
+  void sym(uint8_t *src, int pitch, const uint8_t *blimit, \
+           const uint8_t *limit, const uint8_t *thresh, int count)
 
 #define prototype_loopfilter_block(sym) \
   void sym(uint8_t *y, uint8_t *u, uint8_t *v, \
@@ -53,11 +54,10 @@
 #include "x86/vp9_loopfilter_x86.h"
 #endif
 
-typedef void loop_filter_uvfunction(uint8_t *u,   /* source pointer */
-                                    int p,              /* pitch */
-                                    const unsigned char *blimit,
-                                    const unsigned char *limit,
-                                    const unsigned char *thresh,
+typedef void loop_filter_uvfunction(uint8_t *src, int pitch,
+                                    const uint8_t *blimit,
+                                    const uint8_t *limit,
+                                    const uint8_t *thresh,
                                     uint8_t *v);
 
 /* assorted loopfilter functions which get used elsewhere */
--- a/vp9/common/vp9_seg_common.c
+++ b/vp9/common/vp9_seg_common.c
@@ -13,7 +13,9 @@
 #include "vp9/common/vp9_seg_common.h"
 
 static const int seg_feature_data_signed[SEG_LVL_MAX] = { 1, 1, 0, 0 };
-static const int seg_feature_data_max[SEG_LVL_MAX] = { MAXQ, 63, 3, 0 };
+
+static const int seg_feature_data_max[SEG_LVL_MAX] = {
+  MAXQ, MAX_LOOP_FILTER, 3, 0 };
 
 // These functions provide access to new segment level features.
 // Eventually these function may be "optimized out" but for the moment,