LCOV - code coverage report
Current view: top level - libavcodec - vc2enc_dwt.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 88 156 56.4 %
Date: 2017-12-18 13:19:42 Functions: 4 8 50.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2007 Marco Gerards <marco@gnu.org>
       3             :  * Copyright (C) 2016 Open Broadcast Systems Ltd.
       4             :  * Author        2016 Rostislav Pehlivanov <atomnuker@gmail.com>
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : #include "libavutil/attributes.h"
      24             : #include "libavutil/mem.h"
      25             : #include "vc2enc_dwt.h"
      26             : 
      27             : /* Since the transforms spit out interleaved coefficients, this function
      28             :  * rearranges the coefficients into the more traditional subdivision,
      29             :  * making it easier to encode and perform another level. */
      30        1620 : static av_always_inline void deinterleave(dwtcoef *linell, ptrdiff_t stride,
      31             :                                           int width, int height, dwtcoef *synthl)
      32             : {
      33             :     int x, y;
      34        1620 :     ptrdiff_t synthw = width << 1;
      35        1620 :     dwtcoef *linehl = linell + width;
      36        1620 :     dwtcoef *linelh = linell + height*stride;
      37        1620 :     dwtcoef *linehh = linelh + width;
      38             : 
      39             :     /* Deinterleave the coefficients. */
      40       98820 :     for (y = 0; y < height; y++) {
      41     9942750 :         for (x = 0; x < width; x++) {
      42     9845550 :             linell[x] = synthl[(x << 1)];
      43     9845550 :             linehl[x] = synthl[(x << 1) + 1];
      44     9845550 :             linelh[x] = synthl[(x << 1) + synthw];
      45     9845550 :             linehh[x] = synthl[(x << 1) + synthw + 1];
      46             :         }
      47       97200 :         synthl += synthw << 1;
      48       97200 :         linell += stride;
      49       97200 :         linelh += stride;
      50       97200 :         linehl += stride;
      51       97200 :         linehh += stride;
      52             :     }
      53        1620 : }
      54             : 
      55        1620 : static void vc2_subband_dwt_97(VC2TransformContext *t, dwtcoef *data,
      56             :                                ptrdiff_t stride, int width, int height)
      57             : {
      58             :     int x, y;
      59        1620 :     dwtcoef *datal = data, *synth = t->buffer, *synthl = synth;
      60        1620 :     const ptrdiff_t synth_width  = width  << 1;
      61        1620 :     const ptrdiff_t synth_height = height << 1;
      62             : 
      63             :     /*
      64             :      * Shift in one bit that is used for additional precision and copy
      65             :      * the data to the buffer.
      66             :      */
      67      196020 :     for (y = 0; y < synth_height; y++) {
      68    39576600 :         for (x = 0; x < synth_width; x++)
      69    39382200 :             synthl[x] = datal[x] << 1;
      70      194400 :         synthl += synth_width;
      71      194400 :         datal += stride;
      72             :     }
      73             : 
      74             :     /* Horizontal synthesis. */
      75        1620 :     synthl = synth;
      76      196020 :     for (y = 0; y < synth_height; y++) {
      77             :         /* Lifting stage 2. */
      78      194400 :         synthl[1] -= (8*synthl[0] + 9*synthl[2] - synthl[4] + 8) >> 4;
      79    19302300 :         for (x = 1; x < width - 2; x++)
      80    57323700 :             synthl[2*x + 1] -= (9*synthl[2*x] + 9*synthl[2*x + 2] - synthl[2*x + 4] -
      81    38215800 :                                 synthl[2 * x - 2] + 8) >> 4;
      82      583200 :         synthl[synth_width - 1] -= (17*synthl[synth_width - 2] -
      83      388800 :                                     synthl[synth_width - 4] + 8) >> 4;
      84      583200 :         synthl[synth_width - 3] -= (8*synthl[synth_width - 2] +
      85      388800 :                                     9*synthl[synth_width - 4] -
      86      388800 :                                     synthl[synth_width - 6] + 8) >> 4;
      87             :         /* Lifting stage 1. */
      88      194400 :         synthl[0] += (synthl[1] + synthl[1] + 2) >> 2;
      89    19496700 :         for (x = 1; x < width - 1; x++)
      90    19302300 :             synthl[2*x] += (synthl[2*x - 1] + synthl[2*x + 1] + 2) >> 2;
      91             : 
      92      583200 :         synthl[synth_width - 2] += (synthl[synth_width - 3] +
      93      388800 :                                     synthl[synth_width - 1] + 2) >> 2;
      94      194400 :         synthl += synth_width;
      95             :     }
      96             : 
      97             :     /* Vertical synthesis: Lifting stage 2. */
      98        1620 :     synthl = synth + synth_width;
      99      209520 :     for (x = 0; x < synth_width; x++)
     100      623700 :         synthl[x] -= (8*synthl[x - synth_width] + 9*synthl[x + synth_width] -
     101      415800 :                       synthl[x + 3 * synth_width] + 8) >> 4;
     102             : 
     103        1620 :     synthl = synth + (synth_width << 1);
     104       93960 :     for (y = 1; y < height - 2; y++) {
     105    19159740 :         for (x = 0; x < synth_width; x++)
     106    57202200 :             synthl[x + synth_width] -= (9*synthl[x] +
     107    38134800 :                                         9*synthl[x + 2 * synth_width] -
     108    38134800 :                                         synthl[x - 2 * synth_width] -
     109    38134800 :                                         synthl[x + 4 * synth_width] + 8) >> 4;
     110       92340 :         synthl += synth_width << 1;
     111             :     }
     112             : 
     113        1620 :     synthl = synth + (synth_height - 1) * synth_width;
     114      209520 :     for (x = 0; x < synth_width; x++) {
     115      623700 :         synthl[x] -= (17*synthl[x - synth_width] -
     116      415800 :                       synthl[x - 3*synth_width] + 8) >> 4;
     117      623700 :                       synthl[x - 2*synth_width] -= (9*synthl[x - 3*synth_width] +
     118      415800 :                       8*synthl[x - 1*synth_width] - synthl[x - 5*synth_width] + 8) >> 4;
     119             :     }
     120             : 
     121             :     /* Vertical synthesis: Lifting stage 1. */
     122        1620 :     synthl = synth;
     123      209520 :     for (x = 0; x < synth_width; x++)
     124      207900 :         synthl[x] += (synthl[x + synth_width] + synthl[x + synth_width] + 2) >> 2;
     125             : 
     126        1620 :     synthl = synth + (synth_width << 1);
     127       95580 :     for (y = 1; y < height - 1; y++) {
     128    19369260 :         for (x = 0; x < synth_width; x++)
     129    19275300 :             synthl[x] += (synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2;
     130       93960 :         synthl += synth_width << 1;
     131             :     }
     132             : 
     133        1620 :     synthl = synth + (synth_height - 2) * synth_width;
     134      209520 :     for (x = 0; x < synth_width; x++)
     135      207900 :         synthl[x] += (synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2;
     136             : 
     137        1620 :     deinterleave(data, stride, width, height, synth);
     138        1620 : }
     139             : 
     140           0 : static void vc2_subband_dwt_53(VC2TransformContext *t, dwtcoef *data,
     141             :                                ptrdiff_t stride, int width, int height)
     142             : {
     143             :     int x, y;
     144           0 :     dwtcoef *synth = t->buffer, *synthl = synth, *datal = data;
     145           0 :     const ptrdiff_t synth_width  = width  << 1;
     146           0 :     const ptrdiff_t synth_height = height << 1;
     147             : 
     148             :     /*
     149             :      * Shift in one bit that is used for additional precision and copy
     150             :      * the data to the buffer.
     151             :      */
     152           0 :     for (y = 0; y < synth_height; y++) {
     153           0 :         for (x = 0; x < synth_width; x++)
     154           0 :             synthl[x] = datal[x] << 1;
     155           0 :         synthl += synth_width;
     156           0 :         datal  += stride;
     157             :     }
     158             : 
     159             :     /* Horizontal synthesis. */
     160           0 :     synthl = synth;
     161           0 :     for (y = 0; y < synth_height; y++) {
     162             :         /* Lifting stage 2. */
     163           0 :         for (x = 0; x < width - 1; x++)
     164           0 :             synthl[2 * x + 1] -= (synthl[2 * x] + synthl[2 * x + 2] + 1) >> 1;
     165             : 
     166           0 :         synthl[synth_width - 1] -= (2*synthl[synth_width - 2] + 1) >> 1;
     167             : 
     168             :         /* Lifting stage 1. */
     169           0 :         synthl[0] += (2*synthl[1] + 2) >> 2;
     170           0 :         for (x = 1; x < width - 1; x++)
     171           0 :             synthl[2 * x] += (synthl[2 * x - 1] + synthl[2 * x + 1] + 2) >> 2;
     172             : 
     173           0 :         synthl[synth_width - 2] += (synthl[synth_width - 3] + synthl[synth_width - 1] + 2) >> 2;
     174             : 
     175           0 :         synthl += synth_width;
     176             :     }
     177             : 
     178             :     /* Vertical synthesis: Lifting stage 2. */
     179           0 :     synthl = synth + synth_width;
     180           0 :     for (x = 0; x < synth_width; x++)
     181           0 :         synthl[x] -= (synthl[x - synth_width] + synthl[x + synth_width] + 1) >> 1;
     182             : 
     183           0 :     synthl = synth + (synth_width << 1);
     184           0 :     for (y = 1; y < height - 1; y++) {
     185           0 :         for (x = 0; x < synth_width; x++)
     186           0 :             synthl[x + synth_width] -= (synthl[x] + synthl[x + synth_width * 2] + 1) >> 1;
     187           0 :         synthl += (synth_width << 1);
     188             :     }
     189             : 
     190           0 :     synthl = synth + (synth_height - 1) * synth_width;
     191           0 :     for (x = 0; x < synth_width; x++)
     192           0 :         synthl[x] -= (2*synthl[x - synth_width] + 1) >> 1;
     193             : 
     194             :     /* Vertical synthesis: Lifting stage 1. */
     195           0 :     synthl = synth;
     196           0 :     for (x = 0; x < synth_width; x++)
     197           0 :         synthl[x] += (2*synthl[synth_width + x] + 2) >> 2;
     198             : 
     199           0 :     synthl = synth + (synth_width << 1);
     200           0 :     for (y = 1; y < height - 1; y++) {
     201           0 :         for (x = 0; x < synth_width; x++)
     202           0 :             synthl[x] += (synthl[x + synth_width] + synthl[x - synth_width] + 2) >> 2;
     203           0 :         synthl += (synth_width << 1);
     204             :     }
     205             : 
     206           0 :     synthl = synth + (synth_height - 2)*synth_width;
     207           0 :     for (x = 0; x < synth_width; x++)
     208           0 :         synthl[x] += (synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2;
     209             : 
     210             : 
     211           0 :     deinterleave(data, stride, width, height, synth);
     212           0 : }
     213             : 
     214           0 : static av_always_inline void dwt_haar(VC2TransformContext *t, dwtcoef *data,
     215             :                                       ptrdiff_t stride, int width, int height,
     216             :                                       const int s)
     217             : {
     218             :     int x, y;
     219           0 :     dwtcoef *synth = t->buffer, *synthl = synth, *datal = data;
     220           0 :     const ptrdiff_t synth_width  = width  << 1;
     221           0 :     const ptrdiff_t synth_height = height << 1;
     222             : 
     223             :     /* Horizontal synthesis. */
     224           0 :     for (y = 0; y < synth_height; y++) {
     225           0 :         for (x = 0; x < synth_width; x += 2) {
     226           0 :             synthl[y*synth_width + x + 1] = (datal[y*stride + x + 1] << s) -
     227           0 :                                             (datal[y*stride + x] << s);
     228           0 :             synthl[y*synth_width + x] = (datal[y*stride + x + 0] << s) +
     229           0 :                                         ((synthl[y*synth_width + x + 1] + 1) >> 1);
     230             :         }
     231             :     }
     232             : 
     233             :     /* Vertical synthesis. */
     234           0 :     for (x = 0; x < synth_width; x++) {
     235           0 :         for (y = 0; y < synth_height; y += 2) {
     236           0 :             synthl[(y + 1)*synth_width + x] = synthl[(y + 1)*synth_width + x] -
     237           0 :                                               synthl[y*synth_width + x];
     238           0 :             synthl[y*synth_width + x] = synthl[y*synth_width + x] +
     239           0 :                                         ((synthl[(y + 1)*synth_width + x] + 1) >> 1);
     240             :         }
     241             :     }
     242             : 
     243           0 :     deinterleave(data, stride, width, height, synth);
     244           0 : }
     245             : 
     246           0 : static void vc2_subband_dwt_haar(VC2TransformContext *t, dwtcoef *data,
     247             :                                  ptrdiff_t stride, int width, int height)
     248             : {
     249           0 :     dwt_haar(t, data, stride, width, height, 0);
     250           0 : }
     251             : 
     252           0 : static void vc2_subband_dwt_haar_shift(VC2TransformContext *t, dwtcoef *data,
     253             :                                        ptrdiff_t stride, int width, int height)
     254             : {
     255           0 :     dwt_haar(t, data, stride, width, height, 1);
     256           0 : }
     257             : 
     258          81 : av_cold int ff_vc2enc_init_transforms(VC2TransformContext *s, int p_stride,
     259             :                                       int p_height, int slice_w, int slice_h)
     260             : {
     261          81 :     s->vc2_subband_dwt[VC2_TRANSFORM_9_7]    = vc2_subband_dwt_97;
     262          81 :     s->vc2_subband_dwt[VC2_TRANSFORM_5_3]    = vc2_subband_dwt_53;
     263          81 :     s->vc2_subband_dwt[VC2_TRANSFORM_HAAR]   = vc2_subband_dwt_haar;
     264          81 :     s->vc2_subband_dwt[VC2_TRANSFORM_HAAR_S] = vc2_subband_dwt_haar_shift;
     265             : 
     266             :     /* Pad by the slice size, only matters for non-Haar wavelets */
     267          81 :     s->buffer = av_calloc((p_stride + slice_w)*(p_height + slice_h), sizeof(dwtcoef));
     268          81 :     if (!s->buffer)
     269           0 :         return 1;
     270             : 
     271          81 :     s->padding = (slice_h >> 1)*p_stride + (slice_w >> 1);
     272          81 :     s->buffer += s->padding;
     273             : 
     274          81 :     return 0;
     275             : }
     276             : 
     277          81 : av_cold void ff_vc2enc_free_transforms(VC2TransformContext *s)
     278             : {
     279          81 :     av_free(s->buffer - s->padding);
     280          81 :     s->buffer = NULL;
     281          81 : }

Generated by: LCOV version 1.13