root/src/bifs/arith_decoder.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gp_bifs_aa_model_new
  2. gp_bifs_aa_model_del
  3. gp_bifs_aa_model_init
  4. UpdateAAModel
  5. gp_bifs_aa_dec_new
  6. gp_bifs_aa_dec_del
  7. bit_out_psc_layer
  8. gp_bifs_aa_dec_resync
  9. gp_bifs_aa_dec_flush
  10. gp_bifs_aa_dec_resync_bit
  11. gp_bifs_aa_dec_get_bit
  12. gp_bifs_aa_dec_reset
  13. AADec_Dec
  14. gp_bifs_aa_decode

/*
 *                      GPAC - Multimedia Framework C SDK
 *
 *                      Authors: Jean Le Feuvre
 *                      Copyright (c) Telecom ParisTech 2000-2012
 *                                      All rights reserved
 *
 *  This file is part of GPAC / BIFS codec sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include "quant.h"

#ifdef GPAC_ENABLE_BIFS_PMF

/*
        Adaptive Arithmethic Decoder from Annex G (Normative)

         Original code:
                   sac.c, part of tmndecode (H.263 decoder)

        Copyright (C) 1996  Telenor R&D, Norway
         Karl Olav Lillevold <Karl.Lillevold@nta.no>

        Karl Olav Lillevold               <Karl.Lillevold@nta.no>
                Telenor Research and Development
                P.O.Box 83                        tel.:   +47 63 84 84 00
                N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76

    Robert Danielsen                  e-mail: Robert.Danielsen@nta.no
                Telenor Research and Development  www:    http://www.nta.no/brukere/DVC/
                P.O.Box 83                        tel.:   +47 63 84 84 00
                N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76

         Original license: GNU Lesser General Public License

        This is basically the code from IM1 (the spec is not up-to-date with ref soft)
*/




#define AAM_Q1 16384
#define AAM_Q2 32768
#define AAM_Q3 49152
#define AAM_TOP 65535
#define AAM_ZEROMAX 22
#define AAM_MAX_FREQ 16383

struct _aamodel
{
        s32 nb_symb;
        s32     *cumul_freq;
        s32 *freq;
};

struct _aadecoder
{
        u32 low, high, code_value;
        s32 zero_run;
        Bool Bit;
        GF_BitStream *bs;
        Bool needs_flush;
        u32 read_bits, used_bits;
        /*amount of fake bits (bit read after end of stream)*/
        u32 skip_bits;
};



GF_AAModel *gp_bifs_aa_model_new()
{
        GF_AAModel *tmp;
        GF_SAFEALLOC(tmp, GF_AAModel);
        return tmp;
}

void gp_bifs_aa_model_del(GF_AAModel *model)
{
        if (model->cumul_freq) gf_free(model->cumul_freq);
        if (model->freq) gf_free(model->freq);
        gf_free(model);
}

void gp_bifs_aa_model_init(GF_AAModel *model, u32 nbBits)
{
        s32 i;
        model->nb_symb = 1<<nbBits;
        if (model->cumul_freq) gf_free(model->cumul_freq);
        if (model->freq) gf_free(model->freq);
        model->freq = (s32*)gf_malloc(sizeof(s32) * model->nb_symb);
        model->cumul_freq = (s32*)gf_malloc(sizeof(s32) * (model->nb_symb+1));

        for(i=0; i<model->nb_symb; i++) {
                model->freq[i]=1;
                model->cumul_freq[i] = model->nb_symb - i;
        }
        model->cumul_freq[model->nb_symb] = 0;
}

void UpdateAAModel(GF_AAModel *model, s32 symbol)
{
        s32 sum, i;

        /*The model is rescaled to avoid overflow*/
        if (model->cumul_freq[0] == AAM_MAX_FREQ) {
                sum = 0;
                for (i=model->nb_symb-1; i>=0; i--) {
                        model->freq[i] = (model->freq[i]+1)/2;
                        sum += model->freq[i];
                        model->cumul_freq[i] = sum;
                }
                model->cumul_freq[model->nb_symb] = 0;
        }
        model->freq[symbol] ++;
        model->cumul_freq[symbol] ++;
        while (symbol>0) model->cumul_freq[--symbol] ++;
}


void gf_bs_rewind_bits(GF_BitStream *bs, u64 nbBits);

GF_AADecoder *gp_bifs_aa_dec_new(GF_BitStream *bs)
{
        GF_AADecoder *tmp;
        GF_SAFEALLOC(tmp, GF_AADecoder);
        tmp->bs = bs;
        return tmp;
}
void gp_bifs_aa_dec_del(GF_AADecoder *dec)
{
        gf_free(dec);
}

static Bool bit_out_psc_layer(GF_AADecoder *dec)
{
        s32 v;
        if (gf_bs_bits_available(dec->bs) ) {
                v = gf_bs_read_int(dec->bs, 1) ? 1 : 0;
                dec->read_bits++;
        } else {
                v = (dec->zero_run == AAM_MAX_FREQ) ? 1 : 0;
                dec->skip_bits++;
        }

        if (dec->zero_run == AAM_ZEROMAX) {
                if (!v) return 0;
                v = gf_bs_read_int(dec->bs, 1) ? 1 : 0;
                dec->zero_run = 0;
                dec->read_bits++;
                dec->used_bits++;
        }
        dec->Bit = v;
        dec->needs_flush = 1;

        if (!dec->Bit)
                dec->zero_run++;
        else
                dec->zero_run = 0;

        return 1;
}

void gp_bifs_aa_dec_resync(GF_AADecoder *dec)
{
        u32 rewind;
        if (!dec->needs_flush) return;
        rewind = dec->read_bits - 1 - (dec->used_bits+1);
        /*magic number from IM1 (spec is wrong there)*/
        rewind = 14;
        if (dec->skip_bits < rewind) gf_bs_rewind_bits(dec->bs, rewind - dec->skip_bits);

        dec->needs_flush = 0;
        dec->code_value = 0;
        dec->low = 0;
        dec->high = AAM_TOP;
        dec->zero_run = 0;
        dec->used_bits = dec->read_bits = 0;
}

void gp_bifs_aa_dec_flush(GF_AADecoder *dec)
{
        if (!bit_out_psc_layer(dec)) return;
        dec->code_value = 2 * dec->code_value + dec->Bit;
        if (!bit_out_psc_layer(dec)) return;
        dec->code_value = (2 * dec->code_value + dec->Bit) & AAM_TOP;

        dec->low = 0;
        dec->high = AAM_TOP;
        dec->zero_run = 0;
}

void gp_bifs_aa_dec_resync_bit(GF_AADecoder *dec)
{
        if (dec->needs_flush && (dec->skip_bits < 16))
                gf_bs_rewind_bits(dec->bs, 16 - dec->skip_bits);

        dec->needs_flush = 0;
}

s32 gp_bifs_aa_dec_get_bit(GF_AADecoder *dec)
{
        /*get flag*/
        s32 res = dec->code_value >> 15;
        /*get next bit*/
        bit_out_psc_layer(dec);
        dec->code_value = (2 * dec->code_value + dec->Bit) & AAM_TOP;
        return res;
}

void gp_bifs_aa_dec_reset(GF_AADecoder *dec)
{
        s32 i;
        dec->code_value = 0;
        dec->low = 0;
        dec->high = AAM_TOP;
        dec->zero_run = 0;
        for (i=0; i < 16; i++) {
                if (!bit_out_psc_layer(dec)) return;
                dec->code_value = 2 * dec->code_value + dec->Bit;
        }
        dec->used_bits = 0;
}


static s32 AADec_Dec(GF_AADecoder *dec, GF_AAModel *model)
{
        u32 sac_index, len;
        s32 sum;

        len = dec->high - dec->low + 1;
        sum = (-1 + (dec->code_value - dec->low + 1) * model->cumul_freq[0]) / len;

        for (sac_index = 1; model->cumul_freq[sac_index] > sum; sac_index++) {
        }
        dec->high = dec->low - 1 + (len * model->cumul_freq[sac_index-1]) / model->cumul_freq[0];
        dec->low += (len * model->cumul_freq[sac_index]) / model->cumul_freq[0];

        for ( ; ; ) {
                if (dec->high < AAM_Q2) {
                } else if (dec->low >= AAM_Q2) {
                        dec->code_value -= AAM_Q2;
                        dec->low -= AAM_Q2;
                        dec->high -= AAM_Q2;
                }
                else if (dec->low >= AAM_Q1 && dec->high < AAM_Q3) {
                        dec->code_value -= AAM_Q1;
                        dec->low -= AAM_Q1;
                        dec->high -= AAM_Q1;
                } else {
                        break;
                }

                dec->low *= 2;
                dec->high = 2 * dec->high + 1;
                if (!bit_out_psc_layer(dec)) return -1;
                dec->code_value = 2 * dec->code_value + dec->Bit;
                dec->used_bits++;
        }
        return (sac_index - 1);
}

s32 gp_bifs_aa_decode(GF_AADecoder *dec, GF_AAModel *model)
{
        s32 v;
        v = AADec_Dec(dec, model);
        UpdateAAModel(model, v);
        return v;
}

#endif /*GPAC_ENABLE_BIFS_PMF*/


/* [<][>][^][v][top][bottom][index][help] */