LCOV - code coverage report
Current view: top level - libavcodec - vp56.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 75 75 100.0 %
Date: 2017-12-16 01:21:47 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
       3             :  *
       4             :  * This file is part of FFmpeg.
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public
       8             :  * License as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with FFmpeg; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : /**
      22             :  * @file
      23             :  * VP5 and VP6 compatible video decoder (common features)
      24             :  */
      25             : 
      26             : #ifndef AVCODEC_VP56_H
      27             : #define AVCODEC_VP56_H
      28             : 
      29             : #include "avcodec.h"
      30             : #include "get_bits.h"
      31             : #include "hpeldsp.h"
      32             : #include "bytestream.h"
      33             : #include "h264chroma.h"
      34             : #include "videodsp.h"
      35             : #include "vp3dsp.h"
      36             : #include "vp56dsp.h"
      37             : 
      38             : typedef struct vp56_context VP56Context;
      39             : 
      40             : typedef enum {
      41             :     VP56_FRAME_NONE     =-1,
      42             :     VP56_FRAME_CURRENT  = 0,
      43             :     VP56_FRAME_PREVIOUS = 1,
      44             :     VP56_FRAME_GOLDEN   = 2,
      45             :     VP56_FRAME_GOLDEN2  = 3,
      46             : } VP56Frame;
      47             : 
      48             : typedef enum {
      49             :     VP56_MB_INTER_NOVEC_PF = 0,  /**< Inter MB, no vector, from previous frame */
      50             :     VP56_MB_INTRA          = 1,  /**< Intra MB */
      51             :     VP56_MB_INTER_DELTA_PF = 2,  /**< Inter MB, above/left vector + delta, from previous frame */
      52             :     VP56_MB_INTER_V1_PF    = 3,  /**< Inter MB, first vector, from previous frame */
      53             :     VP56_MB_INTER_V2_PF    = 4,  /**< Inter MB, second vector, from previous frame */
      54             :     VP56_MB_INTER_NOVEC_GF = 5,  /**< Inter MB, no vector, from golden frame */
      55             :     VP56_MB_INTER_DELTA_GF = 6,  /**< Inter MB, above/left vector + delta, from golden frame */
      56             :     VP56_MB_INTER_4V       = 7,  /**< Inter MB, 4 vectors, from previous frame */
      57             :     VP56_MB_INTER_V1_GF    = 8,  /**< Inter MB, first vector, from golden frame */
      58             :     VP56_MB_INTER_V2_GF    = 9,  /**< Inter MB, second vector, from golden frame */
      59             : } VP56mb;
      60             : 
      61             : typedef struct VP56Tree {
      62             :   int8_t val;
      63             :   int8_t prob_idx;
      64             : } VP56Tree;
      65             : 
      66             : typedef struct VP56mv {
      67             :     DECLARE_ALIGNED(4, int16_t, x);
      68             :     int16_t y;
      69             : } VP56mv;
      70             : 
      71             : #define VP56_SIZE_CHANGE 1
      72             : 
      73             : typedef void (*VP56ParseVectorAdjustment)(VP56Context *s,
      74             :                                           VP56mv *vect);
      75             : typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src,
      76             :                            int offset1, int offset2, ptrdiff_t stride,
      77             :                            VP56mv mv, int mask, int select, int luma);
      78             : typedef int  (*VP56ParseCoeff)(VP56Context *s);
      79             : typedef void (*VP56DefaultModelsInit)(VP56Context *s);
      80             : typedef void (*VP56ParseVectorModels)(VP56Context *s);
      81             : typedef int  (*VP56ParseCoeffModels)(VP56Context *s);
      82             : typedef int  (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf,
      83             :                                 int buf_size);
      84             : 
      85             : typedef struct VP56RangeCoder {
      86             :     int high;
      87             :     int bits; /* stored negated (i.e. negative "bits" is a positive number of
      88             :                  bits left) in order to eliminate a negate in cache refilling */
      89             :     const uint8_t *buffer;
      90             :     const uint8_t *end;
      91             :     unsigned int code_word;
      92             : } VP56RangeCoder;
      93             : 
      94             : typedef struct VP56RefDc {
      95             :     uint8_t not_null_dc;
      96             :     VP56Frame ref_frame;
      97             :     int16_t dc_coeff;
      98             : } VP56RefDc;
      99             : 
     100             : typedef struct VP56Macroblock {
     101             :     uint8_t type;
     102             :     VP56mv mv;
     103             : } VP56Macroblock;
     104             : 
     105             : typedef struct VP56Model {
     106             :     uint8_t coeff_reorder[64];       /* used in vp6 only */
     107             :     uint8_t coeff_index_to_pos[64];  /* used in vp6 only */
     108             :     uint8_t vector_sig[2];           /* delta sign */
     109             :     uint8_t vector_dct[2];           /* delta coding types */
     110             :     uint8_t vector_pdi[2][2];        /* predefined delta init */
     111             :     uint8_t vector_pdv[2][7];        /* predefined delta values */
     112             :     uint8_t vector_fdv[2][8];        /* 8 bit delta value definition */
     113             :     uint8_t coeff_dccv[2][11];       /* DC coeff value */
     114             :     uint8_t coeff_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */
     115             :     uint8_t coeff_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */
     116             :     uint8_t coeff_dcct[2][36][5];    /* DC coeff coding type */
     117             :     uint8_t coeff_runv[2][14];       /* run value (vp6 only) */
     118             :     uint8_t mb_type[3][10][10];      /* model for decoding MB type */
     119             :     uint8_t mb_types_stats[3][10][2];/* contextual, next MB type stats */
     120             : } VP56Model;
     121             : 
     122             : struct vp56_context {
     123             :     AVCodecContext *avctx;
     124             :     H264ChromaContext h264chroma;
     125             :     HpelDSPContext hdsp;
     126             :     VideoDSPContext vdsp;
     127             :     VP3DSPContext vp3dsp;
     128             :     VP56DSPContext vp56dsp;
     129             :     uint8_t idct_scantable[64];
     130             :     AVFrame *frames[4];
     131             :     uint8_t *edge_emu_buffer_alloc;
     132             :     uint8_t *edge_emu_buffer;
     133             :     VP56RangeCoder c;
     134             :     VP56RangeCoder cc;
     135             :     VP56RangeCoder *ccp;
     136             :     int sub_version;
     137             : 
     138             :     /* frame info */
     139             :     int golden_frame;
     140             :     int plane_width[4];
     141             :     int plane_height[4];
     142             :     int mb_width;   /* number of horizontal MB */
     143             :     int mb_height;  /* number of vertical MB */
     144             :     int block_offset[6];
     145             : 
     146             :     int quantizer;
     147             :     uint16_t dequant_dc;
     148             :     uint16_t dequant_ac;
     149             : 
     150             :     /* DC predictors management */
     151             :     VP56RefDc *above_blocks;
     152             :     VP56RefDc left_block[4];
     153             :     int above_block_idx[6];
     154             :     int16_t prev_dc[3][3];    /* [plan][ref_frame] */
     155             : 
     156             :     /* blocks / macroblock */
     157             :     VP56mb mb_type;
     158             :     VP56Macroblock *macroblocks;
     159             :     DECLARE_ALIGNED(16, int16_t, block_coeff)[6][64];
     160             : 
     161             :     /* motion vectors */
     162             :     VP56mv mv[6];  /* vectors for each block in MB */
     163             :     VP56mv vector_candidate[2];
     164             :     int vector_candidate_pos;
     165             : 
     166             :     /* filtering hints */
     167             :     int filter_header;               /* used in vp6 only */
     168             :     int deblock_filtering;
     169             :     int filter_selection;
     170             :     int filter_mode;
     171             :     int max_vector_length;
     172             :     int sample_variance_threshold;
     173             : 
     174             :     uint8_t coeff_ctx[4][64];              /* used in vp5 only */
     175             :     uint8_t coeff_ctx_last[4];             /* used in vp5 only */
     176             : 
     177             :     int has_alpha;
     178             : 
     179             :     /* upside-down flipping hints */
     180             :     int flip;  /* are we flipping ? */
     181             :     int frbi;  /* first row block index in MB */
     182             :     int srbi;  /* second row block index in MB */
     183             :     ptrdiff_t stride[4];  /* stride for each plan */
     184             : 
     185             :     const uint8_t *vp56_coord_div;
     186             :     VP56ParseVectorAdjustment parse_vector_adjustment;
     187             :     VP56Filter filter;
     188             :     VP56ParseCoeff parse_coeff;
     189             :     VP56DefaultModelsInit default_models_init;
     190             :     VP56ParseVectorModels parse_vector_models;
     191             :     VP56ParseCoeffModels parse_coeff_models;
     192             :     VP56ParseHeader parse_header;
     193             : 
     194             :     /* for "slice" parallelism between YUV and A */
     195             :     VP56Context *alpha_context;
     196             : 
     197             :     VP56Model *modelp;
     198             :     VP56Model model;
     199             : 
     200             :     /* huffman decoding */
     201             :     int use_huffman;
     202             :     GetBitContext gb;
     203             :     VLC dccv_vlc[2];
     204             :     VLC runv_vlc[2];
     205             :     VLC ract_vlc[2][3][6];
     206             :     unsigned int nb_null[2][2];       /* number of consecutive NULL DC/AC */
     207             : 
     208             :     int have_undamaged_frame;
     209             :     int discard_frame;
     210             : };
     211             : 
     212             : 
     213             : int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
     214             : int ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
     215             :                           int flip, int has_alpha);
     216             : int ff_vp56_free(AVCodecContext *avctx);
     217             : int ff_vp56_free_context(VP56Context *s);
     218             : void ff_vp56_init_dequant(VP56Context *s, int quantizer);
     219             : int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     220             :                          AVPacket *avpkt);
     221             : 
     222             : 
     223             : /**
     224             :  * vp56 specific range coder implementation
     225             :  */
     226             : 
     227             : extern const uint8_t ff_vp56_norm_shift[256];
     228             : int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size);
     229             : 
     230    95142785 : static av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c)
     231             : {
     232    95142785 :     int shift = ff_vp56_norm_shift[c->high];
     233    95142785 :     int bits = c->bits;
     234    95142785 :     unsigned int code_word = c->code_word;
     235             : 
     236    95142785 :     c->high   <<= shift;
     237    95142785 :     code_word <<= shift;
     238    95142785 :     bits       += shift;
     239    95142785 :     if(bits >= 0 && c->buffer < c->end) {
     240     4097226 :         code_word |= bytestream_get_be16(&c->buffer) << bits;
     241     4097226 :         bits -= 16;
     242             :     }
     243    95142785 :     c->bits = bits;
     244    95142785 :     return code_word;
     245             : }
     246             : 
     247             : #if   ARCH_ARM
     248             : #include "arm/vp56_arith.h"
     249             : #elif ARCH_X86
     250             : #include "x86/vp56_arith.h"
     251             : #endif
     252             : 
     253             : #ifndef vp56_rac_get_prob
     254             : #define vp56_rac_get_prob vp56_rac_get_prob
     255             : static av_always_inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob)
     256             : {
     257             :     unsigned int code_word = vp56_rac_renorm(c);
     258             :     unsigned int low = 1 + (((c->high - 1) * prob) >> 8);
     259             :     unsigned int low_shift = low << 16;
     260             :     int bit = code_word >= low_shift;
     261             : 
     262             :     c->high = bit ? c->high - low : low;
     263             :     c->code_word = bit ? code_word - low_shift : code_word;
     264             : 
     265             :     return bit;
     266             : }
     267             : #endif
     268             : 
     269             : #ifndef vp56_rac_get_prob_branchy
     270             : // branchy variant, to be used where there's a branch based on the bit decoded
     271    65167621 : static av_always_inline int vp56_rac_get_prob_branchy(VP56RangeCoder *c, int prob)
     272             : {
     273    65167621 :     unsigned long code_word = vp56_rac_renorm(c);
     274    65167621 :     unsigned low = 1 + (((c->high - 1) * prob) >> 8);
     275    65167621 :     unsigned low_shift = low << 16;
     276             : 
     277    65167621 :     if (code_word >= low_shift) {
     278    29992199 :         c->high     -= low;
     279    29992199 :         c->code_word = code_word - low_shift;
     280    29992199 :         return 1;
     281             :     }
     282             : 
     283    35175422 :     c->high = low;
     284    35175422 :     c->code_word = code_word;
     285    35175422 :     return 0;
     286             : }
     287             : #endif
     288             : 
     289     1303559 : static av_always_inline int vp56_rac_get(VP56RangeCoder *c)
     290             : {
     291     1303559 :     unsigned int code_word = vp56_rac_renorm(c);
     292             :     /* equiprobable */
     293     1303559 :     int low = (c->high + 1) >> 1;
     294     1303559 :     unsigned int low_shift = low << 16;
     295     1303559 :     int bit = code_word >= low_shift;
     296     1303559 :     if (bit) {
     297      651669 :         c->high   -= low;
     298      651669 :         code_word -= low_shift;
     299             :     } else {
     300      651890 :         c->high = low;
     301             :     }
     302             : 
     303     1303559 :     c->code_word = code_word;
     304     1303559 :     return bit;
     305             : }
     306             : 
     307             : // rounding is different than vp56_rac_get, is vp56_rac_get wrong?
     308     9895406 : static av_always_inline int vp8_rac_get(VP56RangeCoder *c)
     309             : {
     310     9895406 :     return vp56_rac_get_prob(c, 128);
     311             : }
     312             : 
     313       52237 : static int vp56_rac_gets(VP56RangeCoder *c, int bits)
     314             : {
     315       52237 :     int value = 0;
     316             : 
     317      255732 :     while (bits--) {
     318      151258 :         value = (value << 1) | vp56_rac_get(c);
     319             :     }
     320             : 
     321       52237 :     return value;
     322             : }
     323             : 
     324       47353 : static int vp8_rac_get_uint(VP56RangeCoder *c, int bits)
     325             : {
     326       47353 :     int value = 0;
     327             : 
     328      335058 :     while (bits--) {
     329      240352 :         value = (value << 1) | vp8_rac_get(c);
     330             :     }
     331             : 
     332       47353 :     return value;
     333             : }
     334             : 
     335             : // fixme: add 1 bit to all the calls to this?
     336        6104 : static av_unused int vp8_rac_get_sint(VP56RangeCoder *c, int bits)
     337             : {
     338             :     int v;
     339             : 
     340        6104 :     if (!vp8_rac_get(c))
     341        5361 :         return 0;
     342             : 
     343         743 :     v = vp8_rac_get_uint(c, bits);
     344             : 
     345         743 :     if (vp8_rac_get(c))
     346          98 :         v = -v;
     347             : 
     348         743 :     return v;
     349             : }
     350             : 
     351             : // P(7)
     352        8496 : static av_unused int vp56_rac_gets_nn(VP56RangeCoder *c, int bits)
     353             : {
     354        8496 :     int v = vp56_rac_gets(c, 7) << 1;
     355        8496 :     return v + !v;
     356             : }
     357             : 
     358         306 : static av_unused int vp8_rac_get_nn(VP56RangeCoder *c)
     359             : {
     360         306 :     int v = vp8_rac_get_uint(c, 7) << 1;
     361         306 :     return v + !v;
     362             : }
     363             : 
     364             : static av_always_inline
     365      445506 : int vp56_rac_get_tree(VP56RangeCoder *c,
     366             :                       const VP56Tree *tree,
     367             :                       const uint8_t *probs)
     368             : {
     369     2210419 :     while (tree->val > 0) {
     370     1319407 :         if (vp56_rac_get_prob_branchy(c, probs[tree->prob_idx]))
     371      450663 :             tree += tree->val;
     372             :         else
     373      868744 :             tree++;
     374             :     }
     375      445506 :     return -tree->val;
     376             : }
     377             : 
     378             : // how probabilities are associated with decisions is different I think
     379             : // well, the new scheme fits in the old but this way has one fewer branches per decision
     380     4171537 : static av_always_inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t (*tree)[2],
     381             :                                    const uint8_t *probs)
     382             : {
     383     4171537 :     int i = 0;
     384             : 
     385             :     do {
     386     9257935 :         i = tree[i][vp56_rac_get_prob(c, probs[i])];
     387     9257935 :     } while (i > 0);
     388             : 
     389     4171537 :     return -i;
     390             : }
     391             : 
     392             : // DCTextra
     393       43890 : static av_always_inline int vp8_rac_get_coeff(VP56RangeCoder *c, const uint8_t *prob)
     394             : {
     395       43890 :     int v = 0;
     396             : 
     397             :     do {
     398      163810 :         v = (v<<1) + vp56_rac_get_prob(c, *prob++);
     399      163810 :     } while (*prob);
     400             : 
     401       43890 :     return v;
     402             : }
     403             : 
     404             : #endif /* AVCODEC_VP56_H */

Generated by: LCOV version 1.13