LCOV - code coverage report
Current view: top level - libavcodec - dirac_vlc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 128 129 99.2 %
Date: 2017-12-16 21:16:39 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2016 Open Broadcast Systems Ltd.
       3             :  * Author        2016 Rostislav Pehlivanov <rpehlivanov@obe.tv>
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : #include "dirac_vlc.h"
      23             : 
      24             : #define LUT_SIZE   (1 << LUT_BITS)
      25             : #define RSIZE_BITS (CHAR_BIT*sizeof(residual))
      26             : 
      27             : #define CONVERT_TO_RESIDUE(a, b)                                               \
      28             :     (((residual)(a)) << (RSIZE_BITS - (b)))
      29             : 
      30             : #define INIT_RESIDUE(N)                                                        \
      31             :     residual N = 0;                                                            \
      32             :     av_unused int32_t N ## _bits  = 0
      33             : 
      34             : #define SET_RESIDUE(N, I, B)                                                   \
      35             :     N          = CONVERT_TO_RESIDUE(I, B);                                     \
      36             :     N ## _bits = B
      37             : 
      38             : #define APPEND_RESIDUE(N, M)                                                   \
      39             :     N          |= M >> (N ## _bits);                                           \
      40             :     N ## _bits  = (N ## _bits + (M ## _bits)) & 0x3F
      41             : 
      42       64152 : int ff_dirac_golomb_read_32bit(DiracGolombLUT *lut_ctx, const uint8_t *buf,
      43             :                                int bytes, uint8_t *_dst, int coeffs)
      44             : {
      45       64152 :     int i, b, c_idx = 0;
      46       64152 :     int32_t *dst = (int32_t *)_dst;
      47       64152 :     DiracGolombLUT *future[4], *l = &lut_ctx[2*LUT_SIZE + buf[0]];
      48       64152 :     INIT_RESIDUE(res);
      49             : 
      50    30259412 :     for (b = 1; b <= bytes; b++) {
      51    30259122 :         future[0] = &lut_ctx[buf[b]];
      52    30259122 :         future[1] = future[0] + 1*LUT_SIZE;
      53    30259122 :         future[2] = future[0] + 2*LUT_SIZE;
      54    30259122 :         future[3] = future[0] + 3*LUT_SIZE;
      55             : 
      56    30259122 :         if ((c_idx + 1) > coeffs)
      57       63862 :             return c_idx;
      58             : 
      59             :         /* res_bits is a hint for better branch prediction */
      60    30195260 :         if (res_bits && l->sign) {
      61    18557443 :             int32_t coeff = 1;
      62    18557443 :             APPEND_RESIDUE(res, l->preamble);
      63   109969756 :             for (i = 0; i < (res_bits >> 1) - 1; i++) {
      64    91412313 :                 coeff <<= 1;
      65    91412313 :                 coeff |= (res >> (RSIZE_BITS - 2*i - 2)) & 1;
      66             :             }
      67    18557443 :             dst[c_idx++] = l->sign * (coeff - 1);
      68    18557443 :             res_bits = res = 0;
      69             :         }
      70             : 
      71    30195260 :         memcpy(&dst[c_idx], l->ready, LUT_BITS*sizeof(int32_t));
      72    30195260 :         c_idx += l->ready_num;
      73             : 
      74    30195260 :         APPEND_RESIDUE(res, l->leftover);
      75             : 
      76    30195260 :         l = future[l->need_s ? 3 : !res_bits ? 2 : res_bits & 1];
      77             :     }
      78             : 
      79         290 :     return c_idx;
      80             : }
      81             : 
      82       32076 : int ff_dirac_golomb_read_16bit(DiracGolombLUT *lut_ctx, const uint8_t *buf,
      83             :                                int bytes, uint8_t *_dst, int coeffs)
      84             : {
      85       32076 :     int i, b, c_idx = 0;
      86       32076 :     int16_t *dst = (int16_t *)_dst;
      87       32076 :     DiracGolombLUT *future[4], *l = &lut_ctx[2*LUT_SIZE + buf[0]];
      88       32076 :     INIT_RESIDUE(res);
      89             : 
      90     8864044 :     for (b = 1; b <= bytes; b++) {
      91     8863882 :         future[0] = &lut_ctx[buf[b]];
      92     8863882 :         future[1] = future[0] + 1*LUT_SIZE;
      93     8863882 :         future[2] = future[0] + 2*LUT_SIZE;
      94     8863882 :         future[3] = future[0] + 3*LUT_SIZE;
      95             : 
      96     8863882 :         if ((c_idx + 1) > coeffs)
      97       31914 :             return c_idx;
      98             : 
      99     8831968 :         if (res_bits && l->sign) {
     100     6215465 :             int32_t coeff = 1;
     101     6215465 :             APPEND_RESIDUE(res, l->preamble);
     102    26090422 :             for (i = 0; i < (res_bits >> 1) - 1; i++) {
     103    19874957 :                 coeff <<= 1;
     104    19874957 :                 coeff |= (res >> (RSIZE_BITS - 2*i - 2)) & 1;
     105             :             }
     106     6215465 :             dst[c_idx++] = l->sign * (coeff - 1);
     107     6215465 :             res_bits = res = 0;
     108             :         }
     109             : 
     110    79487712 :         for (i = 0; i < LUT_BITS; i++)
     111    70655744 :             dst[c_idx + i] = l->ready[i];
     112     8831968 :         c_idx += l->ready_num;
     113             : 
     114     8831968 :         APPEND_RESIDUE(res, l->leftover);
     115             : 
     116     8831968 :         l = future[l->need_s ? 3 : !res_bits ? 2 : res_bits & 1];
     117             :     }
     118             : 
     119         162 :     return c_idx;
     120             : }
     121             : 
     122             : /* Searches for golomb codes in a residue */
     123       56608 : static inline void search_for_golomb(DiracGolombLUT *l, residual r, int bits)
     124             : {
     125       56608 :     int r_count = RSIZE_BITS - 1;
     126       56608 :     int bits_start, bits_tot = bits, need_sign = 0;
     127             : 
     128             : #define READ_BIT(N) (((N) >> (N ## _count--)) & 1)
     129             : 
     130       83868 :     while (1) {
     131      140476 :         int32_t coef = 1;
     132      140476 :         bits_start = (RSIZE_BITS - 1) - r_count;
     133             : 
     134             :         while (1) {
     135      322596 :             if (!bits--)
     136       16588 :                 goto leftover;
     137      214948 :             if (READ_BIT(r))
     138      107474 :                 break;
     139             : 
     140      107474 :             coef <<= 1;
     141             : 
     142      107474 :             if (!bits--)
     143       16414 :                 goto leftover;
     144       91060 :             coef |= READ_BIT(r);
     145             :         }
     146             : 
     147      107474 :         l->ready[l->ready_num] = coef - 1;
     148      107474 :         if (l->ready[l->ready_num]) {
     149       37700 :             if (!bits--) {
     150        7772 :                 need_sign = 1;
     151        7772 :                 goto leftover;
     152             :             }
     153       29928 :             l->ready[l->ready_num] *= READ_BIT(r) ? -1 : +1;
     154             :         }
     155       99702 :         l->ready_num++;
     156             : 
     157       99702 :         if (!bits)
     158       15834 :             return;
     159             :     }
     160             : 
     161       40774 :     leftover:
     162       40774 :         l->leftover      = r << bits_start;
     163       40774 :         l->leftover_bits = bits_tot - bits_start;
     164       40774 :         l->need_s        = need_sign;
     165             : }
     166             : 
     167             : /* Parity LUTs - even and odd bit end positions */
     168         116 : static void generate_parity_lut(DiracGolombLUT *lut, int even)
     169             : {
     170             :     int idx;
     171       29812 :     for (idx = 0; idx < LUT_SIZE; idx++) {
     172       29696 :         DiracGolombLUT *l = &lut[idx];
     173       29696 :         int symbol_end_loc = -1;
     174             :         uint32_t code;
     175             :         int i;
     176             : 
     177       29696 :         INIT_RESIDUE(res);
     178       29696 :         SET_RESIDUE(res, idx, LUT_BITS);
     179             : 
     180       99296 :         for (i = 0; i < LUT_BITS; i++) {
     181       97440 :             const int cond = even ? (i & 1) : !(i & 1);
     182       97440 :             if (((res >> (RSIZE_BITS - i - 1)) & 1) && cond) {
     183       27840 :                 symbol_end_loc = i + 2;
     184       27840 :                 break;
     185             :             }
     186             :         }
     187             : 
     188       29696 :         if (symbol_end_loc < 0 || symbol_end_loc > LUT_BITS) {
     189        2784 :             l->preamble      = 0;
     190        2784 :             l->preamble_bits = 0;
     191        2784 :             l->leftover_bits = LUT_BITS;
     192        2784 :             l->leftover      = CONVERT_TO_RESIDUE(idx, l->leftover_bits);
     193        2784 :             if (even)
     194        1856 :                 l->need_s    = idx & 1;
     195        2784 :             continue;
     196             :         }
     197             : 
     198             :         /* Gets bits 0 through to (symbol_end_loc - 1) inclusive */
     199       26912 :         code  = idx >> ((LUT_BITS - 1) - (symbol_end_loc - 1));
     200       26912 :         code &= ((1 << LUT_BITS) - 1) >> (LUT_BITS - symbol_end_loc);
     201       26912 :         l->preamble_bits = symbol_end_loc;
     202       26912 :         l->preamble      = CONVERT_TO_RESIDUE(code, l->preamble_bits);
     203       26912 :         l->sign = ((l->preamble >> (RSIZE_BITS - l->preamble_bits)) & 1) ? -1 : +1;
     204             : 
     205       26912 :         search_for_golomb(l, res << symbol_end_loc, LUT_BITS - symbol_end_loc);
     206             :     }
     207         116 : }
     208             : 
     209             : /* Reset (off == 0) and needs-one-more-bit (off == 1) LUTs */
     210         116 : static void generate_offset_lut(DiracGolombLUT *lut, int off)
     211             : {
     212             :     int idx;
     213       29812 :     for (idx = 0; idx < LUT_SIZE; idx++) {
     214       29696 :         DiracGolombLUT *l = &lut[idx];
     215             : 
     216       29696 :         INIT_RESIDUE(res);
     217       29696 :         SET_RESIDUE(res, idx, LUT_BITS);
     218             : 
     219       29696 :         l->preamble_bits = off;
     220       29696 :         if (off) {
     221       14848 :             l->preamble  = CONVERT_TO_RESIDUE(res >> (RSIZE_BITS - off), off);
     222       14848 :             l->sign      = ((l->preamble >> (RSIZE_BITS - l->preamble_bits)) & 1) ? -1 : +1;
     223             :         } else {
     224       14848 :             l->preamble  = 0;
     225       14848 :             l->sign = 1;
     226             :         }
     227             : 
     228       29696 :         search_for_golomb(l, res << off, LUT_BITS - off);
     229             :     }
     230         116 : }
     231             : 
     232          58 : av_cold int ff_dirac_golomb_reader_init(DiracGolombLUT **lut_ctx)
     233             : {
     234             :     DiracGolombLUT *lut;
     235             : 
     236          58 :     if (!(lut = av_calloc(4*LUT_SIZE, sizeof(DiracGolombLUT))))
     237           0 :         return AVERROR(ENOMEM);
     238             : 
     239          58 :     generate_parity_lut(&lut[0*LUT_SIZE], 0);
     240          58 :     generate_parity_lut(&lut[1*LUT_SIZE], 1);
     241          58 :     generate_offset_lut(&lut[2*LUT_SIZE], 0);
     242          58 :     generate_offset_lut(&lut[3*LUT_SIZE], 1);
     243             : 
     244          58 :     *lut_ctx = lut;
     245             : 
     246          58 :     return 0;
     247             : }
     248             : 
     249          58 : av_cold void ff_dirac_golomb_reader_end(DiracGolombLUT **lut_ctx)
     250             : {
     251          58 :     av_freep(lut_ctx);
     252          58 : }

Generated by: LCOV version 1.13