LCOV - code coverage report
Current view: top level - Codec - EbPsnr.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 39 137 28.5 %
Date: 2019-11-25 17:38:06 Functions: 5 20 25.0 %

          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 "EbDefinitions.h"
      13             : #include <assert.h>
      14             : #include <math.h>
      15             : #include "EbPsnr.h"
      16             : #include "EbPictureBufferDesc.h"
      17             : #include "aom_dsp_rtcd.h"
      18             : 
      19           0 : double eb_aom_sse_to_psnr(double samples, double peak, double sse) {
      20           0 :     if (sse > 0.0) {
      21           0 :         const double psnr = 10.0 * log10(samples * peak * peak / sse);
      22           0 :         return psnr > MAX_PSNR ? MAX_PSNR : psnr;
      23             :     }
      24             :     else
      25           0 :         return MAX_PSNR;
      26             : }
      27             : 
      28             : /* TODO(yaowu): The block_variance calls the unoptimized versions of variance()
      29             :  * and highbd_8_variance(). It should not.
      30             :  */
      31        9645 : static int32_t encoder_variance(const uint8_t *a, int32_t a_stride, const uint8_t *b,
      32             :     int32_t b_stride, int32_t w, int32_t h) {
      33             :     int32_t i, j;
      34        9645 :     int32_t sse = 0;
      35             : 
      36       74400 :     for (i = 0; i < h; i++) {
      37    15134400 :         for (j = 0; j < w; j++) {
      38    15069600 :             const int32_t diff = a[j] - b[j];
      39    15069600 :             sse += diff * diff;
      40             :         }
      41             : 
      42       64755 :         a += a_stride;
      43       64755 :         b += b_stride;
      44             :     }
      45        9645 :     return sse;
      46             : }
      47             : 
      48           0 : static int64_t encoder_highbd_variance64(const uint8_t *a8, int32_t a_stride,
      49             :     const uint8_t *b8, int32_t b_stride, int32_t w, int32_t h) {
      50           0 :     const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
      51           0 :     const uint16_t *b = CONVERT_TO_SHORTPTR(b8);
      52           0 :     int64_t sse = 0;
      53           0 :     for (int32_t i = 0; i < h; ++i) {
      54           0 :         for (int32_t j = 0; j < w; ++j) {
      55           0 :             const int32_t diff = a[j] - b[j];
      56           0 :             sse += (uint32_t)(diff * diff);
      57             :         }
      58           0 :         a += a_stride;
      59           0 :         b += b_stride;
      60             :     }
      61           0 :     return sse;
      62             : }
      63             : 
      64           0 : static void encoder_highbd_8_variance(const uint8_t *a8, int32_t a_stride,
      65             :     const uint8_t *b8, int32_t b_stride, int32_t w,
      66             :     int32_t h, uint32_t *sse) {
      67           0 :     *sse = (uint32_t)encoder_highbd_variance64(a8, a_stride, b8, b_stride, w, h);
      68           0 : }
      69             : 
      70           0 : static void variance(const uint8_t *a, int32_t a_stride, const uint8_t *b,
      71             :     int b_stride, int w, int h, uint32_t *sse, int32_t *sum) {
      72             :     int i, j;
      73             : 
      74           0 :     *sum = 0;
      75           0 :     *sse = 0;
      76             : 
      77           0 :     for (i = 0; i < h; ++i) {
      78           0 :         for (j = 0; j < w; ++j) {
      79           0 :             const int32_t diff = a[j] - b[j];
      80           0 :             *sum += diff;
      81           0 :             *sse += diff * diff;
      82             :         }
      83             : 
      84           0 :         a += a_stride;
      85           0 :         b += b_stride;
      86             :     }
      87           0 : }
      88             : 
      89           0 : uint32_t eb_aom_mse16x16_c(const uint8_t *src_ptr, int32_t  source_stride,
      90             :     const uint8_t *ref_ptr, int32_t  recon_stride, uint32_t *sse){
      91             :     int32_t sum;
      92           0 :     variance(src_ptr, source_stride, ref_ptr, recon_stride,16, 16, sse, &sum);
      93           0 :     return *sse - (uint32_t)(((int64_t)sum * sum) / (16 * 16));
      94             : }
      95             : 
      96        9645 : static int64_t get_sse(const uint8_t *a, int32_t a_stride, const uint8_t *b,
      97             :     int32_t b_stride, int32_t width, int32_t height) {
      98        9645 :     const int32_t dw = width % 16;
      99        9645 :     const int32_t dh = height % 16;
     100        9645 :     int64_t total_sse = 0;
     101        9645 :     uint32_t sse = 0;
     102             :     int32_t x, y;
     103             : 
     104        9645 :     if (dw > 0) {
     105           0 :         sse = encoder_variance(&a[width - dw], a_stride, &b[width - dw], b_stride, dw,
     106             :             height);
     107           0 :         total_sse += sse;
     108             :     }
     109             : 
     110        9645 :     if (dh > 0) {
     111       19290 :         sse = encoder_variance(&a[(height - dh) * a_stride], a_stride,
     112        9645 :             &b[(height - dh) * b_stride], b_stride, width - dw, dh);
     113        9645 :         total_sse += sse;
     114             :     }
     115             : 
     116      187722 :     for (y = 0; y < height / 16; ++y) {
     117      178075 :         const uint8_t *pa = a;
     118      178075 :         const uint8_t *pb = b;
     119     2767680 :         for (x = 0; x < width / 16; ++x) {
     120     2589600 :             eb_aom_mse16x16(pa, a_stride, pb, b_stride, &sse);
     121             : 
     122     2589600 :             total_sse += sse;
     123             : 
     124     2589600 :             pa += 16;
     125     2589600 :             pb += 16;
     126             :         }
     127             : 
     128      178077 :         a += 16 * a_stride;
     129      178077 :         b += 16 * b_stride;
     130             :     }
     131             : 
     132        9647 :     return total_sse;
     133             : }
     134             : 
     135           0 : static int64_t highbd_get_sse(const uint8_t *a, int32_t a_stride, const uint8_t *b,
     136             :     int32_t b_stride, int32_t width, int32_t height) {
     137           0 :     int64_t total_sse = 0;
     138             :     int32_t x, y;
     139           0 :     const int32_t dw = width % 16;
     140           0 :     const int32_t dh = height % 16;
     141           0 :     uint32_t sse = 0;
     142           0 :     if (dw > 0) {
     143           0 :         encoder_highbd_8_variance(&a[width - dw], a_stride, &b[width - dw],
     144             :             b_stride, dw, height, &sse);
     145           0 :         total_sse += sse;
     146             :     }
     147           0 :     if (dh > 0) {
     148           0 :         encoder_highbd_8_variance(&a[(height - dh) * a_stride], a_stride,
     149           0 :             &b[(height - dh) * b_stride], b_stride,
     150             :             width - dw, dh, &sse);
     151           0 :         total_sse += sse;
     152             :     }
     153           0 :     for (y = 0; y < height / 16; ++y) {
     154           0 :         const uint8_t *pa = a;
     155           0 :         const uint8_t *pb = b;
     156           0 :         for (x = 0; x < width / 16; ++x) {
     157           0 :             eb_aom_highbd_8_mse16x16(pa, a_stride, pb, b_stride, &sse);
     158             : 
     159           0 :             total_sse += sse;
     160           0 :             pa += 16;
     161           0 :             pb += 16;
     162             :         }
     163           0 :         a += 16 * a_stride;
     164           0 :         b += 16 * b_stride;
     165             :     }
     166           0 :     return total_sse;
     167             : }
     168             : 
     169        6544 : int64_t eb_aom_get_y_sse_part(const Yv12BufferConfig *a,
     170             :     const Yv12BufferConfig *b, int32_t hstart, int32_t width,
     171             :     int32_t vstart, int32_t height) {
     172       13088 :     return get_sse(a->y_buffer + vstart * a->y_stride + hstart, a->y_stride,
     173        6544 :         b->y_buffer + vstart * b->y_stride + hstart, b->y_stride,
     174             :         width, height);
     175             : }
     176             : 
     177           0 : int64_t eb_aom_get_y_sse(const Yv12BufferConfig *a,
     178             :     const Yv12BufferConfig *b) {
     179           0 :     assert(a->y_crop_width == b->y_crop_width);
     180           0 :     assert(a->y_crop_height == b->y_crop_height);
     181             : 
     182           0 :     return get_sse(a->y_buffer, a->y_stride, b->y_buffer, b->y_stride,
     183             :         a->y_crop_width, a->y_crop_height);
     184             : }
     185             : 
     186        1555 : int64_t eb_aom_get_u_sse_part(const Yv12BufferConfig *a,
     187             :     const Yv12BufferConfig *b, int32_t hstart, int32_t width,
     188             :     int32_t vstart, int32_t height) {
     189        3110 :     return get_sse(a->u_buffer + vstart * a->uv_stride + hstart, a->uv_stride,
     190        1555 :         b->u_buffer + vstart * b->uv_stride + hstart, b->uv_stride,
     191             :         width, height);
     192             : }
     193             : 
     194           0 : int64_t eb_aom_get_u_sse(const Yv12BufferConfig *a,
     195             :     const Yv12BufferConfig *b) {
     196           0 :     assert(a->uv_crop_width == b->uv_crop_width);
     197           0 :     assert(a->uv_crop_height == b->uv_crop_height);
     198             : 
     199           0 :     return get_sse(a->u_buffer, a->uv_stride, b->u_buffer, b->uv_stride,
     200             :         a->uv_crop_width, a->uv_crop_height);
     201             : }
     202             : 
     203        1546 : int64_t eb_aom_get_v_sse_part(const Yv12BufferConfig *a,
     204             :     const Yv12BufferConfig *b, int32_t hstart, int32_t width,
     205             :     int32_t vstart, int32_t height) {
     206        3092 :     return get_sse(a->v_buffer + vstart * a->uv_stride + hstart, a->uv_stride,
     207        1546 :         b->v_buffer + vstart * b->uv_stride + hstart, b->uv_stride,
     208             :         width, height);
     209             : }
     210             : 
     211           0 : int64_t eb_aom_get_v_sse(const Yv12BufferConfig *a,
     212             :     const Yv12BufferConfig *b) {
     213           0 :     assert(a->uv_crop_width == b->uv_crop_width);
     214           0 :     assert(a->uv_crop_height == b->uv_crop_height);
     215             : 
     216           0 :     return get_sse(a->v_buffer, a->uv_stride, b->v_buffer, b->uv_stride,
     217             :         a->uv_crop_width, a->uv_crop_height);
     218             : }
     219             : 
     220           0 : int64_t eb_aom_highbd_get_y_sse_part(const Yv12BufferConfig *a,
     221             :     const Yv12BufferConfig *b, int32_t hstart,
     222             :     int32_t width, int32_t vstart, int32_t height) {
     223           0 :     return highbd_get_sse(
     224           0 :         a->y_buffer + vstart * a->y_stride + hstart, a->y_stride,
     225           0 :         b->y_buffer + vstart * b->y_stride + hstart, b->y_stride, width, height);
     226             : }
     227             : 
     228           0 : int64_t eb_aom_highbd_get_y_sse(const Yv12BufferConfig *a,
     229             :     const Yv12BufferConfig *b) {
     230           0 :     assert(a->y_crop_width == b->y_crop_width);
     231           0 :     assert(a->y_crop_height == b->y_crop_height);
     232           0 :     assert((a->flags & YV12_FLAG_HIGHBITDEPTH) != 0);
     233           0 :     assert((b->flags & YV12_FLAG_HIGHBITDEPTH) != 0);
     234             : 
     235           0 :     return highbd_get_sse(a->y_buffer, a->y_stride, b->y_buffer, b->y_stride,
     236             :         a->y_crop_width, a->y_crop_height);
     237             : }
     238             : 
     239           0 : int64_t eb_aom_highbd_get_u_sse_part(const Yv12BufferConfig *a,
     240             :     const Yv12BufferConfig *b, int32_t hstart,
     241             :     int32_t width, int32_t vstart, int32_t height) {
     242           0 :     return highbd_get_sse(a->u_buffer + vstart * a->uv_stride + hstart,
     243             :         a->uv_stride,
     244           0 :         b->u_buffer + vstart * b->uv_stride + hstart,
     245             :         b->uv_stride, width, height);
     246             : }
     247             : 
     248           0 : int64_t eb_aom_highbd_get_u_sse(const Yv12BufferConfig *a,
     249             :     const Yv12BufferConfig *b) {
     250           0 :     assert(a->uv_crop_width == b->uv_crop_width);
     251           0 :     assert(a->uv_crop_height == b->uv_crop_height);
     252           0 :     assert((a->flags & YV12_FLAG_HIGHBITDEPTH) != 0);
     253           0 :     assert((b->flags & YV12_FLAG_HIGHBITDEPTH) != 0);
     254             : 
     255           0 :     return highbd_get_sse(a->u_buffer, a->uv_stride, b->u_buffer, b->uv_stride,
     256             :         a->uv_crop_width, a->uv_crop_height);
     257             : }
     258             : 
     259           0 : int64_t eb_aom_highbd_get_v_sse_part(const Yv12BufferConfig *a,
     260             :     const Yv12BufferConfig *b, int32_t hstart,
     261             :     int32_t width, int32_t vstart, int32_t height) {
     262           0 :     return highbd_get_sse(a->v_buffer + vstart * a->uv_stride + hstart,
     263             :         a->uv_stride,
     264           0 :         b->v_buffer + vstart * b->uv_stride + hstart,
     265             :         b->uv_stride, width, height);
     266             : }
     267             : 
     268           0 : int64_t eb_aom_highbd_get_v_sse(const Yv12BufferConfig *a,
     269             :     const Yv12BufferConfig *b) {
     270           0 :     assert(a->uv_crop_width == b->uv_crop_width);
     271           0 :     assert(a->uv_crop_height == b->uv_crop_height);
     272           0 :     assert((a->flags & YV12_FLAG_HIGHBITDEPTH) != 0);
     273           0 :     assert((b->flags & YV12_FLAG_HIGHBITDEPTH) != 0);
     274             : 
     275           0 :     return highbd_get_sse(a->v_buffer, a->uv_stride, b->v_buffer, b->uv_stride,
     276             :         a->uv_crop_width, a->uv_crop_height);
     277             : }

Generated by: LCOV version 1.14