Home | History | Annotate | Download | only in encoder
      1 /*
      2  * Copyright (c) 2018, Alliance for Open Media. All rights reserved
      3  *
      4  * This source code is subject to the terms of the BSD 2 Clause License and
      5  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
      6  * was not distributed with this source code in the LICENSE file, you can
      7  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
      8  * Media Patent License 1.0 was not distributed with this source code in the
      9  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
     10  */
     11 
     12 #include <assert.h>
     13 #include <stdlib.h>
     14 #include <math.h>
     15 
     16 #include "config/av1_rtcd.h"
     17 #include "av1/encoder/dwt.h"
     18 
     19 // Note: block length must be even for this implementation
     20 static void analysis_53_row(int length, tran_low_t *x, tran_low_t *lowpass,
     21                             tran_low_t *highpass) {
     22   int n;
     23   tran_low_t r, *a, *b;
     24 
     25   n = length >> 1;
     26   b = highpass;
     27   a = lowpass;
     28   while (--n) {
     29     *a++ = (r = *x++) * 2;
     30     *b++ = *x - ((r + x[1] + 1) >> 1);
     31     x++;
     32   }
     33   *a = (r = *x++) * 2;
     34   *b = *x - r;
     35 
     36   n = length >> 1;
     37   b = highpass;
     38   a = lowpass;
     39   r = *highpass;
     40   while (n--) {
     41     *a++ += (r + (*b) + 1) >> 1;
     42     r = *b++;
     43   }
     44 }
     45 
     46 static void analysis_53_col(int length, tran_low_t *x, tran_low_t *lowpass,
     47                             tran_low_t *highpass) {
     48   int n;
     49   tran_low_t r, *a, *b;
     50 
     51   n = length >> 1;
     52   b = highpass;
     53   a = lowpass;
     54   while (--n) {
     55     *a++ = (r = *x++);
     56     *b++ = (((*x) * 2) - (r + x[1]) + 2) >> 2;
     57     x++;
     58   }
     59   *a = (r = *x++);
     60   *b = (*x - r + 1) >> 1;
     61 
     62   n = length >> 1;
     63   b = highpass;
     64   a = lowpass;
     65   r = *highpass;
     66   while (n--) {
     67     *a++ += (r + (*b) + 1) >> 1;
     68     r = *b++;
     69   }
     70 }
     71 
     72 static void dyadic_analyze_53_uint8_input(int levels, int width, int height,
     73                                           uint8_t *x, int pitch_x,
     74                                           tran_low_t *c, int pitch_c,
     75                                           int dwt_scale_bits, int hbd) {
     76   int lv, i, j, nh, nw, hh = height, hw = width;
     77   tran_low_t buffer[2 * DWT_MAX_LENGTH];
     78 
     79   if (hbd) {
     80     uint16_t *x16 = CONVERT_TO_SHORTPTR(x);
     81     for (i = 0; i < height; i++) {
     82       for (j = 0; j < width; j++) {
     83         c[i * pitch_c + j] = x16[i * pitch_x + j] << dwt_scale_bits;
     84       }
     85     }
     86   } else {
     87     for (i = 0; i < height; i++) {
     88       for (j = 0; j < width; j++) {
     89         c[i * pitch_c + j] = x[i * pitch_x + j] << dwt_scale_bits;
     90       }
     91     }
     92   }
     93 
     94   for (lv = 0; lv < levels; lv++) {
     95     nh = hh;
     96     hh = (hh + 1) >> 1;
     97     nw = hw;
     98     hw = (hw + 1) >> 1;
     99     if ((nh < 2) || (nw < 2)) return;
    100     for (i = 0; i < nh; i++) {
    101       memcpy(buffer, &c[i * pitch_c], nw * sizeof(tran_low_t));
    102       analysis_53_row(nw, buffer, &c[i * pitch_c], &c[i * pitch_c] + hw);
    103     }
    104     for (j = 0; j < nw; j++) {
    105       for (i = 0; i < nh; i++) buffer[i + nh] = c[i * pitch_c + j];
    106       analysis_53_col(nh, buffer + nh, buffer, buffer + hh);
    107       for (i = 0; i < nh; i++) c[i * pitch_c + j] = buffer[i];
    108     }
    109   }
    110 }
    111 
    112 void av1_fdwt8x8_uint8_input_c(uint8_t *input, tran_low_t *output, int stride,
    113                                int hbd) {
    114   dyadic_analyze_53_uint8_input(4, 8, 8, input, stride, output, 8, 2, hbd);
    115 }
    116 
    117 int av1_haar_ac_sad(tran_low_t *output, int bw, int bh, int stride) {
    118   int acsad = 0;
    119 
    120   for (int r = 0; r < bh; ++r)
    121     for (int c = 0; c < bw; ++c) {
    122       if (r >= bh / 2 || c >= bw / 2) acsad += abs(output[r * stride + c]);
    123     }
    124   return acsad;
    125 }
    126 
    127 uint64_t av1_dct_ac_sad(tran_low_t *output, int bw, int bh, int stride) {
    128   uint64_t acsad = 0;
    129 
    130   for (int r = 0; r < bh; ++r)
    131     for (int c = 0; c < bw; ++c) {
    132       if (r > 0 || c > 0) acsad += abs(output[r * stride + c]);
    133     }
    134 
    135   return acsad;
    136 }
    137 
    138 uint32_t av1_variance(uint8_t *input, int bw, int bh, int stride) {
    139   int sum = 0;
    140   uint32_t sse = 0;
    141 
    142   for (int r = 0; r < bh; ++r)
    143     for (int c = 0; c < bw; ++c) {
    144       sum += input[r * stride + c];
    145       sse += input[r * stride + c] * input[r * stride + c];
    146     }
    147   return sse - (uint32_t)(((int64_t)sum * sum) / (bw * bh));
    148 }
    149 
    150 int av1_haar_ac_sad_8x8_uint8_input(uint8_t *input, int stride, int hbd) {
    151   tran_low_t output[64];
    152 
    153   av1_fdwt8x8_uint8_input_c(input, output, stride, hbd);
    154   return av1_haar_ac_sad(output, 8, 8, 8);
    155 }
    156