LCOV - code coverage report
Current view: top level - third_party/aom/av1/encoder - aq_variance.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 88 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016, 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 <math.h>
      13             : 
      14             : #include "aom_ports/mem.h"
      15             : 
      16             : #include "av1/encoder/aq_variance.h"
      17             : 
      18             : #include "av1/common/seg_common.h"
      19             : #include "av1/encoder/ratectrl.h"
      20             : #include "av1/encoder/rd.h"
      21             : #include "av1/encoder/segmentation.h"
      22             : #include "aom_ports/system_state.h"
      23             : 
      24             : #define ENERGY_MIN (-4)
      25             : #define ENERGY_MAX (1)
      26             : #define ENERGY_SPAN (ENERGY_MAX - ENERGY_MIN + 1)
      27             : #define ENERGY_IN_BOUNDS(energy) \
      28             :   assert((energy) >= ENERGY_MIN && (energy) <= ENERGY_MAX)
      29             : 
      30             : static const double rate_ratio[MAX_SEGMENTS] = { 2.5,  2.0, 1.5, 1.0,
      31             :                                                  0.75, 1.0, 1.0, 1.0 };
      32             : static const int segment_id[ENERGY_SPAN] = { 0, 1, 1, 2, 3, 4 };
      33             : 
      34             : #define SEGMENT_ID(i) segment_id[(i)-ENERGY_MIN]
      35             : 
      36             : DECLARE_ALIGNED(16, static const uint8_t, av1_all_zeros[MAX_SB_SIZE]) = { 0 };
      37             : #if CONFIG_HIGHBITDEPTH
      38             : DECLARE_ALIGNED(16, static const uint16_t,
      39             :                 av1_highbd_all_zeros[MAX_SB_SIZE]) = { 0 };
      40             : #endif
      41             : 
      42           0 : unsigned int av1_vaq_segment_id(int energy) {
      43           0 :   ENERGY_IN_BOUNDS(energy);
      44           0 :   return SEGMENT_ID(energy);
      45             : }
      46             : 
      47           0 : void av1_vaq_frame_setup(AV1_COMP *cpi) {
      48           0 :   AV1_COMMON *cm = &cpi->common;
      49           0 :   struct segmentation *seg = &cm->seg;
      50             :   int i;
      51             : 
      52           0 :   if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
      53           0 :       cpi->refresh_alt_ref_frame ||
      54           0 :       (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) {
      55           0 :     cpi->vaq_refresh = 1;
      56             : 
      57           0 :     av1_enable_segmentation(seg);
      58           0 :     av1_clearall_segfeatures(seg);
      59             : 
      60           0 :     seg->abs_delta = SEGMENT_DELTADATA;
      61             : 
      62           0 :     aom_clear_system_state();
      63             : 
      64           0 :     for (i = 0; i < MAX_SEGMENTS; ++i) {
      65           0 :       int qindex_delta =
      66           0 :           av1_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, cm->base_qindex,
      67             :                                      rate_ratio[i], cm->bit_depth);
      68             : 
      69             :       // We don't allow qindex 0 in a segment if the base value is not 0.
      70             :       // Q index 0 (lossless) implies 4x4 encoding only and in AQ mode a segment
      71             :       // Q delta is sometimes applied without going back around the rd loop.
      72             :       // This could lead to an illegal combination of partition size and q.
      73           0 :       if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) {
      74           0 :         qindex_delta = -cm->base_qindex + 1;
      75             :       }
      76             : 
      77             :       // No need to enable SEG_LVL_ALT_Q for this segment.
      78           0 :       if (rate_ratio[i] == 1.0) {
      79           0 :         continue;
      80             :       }
      81             : 
      82           0 :       av1_set_segdata(seg, i, SEG_LVL_ALT_Q, qindex_delta);
      83           0 :       av1_enable_segfeature(seg, i, SEG_LVL_ALT_Q);
      84             :     }
      85             :   }
      86           0 : }
      87             : 
      88             : /* TODO(agrange, paulwilkins): The block_variance calls the unoptimized versions
      89             :  * of variance() and highbd_8_variance(). It should not.
      90             :  */
      91           0 : static void aq_variance(const uint8_t *a, int a_stride, const uint8_t *b,
      92             :                         int b_stride, int w, int h, unsigned int *sse,
      93             :                         int *sum) {
      94             :   int i, j;
      95             : 
      96           0 :   *sum = 0;
      97           0 :   *sse = 0;
      98             : 
      99           0 :   for (i = 0; i < h; i++) {
     100           0 :     for (j = 0; j < w; j++) {
     101           0 :       const int diff = a[j] - b[j];
     102           0 :       *sum += diff;
     103           0 :       *sse += diff * diff;
     104             :     }
     105             : 
     106           0 :     a += a_stride;
     107           0 :     b += b_stride;
     108             :   }
     109           0 : }
     110             : 
     111             : #if CONFIG_HIGHBITDEPTH
     112           0 : static void aq_highbd_variance64(const uint8_t *a8, int a_stride,
     113             :                                  const uint8_t *b8, int b_stride, int w, int h,
     114             :                                  uint64_t *sse, uint64_t *sum) {
     115             :   int i, j;
     116             : 
     117           0 :   uint16_t *a = CONVERT_TO_SHORTPTR(a8);
     118           0 :   uint16_t *b = CONVERT_TO_SHORTPTR(b8);
     119           0 :   *sum = 0;
     120           0 :   *sse = 0;
     121             : 
     122           0 :   for (i = 0; i < h; i++) {
     123           0 :     for (j = 0; j < w; j++) {
     124           0 :       const int diff = a[j] - b[j];
     125           0 :       *sum += diff;
     126           0 :       *sse += diff * diff;
     127             :     }
     128           0 :     a += a_stride;
     129           0 :     b += b_stride;
     130             :   }
     131           0 : }
     132             : 
     133           0 : static void aq_highbd_8_variance(const uint8_t *a8, int a_stride,
     134             :                                  const uint8_t *b8, int b_stride, int w, int h,
     135             :                                  unsigned int *sse, int *sum) {
     136           0 :   uint64_t sse_long = 0;
     137           0 :   uint64_t sum_long = 0;
     138           0 :   aq_highbd_variance64(a8, a_stride, b8, b_stride, w, h, &sse_long, &sum_long);
     139           0 :   *sse = (unsigned int)sse_long;
     140           0 :   *sum = (int)sum_long;
     141           0 : }
     142             : #endif  // CONFIG_HIGHBITDEPTH
     143             : 
     144           0 : static unsigned int block_variance(const AV1_COMP *const cpi, MACROBLOCK *x,
     145             :                                    BLOCK_SIZE bs) {
     146           0 :   MACROBLOCKD *xd = &x->e_mbd;
     147             :   unsigned int var, sse;
     148           0 :   int right_overflow =
     149           0 :       (xd->mb_to_right_edge < 0) ? ((-xd->mb_to_right_edge) >> 3) : 0;
     150           0 :   int bottom_overflow =
     151           0 :       (xd->mb_to_bottom_edge < 0) ? ((-xd->mb_to_bottom_edge) >> 3) : 0;
     152             : 
     153           0 :   if (right_overflow || bottom_overflow) {
     154           0 :     const int bw = 8 * mi_size_wide[bs] - right_overflow;
     155           0 :     const int bh = 8 * mi_size_high[bs] - bottom_overflow;
     156             :     int avg;
     157             : #if CONFIG_HIGHBITDEPTH
     158           0 :     if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
     159           0 :       aq_highbd_8_variance(x->plane[0].src.buf, x->plane[0].src.stride,
     160           0 :                            CONVERT_TO_BYTEPTR(av1_highbd_all_zeros), 0, bw, bh,
     161             :                            &sse, &avg);
     162           0 :       sse >>= 2 * (xd->bd - 8);
     163           0 :       avg >>= (xd->bd - 8);
     164             :     } else {
     165           0 :       aq_variance(x->plane[0].src.buf, x->plane[0].src.stride, av1_all_zeros, 0,
     166             :                   bw, bh, &sse, &avg);
     167             :     }
     168             : #else
     169             :     aq_variance(x->plane[0].src.buf, x->plane[0].src.stride, av1_all_zeros, 0,
     170             :                 bw, bh, &sse, &avg);
     171             : #endif  // CONFIG_HIGHBITDEPTH
     172           0 :     var = sse - (unsigned int)(((int64_t)avg * avg) / (bw * bh));
     173           0 :     return (unsigned int)((uint64_t)var * 256) / (bw * bh);
     174             :   } else {
     175             : #if CONFIG_HIGHBITDEPTH
     176           0 :     if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
     177           0 :       var =
     178           0 :           cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride,
     179           0 :                              CONVERT_TO_BYTEPTR(av1_highbd_all_zeros), 0, &sse);
     180             :     } else {
     181           0 :       var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride,
     182             :                                av1_all_zeros, 0, &sse);
     183             :     }
     184             : #else
     185             :     var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride,
     186             :                              av1_all_zeros, 0, &sse);
     187             : #endif  // CONFIG_HIGHBITDEPTH
     188           0 :     return (unsigned int)((uint64_t)var * 256) >> num_pels_log2_lookup[bs];
     189             :   }
     190             : }
     191             : 
     192           0 : double av1_log_block_var(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs) {
     193           0 :   unsigned int var = block_variance(cpi, x, bs);
     194           0 :   aom_clear_system_state();
     195           0 :   return log(var + 1.0);
     196             : }
     197             : 
     198             : #define DEFAULT_E_MIDPOINT 10.0
     199           0 : int av1_block_energy(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs) {
     200             :   double energy;
     201             :   double energy_midpoint;
     202           0 :   aom_clear_system_state();
     203           0 :   energy_midpoint =
     204           0 :       (cpi->oxcf.pass == 2) ? cpi->twopass.mb_av_energy : DEFAULT_E_MIDPOINT;
     205           0 :   energy = av1_log_block_var(cpi, x, bs) - energy_midpoint;
     206           0 :   return clamp((int)round(energy), ENERGY_MIN, ENERGY_MAX);
     207             : }

Generated by: LCOV version 1.13