/* * Copyright (c) 2016 Alexandra Hájková * * This file is part of FFmpeg. * * FFmpeg 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.1 of the License, or (at your option) any later version. * * FFmpeg 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 FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file * bitstream reader API header. */ #ifndef AVCODEC_BITSTREAM_H #define AVCODEC_BITSTREAM_H #include #include "config.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "libavutil/log.h" #include "mathops.h" #include "vlc.h" #ifndef UNCHECKED_BITSTREAM_READER #define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER #endif typedef struct BitstreamContext { uint64_t bits; // stores bits read from the buffer const uint8_t *buffer, *buffer_end; const uint8_t *ptr; // pointer to the position inside a buffer unsigned bits_left; // number of bits left in bits field unsigned size_in_bits; } BitstreamContext; /** * Return number of bits already read. */ static inline int bitstream_tell(const BitstreamContext *bc) { return (bc->ptr - bc->buffer) * 8 - bc->bits_left; } /** * Return buffer size in bits. */ static inline int bitstream_tell_size(const BitstreamContext *bc) { return bc->size_in_bits; } /** * Return the number of the bits left in a buffer. */ static inline int bitstream_bits_left(const BitstreamContext *bc) { return (bc->buffer - bc->ptr) * 8 + bc->size_in_bits + bc->bits_left; } /* Unwind the cache so a refill_32 can fill it again. */ static inline void bitstream_unwind(BitstreamContext *bc) { int unwind = 4; int unwind_bits = unwind * 8; if (bc->bits_left < unwind_bits) return; bc->bits >>= unwind_bits; bc->bits <<= unwind_bits; bc->bits_left -= unwind_bits; bc->ptr -= unwind; } /* Unget up to 32 bits. */ static inline void bitstream_unget(BitstreamContext *bc, uint64_t value, size_t amount) { size_t cache_size = sizeof(bc->bits) * 8; if (bc->bits_left + amount > cache_size) bitstream_unwind(bc); bc->bits = (bc->bits >> amount) | (value << (cache_size - amount)); bc->bits_left += amount; } #define BITSTREAM_LE #include "bitstream_template.h" #undef BITSTREAM_LE #include "bitstream_template.h" #define bitstream_init bitstream_init_be #define bitstream_init8 bitstream_init8_be #define bitstream_read_bit bitstream_read_bit_be #define bitstream_read_63 bitstream_read_63_be #define bitstream_read bitstream_read_be #define bitstream_read_signed bitstream_read_signed_be #define bitstream_peek bitstream_peek_be #define bitstream_peek_signed bitstream_peek_signed_be #define bitstream_skip bitstream_skip_be #define bitstream_skip_cache bitstream_skip_cache_be #define bitstream_seek bitstream_seek_be #define bitstream_align bitstream_align_be #define bitstream_read_xbits bitstream_read_xbits_be #define bitstream_decode012 bitstream_decode012_be #define bitstream_decode210 bitstream_decode210_be #define bitstream_apply_sign bitstream_apply_sign_be #define bitstream_read_vlc bitstream_read_vlc_be #define BITSTREAM_RL_VLC(level, run, bc, table, bits, max_depth) \ do { \ int n, nb_bits; \ unsigned int index = bitstream_peek(bc, bits); \ level = table[index].level; \ n = table[index].len; \ \ if (max_depth > 1 && n < 0) { \ bitstream_skip(bc, bits); \ \ nb_bits = -n; \ \ index = bitstream_peek(bc, nb_bits) + level; \ level = table[index].level; \ n = table[index].len; \ if (max_depth > 2 && n < 0) { \ bitstream_skip(bc, nb_bits); \ nb_bits = -n; \ \ index = bitstream_peek(bc, nb_bits) + level; \ level = table[index].level; \ n = table[index].len; \ } \ } \ run = table[index].run; \ bitstream_skip(bc, n); \ } while (0) #endif /* AVCODEC_BITSTREAM_H */