LCOV - code coverage report
Current view: top level - src/libavcodec/tests - cabac.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 73 80 91.2 %
Date: 2017-01-19 23:52:33 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
       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             : #include "libavcodec/cabac.c"
      22             : 
      23             : #define SIZE 10240
      24             : 
      25             : #include "libavutil/lfg.h"
      26             : #include "libavcodec/avcodec.h"
      27             : 
      28        8410 : static inline void put_cabac_bit(CABACContext *c, int b){
      29        8410 :     put_bits(&c->pb, 1, b);
      30       16404 :     for(;c->outstanding_count; c->outstanding_count--){
      31        7994 :         put_bits(&c->pb, 1, 1-b);
      32             :     }
      33        8410 : }
      34             : 
      35       10241 : static inline void renorm_cabac_encoder(CABACContext *c){
      36       26645 :     while(c->range < 0x100){
      37             :         //FIXME optimize
      38        6163 :         if(c->low<0x100){
      39        2370 :             put_cabac_bit(c, 0);
      40        3793 :         }else if(c->low<0x200){
      41        2944 :             c->outstanding_count++;
      42        2944 :             c->low -= 0x100;
      43             :         }else{
      44         849 :             put_cabac_bit(c, 1);
      45         849 :             c->low -= 0x200;
      46             :         }
      47             : 
      48        6163 :         c->range+= c->range;
      49        6163 :         c->low += c->low;
      50             :     }
      51       10241 : }
      52             : 
      53       10240 : static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
      54       10240 :     int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
      55             : 
      56       10240 :     if(bit == ((*state)&1)){
      57        7637 :         c->range -= RangeLPS;
      58        7637 :         *state    = ff_h264_mlps_state[128 + *state];
      59             :     }else{
      60        2603 :         c->low += c->range - RangeLPS;
      61        2603 :         c->range = RangeLPS;
      62        2603 :         *state= ff_h264_mlps_state[127 - *state];
      63             :     }
      64             : 
      65       10240 :     renorm_cabac_encoder(c);
      66       10240 : }
      67             : 
      68             : /**
      69             :  * @param bit 0 -> write zero bit, !=0 write one bit
      70             :  */
      71       10240 : static void put_cabac_bypass(CABACContext *c, int bit){
      72       10240 :     c->low += c->low;
      73             : 
      74       10240 :     if(bit){
      75        4761 :         c->low += c->range;
      76             :     }
      77             : //FIXME optimize
      78       10240 :     if(c->low<0x200){
      79        3869 :         put_cabac_bit(c, 0);
      80        6371 :     }else if(c->low<0x400){
      81        5050 :         c->outstanding_count++;
      82        5050 :         c->low -= 0x200;
      83             :     }else{
      84        1321 :         put_cabac_bit(c, 1);
      85        1321 :         c->low -= 0x400;
      86             :     }
      87       10240 : }
      88             : 
      89             : /**
      90             :  *
      91             :  * @return the number of bytes written
      92             :  */
      93           1 : static int put_cabac_terminate(CABACContext *c, int bit){
      94           1 :     c->range -= 2;
      95             : 
      96           1 :     if(!bit){
      97           0 :         renorm_cabac_encoder(c);
      98             :     }else{
      99           1 :         c->low += c->range;
     100           1 :         c->range= 2;
     101             : 
     102           1 :         renorm_cabac_encoder(c);
     103             : 
     104           1 :         av_assert0(c->low <= 0x1FF);
     105           1 :         put_cabac_bit(c, c->low>>9);
     106           1 :         put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
     107             : 
     108           1 :         flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
     109             :     }
     110             : 
     111           1 :     return (put_bits_count(&c->pb)+7)>>3;
     112             : }
     113             : 
     114           1 : int main(void){
     115             :     CABACContext c;
     116             :     uint8_t b[9*SIZE];
     117             :     uint8_t r[9*SIZE];
     118           1 :     int i, ret = 0;
     119           1 :     uint8_t state[10]= {0};
     120             :     AVLFG prng;
     121             : 
     122           1 :     av_lfg_init(&prng, 1);
     123           1 :     ff_init_cabac_encoder(&c, b, SIZE);
     124             : 
     125       10241 :     for(i=0; i<SIZE; i++){
     126       10240 :         if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7;
     127        5120 :         else         r[i] = (i>>8)&1;
     128             :     }
     129             : 
     130       10241 :     for(i=0; i<SIZE; i++){
     131       10240 :         put_cabac_bypass(&c, r[i]&1);
     132             :     }
     133             : 
     134       10241 :     for(i=0; i<SIZE; i++){
     135       10240 :         put_cabac(&c, state, r[i]&1);
     136             :     }
     137             : 
     138           1 :     i= put_cabac_terminate(&c, 1);
     139           1 :     b[i++] = av_lfg_get(&prng);
     140           1 :     b[i  ] = av_lfg_get(&prng);
     141             : 
     142           1 :     ff_init_cabac_decoder(&c, b, SIZE);
     143             : 
     144           1 :     memset(state, 0, sizeof(state));
     145             : 
     146       10241 :     for(i=0; i<SIZE; i++){
     147       10240 :         if( (r[i]&1) != get_cabac_bypass(&c) ) {
     148           0 :             av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i);
     149           0 :             ret = 1;
     150             :         }
     151             :     }
     152             : 
     153       10241 :     for(i=0; i<SIZE; i++){
     154       10240 :         if( (r[i]&1) != get_cabac_noinline(&c, state) ) {
     155           0 :             av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
     156           0 :             ret = 1;
     157             :         }
     158             :     }
     159           1 :     if(!get_cabac_terminate(&c)) {
     160           0 :         av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
     161           0 :         ret = 1;
     162             :     }
     163             : 
     164           1 :     return ret;
     165             : }

Generated by: LCOV version 1.12