• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/rangecoder.h

Go to the documentation of this file.
00001 /*
00002  * Range coder
00003  * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #ifndef AVCODEC_RANGECODER_H
00028 #define AVCODEC_RANGECODER_H
00029 
00030 #include <stdint.h>
00031 #include <assert.h>
00032 #include "libavutil/common.h"
00033 
00034 typedef struct RangeCoder{
00035     int low;
00036     int range;
00037     int outstanding_count;
00038     int outstanding_byte;
00039     uint8_t zero_state[256];
00040     uint8_t  one_state[256];
00041     uint8_t *bytestream_start;
00042     uint8_t *bytestream;
00043     uint8_t *bytestream_end;
00044 }RangeCoder;
00045 
00046 void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size);
00047 void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size);
00048 int ff_rac_terminate(RangeCoder *c);
00049 void ff_build_rac_states(RangeCoder *c, int factor, int max_p);
00050 
00051 static inline void renorm_encoder(RangeCoder *c){
00052     //FIXME optimize
00053     while(c->range < 0x100){
00054         if(c->outstanding_byte < 0){
00055             c->outstanding_byte= c->low>>8;
00056         }else if(c->low <= 0xFF00){
00057             *c->bytestream++ = c->outstanding_byte;
00058             for(;c->outstanding_count; c->outstanding_count--)
00059                 *c->bytestream++ = 0xFF;
00060             c->outstanding_byte= c->low>>8;
00061         }else if(c->low >= 0x10000){
00062             *c->bytestream++ = c->outstanding_byte + 1;
00063             for(;c->outstanding_count; c->outstanding_count--)
00064                 *c->bytestream++ = 0x00;
00065             c->outstanding_byte= (c->low>>8) & 0xFF;
00066         }else{
00067             c->outstanding_count++;
00068         }
00069 
00070         c->low = (c->low & 0xFF)<<8;
00071         c->range <<= 8;
00072     }
00073 }
00074 
00075 static inline int get_rac_count(RangeCoder *c){
00076     int x= c->bytestream - c->bytestream_start + c->outstanding_count;
00077     if(c->outstanding_byte >= 0)
00078         x++;
00079     return 8*x - av_log2(c->range);
00080 }
00081 
00082 static inline void put_rac(RangeCoder *c, uint8_t * const state, int bit){
00083     int range1= (c->range * (*state)) >> 8;
00084 
00085     assert(*state);
00086     assert(range1 < c->range);
00087     assert(range1 > 0);
00088     if(!bit){
00089         c->range -= range1;
00090         *state= c->zero_state[*state];
00091     }else{
00092         c->low += c->range - range1;
00093         c->range = range1;
00094         *state= c->one_state[*state];
00095     }
00096 
00097     renorm_encoder(c);
00098 }
00099 
00100 static inline void refill(RangeCoder *c){
00101     if(c->range < 0x100){
00102         c->range <<= 8;
00103         c->low <<= 8;
00104         if(c->bytestream < c->bytestream_end)
00105             c->low+= c->bytestream[0];
00106         c->bytestream++;
00107     }
00108 }
00109 
00110 static inline int get_rac(RangeCoder *c, uint8_t * const state){
00111     int range1= (c->range * (*state)) >> 8;
00112     int av_unused one_mask;
00113 
00114     c->range -= range1;
00115 #if 1
00116     if(c->low < c->range){
00117         *state= c->zero_state[*state];
00118         refill(c);
00119         return 0;
00120     }else{
00121         c->low -= c->range;
00122         *state= c->one_state[*state];
00123         c->range = range1;
00124         refill(c);
00125         return 1;
00126     }
00127 #else
00128     one_mask= (c->range - c->low-1)>>31;
00129 
00130     c->low -= c->range & one_mask;
00131     c->range += (range1 - c->range) & one_mask;
00132 
00133     *state= c->zero_state[(*state) + (256&one_mask)];
00134 
00135     refill(c);
00136 
00137     return one_mask&1;
00138 #endif
00139 }
00140 
00141 #endif /* AVCODEC_RANGECODER_H */

Generated on Fri Sep 16 2011 17:17:42 for FFmpeg by  doxygen 1.7.1