put_bits.h 6.74 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
 *
 * 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
 */

/**
22
 * @file
23 24 25 26 27 28 29
 * bitstream writer API
 */

#ifndef AVCODEC_PUT_BITS_H
#define AVCODEC_PUT_BITS_H

#include <stdint.h>
30
#include <stddef.h>
31

32
#include "libavutil/intreadwrite.h"
33
#include "libavutil/avassert.h"
34 35 36 37 38 39 40 41 42

typedef struct PutBitContext {
    uint32_t bit_buf;
    int bit_left;
    uint8_t *buf, *buf_ptr, *buf_end;
    int size_in_bits;
} PutBitContext;

/**
43
 * Initialize the PutBitContext s.
44 45
 *
 * @param buffer the buffer where to put bits
46
 * @param buffer_size the size in bytes of buffer
47
 */
48 49
static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
                                 int buffer_size)
50
{
51
    if (buffer_size < 0) {
52
        buffer_size = 0;
53
        buffer      = NULL;
54 55
    }

56 57 58 59 60 61
    s->size_in_bits = 8 * buffer_size;
    s->buf          = buffer;
    s->buf_end      = s->buf + buffer_size;
    s->buf_ptr      = s->buf;
    s->bit_left     = 32;
    s->bit_buf      = 0;
62 63
}

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
/**
 * Rebase the bit writer onto a reallocated buffer.
 *
 * @param buffer the buffer where to put bits
 * @param buffer_size the size in bytes of buffer,
 *                    must be larger than the previous size
 */
static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
                                   int buffer_size)
{
    av_assert0(8*buffer_size > s->size_in_bits);

    s->buf_end = buffer + buffer_size;
    s->buf_ptr = buffer + (s->buf_ptr - s->buf);
    s->buf     = buffer;
    s->size_in_bits = 8 * buffer_size;
}

82
/**
83
 * @return the total number of bits written to the bitstream.
84 85 86 87 88 89
 */
static inline int put_bits_count(PutBitContext *s)
{
    return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
}

90 91 92 93 94 95 96 97
/**
 * @return the number of bits available in the bitstream.
 */
static inline int put_bits_left(PutBitContext* s)
{
    return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left;
}

98
/**
99
 * Pad the end of the output stream with zeros.
100 101 102 103
 */
static inline void flush_put_bits(PutBitContext *s)
{
#ifndef BITSTREAM_WRITER_LE
104
    if (s->bit_left < 32)
105
        s->bit_buf <<= s->bit_left;
106 107
#endif
    while (s->bit_left < 32) {
108
        av_assert0(s->buf_ptr < s->buf_end);
109
#ifdef BITSTREAM_WRITER_LE
110 111
        *s->buf_ptr++ = s->bit_buf;
        s->bit_buf  >>= 8;
112
#else
113 114
        *s->buf_ptr++ = s->bit_buf >> 24;
        s->bit_buf  <<= 8;
115
#endif
116
        s->bit_left  += 8;
117
    }
118 119
    s->bit_left = 32;
    s->bit_buf  = 0;
120 121
}

122
#ifdef BITSTREAM_WRITER_LE
123
#define avpriv_align_put_bits align_put_bits_unsupported_here
124
#define avpriv_put_string ff_put_string_unsupported_here
125
#define avpriv_copy_bits avpriv_copy_bits_unsupported_here
126
#else
127
/**
128
 * Pad the bitstream with zeros up to the next byte boundary.
129
 */
130
void avpriv_align_put_bits(PutBitContext *s);
131 132

/**
133
 * Put the string string in the bitstream.
134 135 136
 *
 * @param terminate_string 0-terminates the written string if value is 1
 */
137 138
void avpriv_put_string(PutBitContext *pb, const char *string,
                       int terminate_string);
139 140

/**
141
 * Copy the content of src to the bitstream.
142
 *
143
 * @param length the number of bits of src to copy
144
 */
145
void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
146
#endif
147

148
/**
149
 * Write up to 31 bits into a bitstream.
150 151
 * Use put_bits32 to write 32 bits.
 */
152 153 154 155 156
static inline void put_bits(PutBitContext *s, int n, unsigned int value)
{
    unsigned int bit_buf;
    int bit_left;

157
    av_assert2(n <= 31 && value < (1U << n));
158

159
    bit_buf  = s->bit_buf;
160 161 162 163 164 165
    bit_left = s->bit_left;

    /* XXX: optimize */
#ifdef BITSTREAM_WRITER_LE
    bit_buf |= value << (32 - bit_left);
    if (n >= bit_left) {
166 167 168 169 170 171 172
        if (3 < s->buf_end - s->buf_ptr) {
            AV_WL32(s->buf_ptr, bit_buf);
            s->buf_ptr += 4;
        } else {
            av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
            av_assert2(0);
        }
173
        bit_buf     = value >> bit_left;
174
        bit_left   += 32;
175
    }
176
    bit_left -= n;
177 178
#else
    if (n < bit_left) {
179 180
        bit_buf     = (bit_buf << n) | value;
        bit_left   -= n;
181
    } else {
182 183
        bit_buf   <<= bit_left;
        bit_buf    |= value >> (n - bit_left);
184 185 186 187 188 189 190
        if (3 < s->buf_end - s->buf_ptr) {
            AV_WB32(s->buf_ptr, bit_buf);
            s->buf_ptr += 4;
        } else {
            av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
            av_assert2(0);
        }
191 192
        bit_left   += 32 - n;
        bit_buf     = value;
193 194 195
    }
#endif

196
    s->bit_buf  = bit_buf;
197 198 199
    s->bit_left = bit_left;
}

200
static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
201
{
202
    av_assert2(n >= 0 && n <= 31);
203

204
    put_bits(pb, n, av_mod_uintp2(value, n));
205 206
}

207
/**
208
 * Write exactly 32 bits into a bitstream.
209 210 211 212 213
 */
static void av_unused put_bits32(PutBitContext *s, uint32_t value)
{
    int lo = value & 0xffff;
    int hi = value >> 16;
214
#ifdef BITSTREAM_WRITER_LE
215 216 217 218 219 220 221 222
    put_bits(s, 16, lo);
    put_bits(s, 16, hi);
#else
    put_bits(s, 16, hi);
    put_bits(s, 16, lo);
#endif
}

Stefano Sabatini's avatar
Stefano Sabatini committed
223
/**
224
 * Return the pointer to the byte where the bitstream writer will put
Stefano Sabatini's avatar
Stefano Sabatini committed
225 226
 * the next bit.
 */
227
static inline uint8_t *put_bits_ptr(PutBitContext *s)
228
{
229
    return s->buf_ptr;
230 231 232
}

/**
233
 * Skip the given number of bytes.
234 235
 * PutBitContext must be flushed & aligned to a byte boundary before calling this.
 */
236 237
static inline void skip_put_bytes(PutBitContext *s, int n)
{
238 239
    av_assert2((put_bits_count(s) & 7) == 0);
    av_assert2(s->bit_left == 32);
240
    av_assert0(n <= s->buf_end - s->buf_ptr);
241
    s->buf_ptr += n;
242 243 244
}

/**
245
 * Skip the given number of bits.
246
 * Must only be used if the actual values in the bitstream do not matter.
247
 * If n is 0 the behavior is undefined.
248
 */
249 250
static inline void skip_put_bits(PutBitContext *s, int n)
{
251
    s->bit_left -= n;
252
    s->buf_ptr  -= 4 * (s->bit_left >> 5);
253 254 255 256
    s->bit_left &= 31;
}

/**
257
 * Change the end of the buffer.
258 259 260
 *
 * @param size the new size in bytes of the buffer where to put bits
 */
261 262
static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
{
263
    av_assert0(size <= INT_MAX/8 - 32);
264
    s->buf_end = s->buf + size;
265
    s->size_in_bits = 8*size;
266 267 268
}

#endif /* AVCODEC_PUT_BITS_H */