Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (C) 2007 Marco Gerards <marco@gnu.org>
  3.  * Copyright (C) 2009 David Conrad
  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. /**
  23.  * @file
  24.  * Arithmetic decoder for Dirac
  25.  * @author Marco Gerards <marco@gnu.org>
  26.  */
  27.  
  28. #ifndef AVCODEC_DIRAC_ARITH_H
  29. #define AVCODEC_DIRAC_ARITH_H
  30.  
  31. #include "libavutil/x86/asm.h"
  32. #include "bytestream.h"
  33. #include "get_bits.h"
  34.  
  35. enum dirac_arith_contexts {
  36.     CTX_ZPZN_F1,
  37.     CTX_ZPNN_F1,
  38.     CTX_NPZN_F1,
  39.     CTX_NPNN_F1,
  40.     CTX_ZP_F2,
  41.     CTX_ZP_F3,
  42.     CTX_ZP_F4,
  43.     CTX_ZP_F5,
  44.     CTX_ZP_F6,
  45.     CTX_NP_F2,
  46.     CTX_NP_F3,
  47.     CTX_NP_F4,
  48.     CTX_NP_F5,
  49.     CTX_NP_F6,
  50.     CTX_COEFF_DATA,
  51.     CTX_SIGN_NEG,
  52.     CTX_SIGN_ZERO,
  53.     CTX_SIGN_POS,
  54.     CTX_ZERO_BLOCK,
  55.     CTX_DELTA_Q_F,
  56.     CTX_DELTA_Q_DATA,
  57.     CTX_DELTA_Q_SIGN,
  58.  
  59.     DIRAC_CTX_COUNT
  60. };
  61.  
  62. // Dirac resets the arith decoder between decoding various types of data,
  63. // so many contexts are never used simultaneously. Thus, we can reduce
  64. // the number of contexts needed by reusing them.
  65. #define CTX_SB_F1        CTX_ZP_F5
  66. #define CTX_SB_DATA      0
  67. #define CTX_PMODE_REF1   0
  68. #define CTX_PMODE_REF2   1
  69. #define CTX_GLOBAL_BLOCK 2
  70. #define CTX_MV_F1        CTX_ZP_F2
  71. #define CTX_MV_DATA      0
  72. #define CTX_DC_F1        CTX_ZP_F5
  73. #define CTX_DC_DATA      0
  74.  
  75. typedef struct {
  76.     unsigned low;
  77.     uint16_t range;
  78.     int16_t  counter;
  79.  
  80.     const uint8_t *bytestream;
  81.     const uint8_t *bytestream_end;
  82.  
  83.     uint16_t contexts[DIRAC_CTX_COUNT];
  84. } DiracArith;
  85.  
  86. extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT];
  87. extern const uint16_t ff_dirac_prob[256];
  88. extern int16_t ff_dirac_prob_branchless[256][2];
  89.  
  90. static inline void renorm(DiracArith *c)
  91. {
  92. #if HAVE_FAST_CLZ
  93.     int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15);
  94.  
  95.     c->low    <<= shift;
  96.     c->range  <<= shift;
  97.     c->counter += shift;
  98. #else
  99.     while (c->range <= 0x4000) {
  100.         c->low   <<= 1;
  101.         c->range <<= 1;
  102.         c->counter++;
  103.     }
  104. #endif
  105. }
  106.  
  107. static inline void refill(DiracArith *c)
  108. {
  109.     int counter = c->counter;
  110.  
  111.     if (counter >= 0) {
  112.         int new = bytestream_get_be16(&c->bytestream);
  113.  
  114.         // the spec defines overread bits to be 1, and streams rely on this
  115.         if (c->bytestream > c->bytestream_end) {
  116.             new |= 0xff;
  117.             if (c->bytestream > c->bytestream_end+1)
  118.                 new |= 0xff00;
  119.  
  120.             c->bytestream = c->bytestream_end;
  121.         }
  122.  
  123.         c->low += new << counter;
  124.         counter -= 16;
  125.     }
  126.     c->counter = counter;
  127. }
  128.  
  129. static inline int dirac_get_arith_bit(DiracArith *c, int ctx)
  130. {
  131.     int prob_zero = c->contexts[ctx];
  132.     int range_times_prob, bit;
  133.     unsigned low = c->low;
  134.     int    range = c->range;
  135.  
  136.     range_times_prob = (c->range * prob_zero) >> 16;
  137.  
  138. #if ARCH_X86 && HAVE_FAST_CMOV && HAVE_INLINE_ASM && HAVE_6REGS
  139.     low   -= range_times_prob << 16;
  140.     range -= range_times_prob;
  141.     bit = 0;
  142.     __asm__(
  143.         "cmpl   %5, %4 \n\t"
  144.         "setae  %b0    \n\t"
  145.         "cmovb  %3, %2 \n\t"
  146.         "cmovb  %5, %1 \n\t"
  147.         : "+q"(bit), "+r"(range), "+r"(low)
  148.         : "r"(c->low), "r"(c->low>>16),
  149.           "r"(range_times_prob)
  150.     );
  151. #else
  152.     bit = (low >> 16) >= range_times_prob;
  153.     if (bit) {
  154.         low   -= range_times_prob << 16;
  155.         range -= range_times_prob;
  156.     } else {
  157.         range  = range_times_prob;
  158.     }
  159. #endif
  160.  
  161.     c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit];
  162.     c->low   = low;
  163.     c->range = range;
  164.  
  165.     renorm(c);
  166.     refill(c);
  167.     return bit;
  168. }
  169.  
  170. static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx)
  171. {
  172.     int ret = 1;
  173.     while (!dirac_get_arith_bit(c, follow_ctx)) {
  174.         if (ret >= 0x40000000) {
  175.             av_log(NULL, AV_LOG_ERROR, "dirac_get_arith_uint overflow\n");
  176.             return -1;
  177.         }
  178.         ret <<= 1;
  179.         ret += dirac_get_arith_bit(c, data_ctx);
  180.         follow_ctx = ff_dirac_next_ctx[follow_ctx];
  181.     }
  182.     return ret-1;
  183. }
  184.  
  185. static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx)
  186. {
  187.     int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx);
  188.     if (ret && dirac_get_arith_bit(c, data_ctx+1))
  189.         ret = -ret;
  190.     return ret;
  191. }
  192.  
  193. void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length);
  194.  
  195. #endif /* AVCODEC_DIRAC_ARITH_H */
  196.