annotate libavcodec/get_bits.h @ 4:96e628866d41

naming some tasks to help debugging
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Wed, 19 Dec 2012 15:40:26 +0100
parents
children
rev   line source
nengel@2 1 /*
nengel@2 2 * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
nengel@2 3 *
nengel@2 4 * This file is part of FFmpeg.
nengel@2 5 *
nengel@2 6 * FFmpeg is free software; you can redistribute it and/or
nengel@2 7 * modify it under the terms of the GNU Lesser General Public
nengel@2 8 * License as published by the Free Software Foundation; either
nengel@2 9 * version 2.1 of the License, or (at your option) any later version.
nengel@2 10 *
nengel@2 11 * FFmpeg is distributed in the hope that it will be useful,
nengel@2 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nengel@2 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
nengel@2 14 * Lesser General Public License for more details.
nengel@2 15 *
nengel@2 16 * You should have received a copy of the GNU Lesser General Public
nengel@2 17 * License along with FFmpeg; if not, write to the Free Software
nengel@2 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
nengel@2 19 */
nengel@2 20
nengel@2 21 /**
nengel@2 22 * @file
nengel@2 23 * bitstream reader API header.
nengel@2 24 */
nengel@2 25
nengel@2 26 #ifndef AVCODEC_GET_BITS_H
nengel@2 27 #define AVCODEC_GET_BITS_H
nengel@2 28
nengel@2 29 #include <stdint.h>
nengel@2 30 #include <stdlib.h>
nengel@2 31 #include <assert.h>
nengel@2 32 #include "libavutil/bswap.h"
nengel@2 33 #include "libavutil/common.h"
nengel@2 34 #include "libavutil/intreadwrite.h"
nengel@2 35 #include "libavutil/log.h"
nengel@2 36 #include "mathops.h"
nengel@2 37
nengel@2 38
nengel@2 39 typedef struct GetBitContext {
nengel@2 40 uint8_t *rbsp;
nengel@2 41 unsigned int rbsp_size;
nengel@2 42 uint8_t *raw;
nengel@2 43 const uint8_t *buffer, *buffer_end;
nengel@2 44 unsigned int alloc_size;
nengel@2 45 unsigned int buf_size;
nengel@2 46 uint32_t *buffer_ptr;
nengel@2 47 uint32_t cache0;
nengel@2 48 uint32_t cache1;
nengel@2 49 int bit_count;
nengel@2 50 int size_in_bits;
nengel@2 51 } GetBitContext;
nengel@2 52
nengel@2 53 /* Bitstream reader API docs:
nengel@2 54 name
nengel@2 55 arbitrary name which is used as prefix for the internal variables
nengel@2 56
nengel@2 57 gb
nengel@2 58 getbitcontext
nengel@2 59
nengel@2 60 OPEN_READER(name, gb)
nengel@2 61 loads gb into local variables
nengel@2 62
nengel@2 63 CLOSE_READER(name, gb)
nengel@2 64 stores local vars in gb
nengel@2 65
nengel@2 66 UPDATE_CACHE(name, gb)
nengel@2 67 refills the internal cache from the bitstream
nengel@2 68 after this call at least MIN_CACHE_BITS will be available,
nengel@2 69
nengel@2 70 GET_CACHE(name, gb)
nengel@2 71 will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit)
nengel@2 72
nengel@2 73 SHOW_UBITS(name, gb, num)
nengel@2 74 will return the next num bits
nengel@2 75
nengel@2 76 SHOW_SBITS(name, gb, num)
nengel@2 77 will return the next num bits and do sign extension
nengel@2 78
nengel@2 79 SKIP_BITS(name, gb, num)
nengel@2 80 will skip over the next num bits
nengel@2 81 note, this is equivalent to SKIP_CACHE; SKIP_COUNTER
nengel@2 82
nengel@2 83 SKIP_CACHE(name, gb, num)
nengel@2 84 will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER)
nengel@2 85
nengel@2 86 SKIP_COUNTER(name, gb, num)
nengel@2 87 will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS)
nengel@2 88
nengel@2 89 LAST_SKIP_CACHE(name, gb, num)
nengel@2 90 will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing
nengel@2 91
nengel@2 92 LAST_SKIP_BITS(name, gb, num)
nengel@2 93 is equivalent to LAST_SKIP_CACHE; SKIP_COUNTER
nengel@2 94
nengel@2 95 for examples see get_bits, show_bits, skip_bits, get_vlc
nengel@2 96 */
nengel@2 97
nengel@2 98 #define MIN_CACHE_BITS 32
nengel@2 99
nengel@2 100 #define OPEN_READER(name, gb)\
nengel@2 101 int name##_bit_count=(gb)->bit_count;\
nengel@2 102 uint32_t name##_cache0= (gb)->cache0;\
nengel@2 103 uint32_t name##_cache1= (gb)->cache1;\
nengel@2 104 uint32_t * name##_buffer_ptr=(gb)->buffer_ptr;\
nengel@2 105
nengel@2 106 #define CLOSE_READER(name, gb)\
nengel@2 107 (gb)->bit_count= name##_bit_count;\
nengel@2 108 (gb)->cache0= name##_cache0;\
nengel@2 109 (gb)->cache1= name##_cache1;\
nengel@2 110 (gb)->buffer_ptr= name##_buffer_ptr;\
nengel@2 111
nengel@2 112 #define UPDATE_CACHE(name, gb)\
nengel@2 113 if(name##_bit_count > 0){\
nengel@2 114 const uint32_t next= be2me_32( *name##_buffer_ptr );\
nengel@2 115 name##_cache0 |= NEG_USR32(next,name##_bit_count);\
nengel@2 116 name##_cache1 |= next<<name##_bit_count;\
nengel@2 117 name##_buffer_ptr++;\
nengel@2 118 name##_bit_count-= 32;\
nengel@2 119 }\
nengel@2 120
nengel@2 121 #if ARCH_X86
nengel@2 122 # define SKIP_CACHE(name, gb, num)\
nengel@2 123 __asm__(\
nengel@2 124 "shldl %2, %1, %0 \n\t"\
nengel@2 125 "shll %2, %1 \n\t"\
nengel@2 126 : "+r" (name##_cache0), "+r" (name##_cache1)\
nengel@2 127 : "Ic" ((uint8_t)(num))\
nengel@2 128 );
nengel@2 129 #else
nengel@2 130 # define SKIP_CACHE(name, gb, num)\
nengel@2 131 name##_cache0 <<= (num);\
nengel@2 132 name##_cache0 |= NEG_USR32(name##_cache1,num);\
nengel@2 133 name##_cache1 <<= (num);
nengel@2 134 #endif
nengel@2 135
nengel@2 136 #define SKIP_COUNTER(name, gb, num)\
nengel@2 137 name##_bit_count += (num);\
nengel@2 138
nengel@2 139 #define SKIP_BITS(name, gb, num)\
nengel@2 140 {\
nengel@2 141 SKIP_CACHE(name, gb, num)\
nengel@2 142 SKIP_COUNTER(name, gb, num)\
nengel@2 143 }\
nengel@2 144
nengel@2 145 #define LAST_SKIP_BITS(name, gb, num) SKIP_BITS(name, gb, num)
nengel@2 146 #define LAST_SKIP_CACHE(name, gb, num) SKIP_CACHE(name, gb, num)
nengel@2 147
nengel@2 148 #define SHOW_UBITS(name, gb, num)\
nengel@2 149 NEG_USR32(name##_cache0, num)
nengel@2 150
nengel@2 151 #define SHOW_SBITS(name, gb, num)\
nengel@2 152 NEG_SSR32(name##_cache0, num)
nengel@2 153
nengel@2 154 #define GET_CACHE(name, gb)\
nengel@2 155 (name##_cache0)
nengel@2 156
nengel@2 157 static inline int get_bits_count(const GetBitContext *s){
nengel@2 158 return ((uint8_t*)s->buffer_ptr - s->buffer)*8 - 32 + s->bit_count;
nengel@2 159 }
nengel@2 160
nengel@2 161 static inline void skip_bits_long(GetBitContext *s, int n){
nengel@2 162 OPEN_READER(re, s)
nengel@2 163 re_bit_count += n;
nengel@2 164 re_buffer_ptr += re_bit_count>>5;
nengel@2 165 re_bit_count &= 31;
nengel@2 166 re_cache0 = be2me_32( re_buffer_ptr[-1] ) << re_bit_count;
nengel@2 167 re_cache1 = 0;
nengel@2 168 UPDATE_CACHE(re, s)
nengel@2 169 CLOSE_READER(re, s)
nengel@2 170 }
nengel@2 171
nengel@2 172 /**
nengel@2 173 * read mpeg1 dc style vlc (sign bit + mantisse with no MSB).
nengel@2 174 * if MSB not set it is negative
nengel@2 175 * @param n length in bits
nengel@2 176 * @author BERO
nengel@2 177 */
nengel@2 178 static inline int get_xbits(GetBitContext *s, int n){
nengel@2 179 register int sign;
nengel@2 180 register int32_t cache;
nengel@2 181 OPEN_READER(re, s)
nengel@2 182 UPDATE_CACHE(re, s)
nengel@2 183 cache = GET_CACHE(re,s);
nengel@2 184 sign=(~cache)>>31;
nengel@2 185 LAST_SKIP_BITS(re, s, n)
nengel@2 186 CLOSE_READER(re, s)
nengel@2 187 return (NEG_USR32(sign ^ cache, n) ^ sign) - sign;
nengel@2 188 }
nengel@2 189
nengel@2 190 static inline int get_sbits(GetBitContext *s, int n){
nengel@2 191 register int tmp;
nengel@2 192 OPEN_READER(re, s)
nengel@2 193 UPDATE_CACHE(re, s)
nengel@2 194 tmp= SHOW_SBITS(re, s, n);
nengel@2 195 LAST_SKIP_BITS(re, s, n)
nengel@2 196 CLOSE_READER(re, s)
nengel@2 197 return tmp;
nengel@2 198 }
nengel@2 199
nengel@2 200 /**
nengel@2 201 * reads 1-17 bits.
nengel@2 202 * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't
nengel@2 203 */
nengel@2 204 static inline unsigned int get_bits(GetBitContext *s, int n){
nengel@2 205 register int tmp;
nengel@2 206 OPEN_READER(re, s)
nengel@2 207 UPDATE_CACHE(re, s)
nengel@2 208 tmp= SHOW_UBITS(re, s, n);
nengel@2 209 LAST_SKIP_BITS(re, s, n)
nengel@2 210 CLOSE_READER(re, s)
nengel@2 211 return tmp;
nengel@2 212 }
nengel@2 213
nengel@2 214 /**
nengel@2 215 * shows 1-17 bits.
nengel@2 216 * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't
nengel@2 217 */
nengel@2 218 static inline unsigned int show_bits(GetBitContext *s, int n){
nengel@2 219 register int tmp;
nengel@2 220 OPEN_READER(re, s)
nengel@2 221 UPDATE_CACHE(re, s)
nengel@2 222 tmp= SHOW_UBITS(re, s, n);
nengel@2 223 // CLOSE_READER(re, s)
nengel@2 224 return tmp;
nengel@2 225 }
nengel@2 226
nengel@2 227 static inline void skip_bits(GetBitContext *s, int n){
nengel@2 228 //Note gcc seems to optimize this to s->index+=n for the ALT_READER :))
nengel@2 229 OPEN_READER(re, s)
nengel@2 230 UPDATE_CACHE(re, s)
nengel@2 231 LAST_SKIP_BITS(re, s, n)
nengel@2 232 CLOSE_READER(re, s)
nengel@2 233 }
nengel@2 234
nengel@2 235 static inline unsigned int get_bits1(GetBitContext *s){
nengel@2 236 return get_bits(s, 1);
nengel@2 237 }
nengel@2 238
nengel@2 239 static inline unsigned int show_bits1(GetBitContext *s){
nengel@2 240 return show_bits(s, 1);
nengel@2 241 }
nengel@2 242
nengel@2 243 static inline void skip_bits1(GetBitContext *s){
nengel@2 244 skip_bits(s, 1);
nengel@2 245 }
nengel@2 246
nengel@2 247 /**
nengel@2 248 * reads 0-32 bits.
nengel@2 249 */
nengel@2 250 static inline unsigned int get_bits_long(GetBitContext *s, int n){
nengel@2 251 if(n<=MIN_CACHE_BITS) return get_bits(s, n);
nengel@2 252 else{
nengel@2 253 int ret= get_bits(s, 16) << (n-16);
nengel@2 254 return ret | get_bits(s, n-16);
nengel@2 255 }
nengel@2 256 }
nengel@2 257
nengel@2 258 /**
nengel@2 259 * reads 0-32 bits as a signed integer.
nengel@2 260 */
nengel@2 261 static inline int get_sbits_long(GetBitContext *s, int n) {
nengel@2 262 return sign_extend(get_bits_long(s, n), n);
nengel@2 263 }
nengel@2 264
nengel@2 265 /**
nengel@2 266 * shows 0-32 bits.
nengel@2 267 */
nengel@2 268 static inline unsigned int show_bits_long(GetBitContext *s, int n){
nengel@2 269 if(n<=MIN_CACHE_BITS) return show_bits(s, n);
nengel@2 270 else{
nengel@2 271 GetBitContext gb= *s;
nengel@2 272 return get_bits_long(&gb, n);
nengel@2 273 }
nengel@2 274 }
nengel@2 275
nengel@2 276 static inline int check_marker(GetBitContext *s, const char *msg)
nengel@2 277 {
nengel@2 278 int bit= get_bits1(s);
nengel@2 279 if(!bit)
nengel@2 280 av_log(AV_LOG_INFO, "Marker bit missing %s\n", msg);
nengel@2 281
nengel@2 282 return bit;
nengel@2 283 }
nengel@2 284
nengel@2 285 /**
nengel@2 286 * init GetBitContext.
nengel@2 287 * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits
nengel@2 288 * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end
nengel@2 289 * @param bit_size the size of the buffer in bits
nengel@2 290 *
nengel@2 291 * While GetBitContext stores the buffer size, for performance reasons you are
nengel@2 292 * responsible for checking for the buffer end yourself (take advantage of the padding)!
nengel@2 293 */
nengel@2 294 static inline void init_get_bits(GetBitContext *s,
nengel@2 295 const uint8_t *buffer, int bit_size)
nengel@2 296 {
nengel@2 297 int buffer_size= (bit_size+7)>>3;
nengel@2 298 if(buffer_size < 0 || bit_size < 0) {
nengel@2 299 buffer_size = bit_size = 0;
nengel@2 300 buffer = NULL;
nengel@2 301 }
nengel@2 302
nengel@2 303 s->buffer= buffer;
nengel@2 304 s->size_in_bits= bit_size;
nengel@2 305 s->buffer_end= buffer + buffer_size;
nengel@2 306
nengel@2 307 s->buffer_ptr = (uint32_t*)((intptr_t)buffer&(~3));
nengel@2 308 s->bit_count = 32 + 8*((intptr_t)buffer&3);
nengel@2 309 skip_bits_long(s, 0);
nengel@2 310 }
nengel@2 311
nengel@2 312 static inline void align_get_bits(GetBitContext *s)
nengel@2 313 {
nengel@2 314 int n= (-get_bits_count(s)) & 7;
nengel@2 315 if(n) skip_bits(s, n);
nengel@2 316 }
nengel@2 317
nengel@2 318 #define tprintf(p, ...) {}
nengel@2 319
nengel@2 320 static inline int get_bits_left(GetBitContext *gb)
nengel@2 321 {
nengel@2 322 return gb->size_in_bits - get_bits_count(gb);
nengel@2 323 }
nengel@2 324
nengel@2 325 #endif /* AVCODEC_GET_BITS_H */