diff libavcodec/cabac.c @ 2:897f711a7157

rearrange to work with autoconf
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Tue, 25 Sep 2012 15:55:33 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libavcodec/cabac.c	Tue Sep 25 15:55:33 2012 +0200
     1.3 @@ -0,0 +1,242 @@
     1.4 +/*
     1.5 + * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
     1.6 + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
     1.7 + *
     1.8 + * This file is part of FFmpeg.
     1.9 + *
    1.10 + * FFmpeg is free software; you can redistribute it and/or
    1.11 + * modify it under the terms of the GNU Lesser General Public
    1.12 + * License as published by the Free Software Foundation; either
    1.13 + * version 2.1 of the License, or (at your option) any later version.
    1.14 + *
    1.15 + * FFmpeg is distributed in the hope that it will be useful,
    1.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.18 + * Lesser General Public License for more details.
    1.19 + *
    1.20 + * You should have received a copy of the GNU Lesser General Public
    1.21 + * License along with FFmpeg; if not, write to the Free Software
    1.22 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    1.23 + */
    1.24 +
    1.25 +/**
    1.26 + * @file
    1.27 + * Context Adaptive Binary Arithmetic Coder.
    1.28 + */
    1.29 +
    1.30 +#include <string.h>
    1.31 +
    1.32 +#include "libavutil/common.h"
    1.33 +//#include "get_bits.h"
    1.34 +#include "cabac.h"
    1.35 +
    1.36 +static const uint8_t lps_range[64][4]= {
    1.37 +{128,176,208,240}, {128,167,197,227}, {128,158,187,216}, {123,150,178,205},
    1.38 +{116,142,169,195}, {111,135,160,185}, {105,128,152,175}, {100,122,144,166},
    1.39 +{ 95,116,137,158}, { 90,110,130,150}, { 85,104,123,142}, { 81, 99,117,135},
    1.40 +{ 77, 94,111,128}, { 73, 89,105,122}, { 69, 85,100,116}, { 66, 80, 95,110},
    1.41 +{ 62, 76, 90,104}, { 59, 72, 86, 99}, { 56, 69, 81, 94}, { 53, 65, 77, 89},
    1.42 +{ 51, 62, 73, 85}, { 48, 59, 69, 80}, { 46, 56, 66, 76}, { 43, 53, 63, 72},
    1.43 +{ 41, 50, 59, 69}, { 39, 48, 56, 65}, { 37, 45, 54, 62}, { 35, 43, 51, 59},
    1.44 +{ 33, 41, 48, 56}, { 32, 39, 46, 53}, { 30, 37, 43, 50}, { 29, 35, 41, 48},
    1.45 +{ 27, 33, 39, 45}, { 26, 31, 37, 43}, { 24, 30, 35, 41}, { 23, 28, 33, 39},
    1.46 +{ 22, 27, 32, 37}, { 21, 26, 30, 35}, { 20, 24, 29, 33}, { 19, 23, 27, 31},
    1.47 +{ 18, 22, 26, 30}, { 17, 21, 25, 28}, { 16, 20, 23, 27}, { 15, 19, 22, 25},
    1.48 +{ 14, 18, 21, 24}, { 14, 17, 20, 23}, { 13, 16, 19, 22}, { 12, 15, 18, 21},
    1.49 +{ 12, 14, 17, 20}, { 11, 14, 16, 19}, { 11, 13, 15, 18}, { 10, 12, 15, 17},
    1.50 +{ 10, 12, 14, 16}, {  9, 11, 13, 15}, {  9, 11, 12, 14}, {  8, 10, 12, 14},
    1.51 +{  8,  9, 11, 13}, {  7,  9, 11, 12}, {  7,  9, 10, 12}, {  7,  8, 10, 11},
    1.52 +{  6,  8,  9, 11}, {  6,  7,  9, 10}, {  6,  7,  8,  9}, {  2,  2,  2,  2},
    1.53 +};
    1.54 +
    1.55 +uint8_t ff_h264_mlps_state[4*64];
    1.56 +uint8_t ff_h264_lps_range[4*2*64];
    1.57 +uint8_t ff_h264_lps_state[2*64];
    1.58 +uint8_t ff_h264_mps_state[2*64];
    1.59 +
    1.60 +static const uint8_t mps_state[64]= {
    1.61 +  1, 2, 3, 4, 5, 6, 7, 8,
    1.62 +  9,10,11,12,13,14,15,16,
    1.63 + 17,18,19,20,21,22,23,24,
    1.64 + 25,26,27,28,29,30,31,32,
    1.65 + 33,34,35,36,37,38,39,40,
    1.66 + 41,42,43,44,45,46,47,48,
    1.67 + 49,50,51,52,53,54,55,56,
    1.68 + 57,58,59,60,61,62,62,63,
    1.69 +};
    1.70 +
    1.71 +static const uint8_t lps_state[64]= {
    1.72 +  0, 0, 1, 2, 2, 4, 4, 5,
    1.73 +  6, 7, 8, 9, 9,11,11,12,
    1.74 + 13,13,15,15,16,16,18,18,
    1.75 + 19,19,21,21,22,22,23,24,
    1.76 + 24,25,26,26,27,27,28,29,
    1.77 + 29,30,30,30,31,32,32,33,
    1.78 + 33,33,34,34,35,35,35,36,
    1.79 + 36,36,37,37,37,38,38,63,
    1.80 +};
    1.81 +
    1.82 +const uint8_t ff_h264_norm_shift[512]= {
    1.83 + 9,8,7,7,6,6,6,6,5,5,5,5,5,5,5,5,
    1.84 + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
    1.85 + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
    1.86 + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
    1.87 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
    1.88 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
    1.89 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
    1.90 + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
    1.91 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1.92 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1.93 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1.94 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1.95 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    1.96 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    1.97 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    1.98 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    1.99 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   1.100 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   1.101 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   1.102 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   1.103 +};
   1.104 +
   1.105 +/**
   1.106 + *
   1.107 + * @param buf_size size of buf in bits
   1.108 + */
   1.109 +void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
   1.110 +    c->bytestream_start=
   1.111 +    c->bytestream= buf;
   1.112 +    c->bytestream_end= buf + buf_size;
   1.113 +
   1.114 +#if CABAC_BITS == 16
   1.115 +    c->low =  (*c->bytestream++)<<18;
   1.116 +    c->low+=  (*c->bytestream++)<<10;
   1.117 +#else
   1.118 +    c->low =  (*c->bytestream++)<<10;
   1.119 +#endif
   1.120 +    c->low+= ((*c->bytestream++)<<2) + 2;
   1.121 +    c->range= 0x1FE;
   1.122 +}
   1.123 +
   1.124 +void ff_init_cabac_states(){
   1.125 +    int i, j;
   1.126 +
   1.127 +    for(i=0; i<64; i++){
   1.128 +        for(j=0; j<4; j++){ //FIXME check if this is worth the 1 shift we save
   1.129 +            ff_h264_lps_range[j*2*64+2*i+0]=
   1.130 +            ff_h264_lps_range[j*2*64+2*i+1]= lps_range[i][j];
   1.131 +        }
   1.132 +
   1.133 +        ff_h264_mlps_state[128+2*i+0]=
   1.134 +        ff_h264_mps_state[2*i+0]= 2*mps_state[i]+0;
   1.135 +        ff_h264_mlps_state[128+2*i+1]=
   1.136 +        ff_h264_mps_state[2*i+1]= 2*mps_state[i]+1;
   1.137 +
   1.138 +        if( i ){
   1.139 +#ifdef BRANCHLESS_CABAC_DECODER
   1.140 +            ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0;
   1.141 +            ff_h264_mlps_state[128-2*i-2]= 2*lps_state[i]+1;
   1.142 +        }else{
   1.143 +            ff_h264_mlps_state[128-2*i-1]= 1;
   1.144 +            ff_h264_mlps_state[128-2*i-2]= 0;
   1.145 +#else
   1.146 +            ff_h264_lps_state[2*i+0]= 2*lps_state[i]+0;
   1.147 +            ff_h264_lps_state[2*i+1]= 2*lps_state[i]+1;
   1.148 +        }else{
   1.149 +            ff_h264_lps_state[2*i+0]= 1;
   1.150 +            ff_h264_lps_state[2*i+1]= 0;
   1.151 +#endif
   1.152 +        }
   1.153 +    }
   1.154 +}
   1.155 +
   1.156 +#ifdef TEST
   1.157 +#define SIZE 10240
   1.158 +#define START_TIMER
   1.159 +#define STOP_TIMER(...)
   1.160 +#define av_log(...)
   1.161 +// #include "libavutil/lfg.h"
   1.162 +#include "avcodec.h"
   1.163 +#include "cabac.h"
   1.164 +
   1.165 +int main(void){
   1.166 +    CABACContext c;
   1.167 +    uint8_t b[9*SIZE];
   1.168 +    uint8_t r[9*SIZE];
   1.169 +    int i;
   1.170 +    uint8_t state[10]= {0};
   1.171 +//    AVLFG prng;
   1.172 +
   1.173 +// //     av_lfg_init(&prng, 1);
   1.174 +//     ff_init_cabac_encoder(&c, b, SIZE);
   1.175 +//     ff_init_cabac_states();
   1.176 +//
   1.177 +//     for(i=0; i<SIZE; i++){
   1.178 +//         r[i] = i%7; //av_lfg_get(&prng) % 7;
   1.179 +//     }
   1.180 +//
   1.181 +//     for(i=0; i<SIZE; i++){
   1.182 +// START_TIMER
   1.183 +//         put_cabac_bypass(&c, r[i]&1);
   1.184 +// STOP_TIMER("put_cabac_bypass")
   1.185 +//     }
   1.186 +//
   1.187 +//     for(i=0; i<SIZE; i++){
   1.188 +// START_TIMER
   1.189 +//         put_cabac(&c, state, r[i]&1);
   1.190 +// STOP_TIMER("put_cabac")
   1.191 +//     }
   1.192 +//
   1.193 +//     for(i=0; i<SIZE; i++){
   1.194 +// START_TIMER
   1.195 +//         put_cabac_u(&c, state, r[i], 6, 3, i&1);
   1.196 +// STOP_TIMER("put_cabac_u")
   1.197 +//     }
   1.198 +//
   1.199 +//     for(i=0; i<SIZE; i++){
   1.200 +// START_TIMER
   1.201 +//         put_cabac_ueg(&c, state, r[i], 3, 0, 1, 2);
   1.202 +// STOP_TIMER("put_cabac_ueg")
   1.203 +//     }
   1.204 +//
   1.205 +//     put_cabac_terminate(&c, 1);
   1.206 +
   1.207 +    ff_init_cabac_decoder(&c, b, SIZE);
   1.208 +
   1.209 +    memset(state, 0, sizeof(state));
   1.210 +
   1.211 +    for(i=0; i<SIZE; i++){
   1.212 +START_TIMER
   1.213 +        if( (r[i]&1) != get_cabac_bypass(&c) )
   1.214 +            av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i);
   1.215 +STOP_TIMER("get_cabac_bypass")
   1.216 +    }
   1.217 +
   1.218 +    for(i=0; i<SIZE; i++){
   1.219 +START_TIMER
   1.220 +        if( (r[i]&1) != get_cabac(&c, state) )
   1.221 +            av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
   1.222 +STOP_TIMER("get_cabac")
   1.223 +    }
   1.224 +#if 0
   1.225 +    for(i=0; i<SIZE; i++){
   1.226 +START_TIMER
   1.227 +        if( r[i] != get_cabac_u(&c, state, (i&1) ? 6 : 7, 3, i&1) )
   1.228 +            av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i);
   1.229 +STOP_TIMER("get_cabac_u")
   1.230 +    }
   1.231 +
   1.232 +    for(i=0; i<SIZE; i++){
   1.233 +START_TIMER
   1.234 +        if( r[i] != get_cabac_ueg(&c, state, 3, 0, 1, 2))
   1.235 +            av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i);
   1.236 +STOP_TIMER("get_cabac_ueg")
   1.237 +    }
   1.238 +#endif
   1.239 +    if(!get_cabac_terminate(&c))
   1.240 +        av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
   1.241 +
   1.242 +    return 0;
   1.243 +}
   1.244 +
   1.245 +#endif /* TEST */