1/* 2 * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21/** 22 * @file 23 * bitstream writer API 24 */ 25 26#ifndef AVCODEC_PUT_BITS_H 27#define AVCODEC_PUT_BITS_H 28 29#include <stdint.h> 30#include <stddef.h> 31#include <assert.h> 32 33#include "libavutil/intreadwrite.h" 34#include "libavutil/avassert.h" 35 36typedef struct PutBitContext { 37 uint32_t bit_buf; 38 int bit_left; 39 uint8_t *buf, *buf_ptr, *buf_end; 40 int size_in_bits; 41} PutBitContext; 42 43/** 44 * Initialize the PutBitContext s. 45 * 46 * @param buffer the buffer where to put bits 47 * @param buffer_size the size in bytes of buffer 48 */ 49static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, 50 int buffer_size) 51{ 52 if (buffer_size < 0) { 53 buffer_size = 0; 54 buffer = NULL; 55 } 56 57 s->size_in_bits = 8 * buffer_size; 58 s->buf = buffer; 59 s->buf_end = s->buf + buffer_size; 60 s->buf_ptr = s->buf; 61 s->bit_left = 32; 62 s->bit_buf = 0; 63} 64 65/** 66 * @return the total number of bits written to the bitstream. 67 */ 68static inline int put_bits_count(PutBitContext *s) 69{ 70 return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; 71} 72 73/** 74 * @return the number of bits available in the bitstream. 75 */ 76static inline int put_bits_left(PutBitContext* s) 77{ 78 return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left; 79} 80 81/** 82 * Pad the end of the output stream with zeros. 83 */ 84static inline void flush_put_bits(PutBitContext *s) 85{ 86#ifndef BITSTREAM_WRITER_LE 87 if (s->bit_left < 32) 88 s->bit_buf <<= s->bit_left; 89#endif 90 while (s->bit_left < 32) { 91 /* XXX: should test end of buffer */ 92#ifdef BITSTREAM_WRITER_LE 93 *s->buf_ptr++ = s->bit_buf; 94 s->bit_buf >>= 8; 95#else 96 *s->buf_ptr++ = s->bit_buf >> 24; 97 s->bit_buf <<= 8; 98#endif 99 s->bit_left += 8; 100 } 101 s->bit_left = 32; 102 s->bit_buf = 0; 103} 104 105#ifdef BITSTREAM_WRITER_LE 106#define avpriv_align_put_bits align_put_bits_unsupported_here 107#define avpriv_put_string ff_put_string_unsupported_here 108#define avpriv_copy_bits avpriv_copy_bits_unsupported_here 109#else 110/** 111 * Pad the bitstream with zeros up to the next byte boundary. 112 */ 113void avpriv_align_put_bits(PutBitContext *s); 114 115/** 116 * Put the string string in the bitstream. 117 * 118 * @param terminate_string 0-terminates the written string if value is 1 119 */ 120void avpriv_put_string(PutBitContext *pb, const char *string, 121 int terminate_string); 122 123/** 124 * Copy the content of src to the bitstream. 125 * 126 * @param length the number of bits of src to copy 127 */ 128void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length); 129#endif 130 131/** 132 * Write up to 31 bits into a bitstream. 133 * Use put_bits32 to write 32 bits. 134 */ 135static inline void put_bits(PutBitContext *s, int n, unsigned int value) 136{ 137 unsigned int bit_buf; 138 int bit_left; 139 140 av_assert2(n <= 31 && value < (1U << n)); 141 142 bit_buf = s->bit_buf; 143 bit_left = s->bit_left; 144 145 /* XXX: optimize */ 146#ifdef BITSTREAM_WRITER_LE 147 bit_buf |= value << (32 - bit_left); 148 if (n >= bit_left) { 149 av_assert2(s->buf_ptr+3<s->buf_end); 150 AV_WL32(s->buf_ptr, bit_buf); 151 s->buf_ptr += 4; 152 bit_buf = (bit_left == 32) ? 0 : value >> bit_left; 153 bit_left += 32; 154 } 155 bit_left -= n; 156#else 157 if (n < bit_left) { 158 bit_buf = (bit_buf << n) | value; 159 bit_left -= n; 160 } else { 161 bit_buf <<= bit_left; 162 bit_buf |= value >> (n - bit_left); 163 av_assert2(s->buf_ptr+3<s->buf_end); 164 AV_WB32(s->buf_ptr, bit_buf); 165 s->buf_ptr += 4; 166 bit_left += 32 - n; 167 bit_buf = value; 168 } 169#endif 170 171 s->bit_buf = bit_buf; 172 s->bit_left = bit_left; 173} 174 175static inline void put_sbits(PutBitContext *pb, int n, int32_t value) 176{ 177 av_assert2(n >= 0 && n <= 31); 178 179 put_bits(pb, n, value & ((1 << n) - 1)); 180} 181 182/** 183 * Write exactly 32 bits into a bitstream. 184 */ 185static void av_unused put_bits32(PutBitContext *s, uint32_t value) 186{ 187 int lo = value & 0xffff; 188 int hi = value >> 16; 189#ifdef BITSTREAM_WRITER_LE 190 put_bits(s, 16, lo); 191 put_bits(s, 16, hi); 192#else 193 put_bits(s, 16, hi); 194 put_bits(s, 16, lo); 195#endif 196} 197 198/** 199 * Return the pointer to the byte where the bitstream writer will put 200 * the next bit. 201 */ 202static inline uint8_t *put_bits_ptr(PutBitContext *s) 203{ 204 return s->buf_ptr; 205} 206 207/** 208 * Skip the given number of bytes. 209 * PutBitContext must be flushed & aligned to a byte boundary before calling this. 210 */ 211static inline void skip_put_bytes(PutBitContext *s, int n) 212{ 213 av_assert2((put_bits_count(s) & 7) == 0); 214 av_assert2(s->bit_left == 32); 215 s->buf_ptr += n; 216} 217 218/** 219 * Skip the given number of bits. 220 * Must only be used if the actual values in the bitstream do not matter. 221 * If n is 0 the behavior is undefined. 222 */ 223static inline void skip_put_bits(PutBitContext *s, int n) 224{ 225 s->bit_left -= n; 226 s->buf_ptr -= 4 * (s->bit_left >> 5); 227 s->bit_left &= 31; 228} 229 230/** 231 * Change the end of the buffer. 232 * 233 * @param size the new size in bytes of the buffer where to put bits 234 */ 235static inline void set_put_bits_buffer_size(PutBitContext *s, int size) 236{ 237 s->buf_end = s->buf + size; 238} 239 240#endif /* AVCODEC_PUT_BITS_H */ 241