📄 arith_decoder.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * 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" /* 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 16383struct _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) free(model->cumul_freq); if (model->freq) free(model->freq); free(model);}void gp_bifs_aa_model_init(GF_AAModel *model, u32 nbBits){ s32 i; model->nb_symb = 1<<nbBits; if (model->cumul_freq) free(model->cumul_freq); if (model->freq) free(model->freq); model->freq = (s32*)malloc(sizeof(s32) * model->nb_symb); model->cumul_freq = (s32*)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){ 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -