• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  */
16 
17 #ifndef AVCODEC_PUT_BITS_H
18 #define AVCODEC_PUT_BITS_H
19 
20 #include <linux/kernel.h>
21 #include <linux/types.h>
22 #include "common.h"
23 
24 struct put_bits_context {
25 	u32 bit_buf;
26 	int bit_left;
27 	u8 *buf;
28 	u8 *buf_ptr;
29 	u8 *buf_end;
30 	int size_in_bits;
31 };
32 
33 /**
34  * Initialize the struct put_bits_context s.
35  *
36  * @param buffer the buffer where to put bits
37  * @param buffer_size the size in bytes of buffer
38  */
init_put_bits(struct put_bits_context * s,u8 * buffer,int buffer_size)39 static inline void init_put_bits(struct put_bits_context *s,
40 	u8 *buffer, int buffer_size)
41 {
42 	if (buffer_size < 0) {
43 		buffer_size = 0;
44 		buffer      = NULL;
45 	}
46 
47 	s->size_in_bits = 8 * buffer_size;
48 	s->buf          = buffer;
49 	s->buf_end      = s->buf + buffer_size;
50 	s->buf_ptr      = s->buf;
51 	s->bit_left     = 32;
52 	s->bit_buf      = 0;
53 }
54 
55 /**
56  * Rebase the bit writer onto a reallocated buffer.
57  *
58  * @param buffer the buffer where to put bits
59  * @param buffer_size the size in bytes of buffer,
60  *                    must be larger than the previous size
61  */
rebase_put_bits(struct put_bits_context * s,u8 * buffer,int buffer_size)62 static inline void rebase_put_bits(struct put_bits_context *s,
63 	u8 *buffer, int buffer_size)
64 {
65 	s->buf_end = buffer + buffer_size;
66 	s->buf_ptr = buffer + (s->buf_ptr - s->buf);
67 	s->buf     = buffer;
68 	s->size_in_bits = 8 * buffer_size;
69 }
70 
71 /**
72  * @return the total number of bits written to the bitstream.
73  */
put_bits_count(struct put_bits_context * s)74 static inline int put_bits_count(struct put_bits_context *s)
75 {
76 	return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
77 }
78 
79 /**
80  * @return the number of bits available in the bitstream.
81  */
put_bits_left(struct put_bits_context * s)82 static inline int put_bits_left(struct put_bits_context* s)
83 {
84 	return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left;
85 }
86 
87 /**
88  * Pad the end of the output stream with zeros.
89  */
flush_put_bits(struct put_bits_context * s)90 static inline void flush_put_bits(struct put_bits_context *s)
91 {
92 #ifndef BITSTREAM_WRITER_LE
93 	if (s->bit_left < 32)
94 		s->bit_buf <<= s->bit_left;
95 #endif
96 	while (s->bit_left < 32) {
97 #ifdef BITSTREAM_WRITER_LE
98 		*s->buf_ptr++ = s->bit_buf;
99 		s->bit_buf  >>= 8;
100 #else
101 		*s->buf_ptr++ = s->bit_buf >> 24;
102 		s->bit_buf  <<= 8;
103 #endif
104 		s->bit_left  += 8;
105 	}
106 	s->bit_left = 32;
107 	s->bit_buf  = 0;
108 }
109 
flush_put_bits_le(struct put_bits_context * s)110 static inline void flush_put_bits_le(struct put_bits_context *s)
111 {
112 	while (s->bit_left < 32) {
113 		*s->buf_ptr++ = s->bit_buf;
114 		s->bit_buf  >>= 8;
115 		s->bit_left  += 8;
116 	}
117 	s->bit_left = 32;
118 	s->bit_buf  = 0;
119 }
120 
121 #ifdef BITSTREAM_WRITER_LE
122 #define avpriv_align_put_bits align_put_bits_unsupported_here
123 #define avpriv_put_string ff_put_string_unsupported_here
124 #define avpriv_copy_bits avpriv_copy_bits_unsupported_here
125 #else
126 /**
127  * Pad the bitstream with zeros up to the next byte boundary.
128  */
129 void avpriv_align_put_bits(struct put_bits_context *s);
130 
131 /**
132  * Put the string string in the bitstream.
133  *
134  * @param terminate_string 0-terminates the written string if value is 1
135  */
136 void avpriv_put_string(struct put_bits_context *pb,
137 	const char *string, int terminate_string);
138 
139 /**
140  * Copy the content of src to the bitstream.
141  *
142  * @param length the number of bits of src to copy
143  */
144 void avpriv_copy_bits(struct put_bits_context *pb, const u8 *src, int length);
145 #endif
146 
147 /**
148  * Write up to 31 bits into a bitstream.
149  * Use put_bits32 to write 32 bits.
150  */
put_bits(struct put_bits_context * s,int n,u32 value)151 static inline void put_bits(struct put_bits_context *s, int n, u32 value)
152 {
153 	u32 bit_buf;
154 	int bit_left;
155 
156 	bit_buf  = s->bit_buf;
157 	bit_left = s->bit_left;
158 
159 	/* XXX: optimize */
160 #ifdef BITSTREAM_WRITER_LE
161 	bit_buf |= value << (32 - bit_left);
162 	if (n >= bit_left) {
163 		if (3 < s->buf_end - s->buf_ptr) {
164 			AV_WL32(s->buf_ptr, bit_buf);
165 			s->buf_ptr += 4;
166 		} else {
167 			pr_err("Internal error, put_bits buffer too small\n");
168 		}
169 		bit_buf     = value >> bit_left;
170 		bit_left   += 32;
171 	}
172 	bit_left -= n;
173 #else
174 	if (n < bit_left) {
175 		bit_buf     = (bit_buf << n) | value;
176 		bit_left   -= n;
177 	} else {
178 		bit_buf   <<= bit_left;
179 		bit_buf    |= value >> (n - bit_left);
180 		if (3 < s->buf_end - s->buf_ptr) {
181 			AV_WB32(s->buf_ptr, bit_buf);
182 			s->buf_ptr += 4;
183 		} else {
184 			pr_err("Internal error, put_bits buffer too small\n");
185 		}
186 		bit_left   += 32 - n;
187 		bit_buf     = value;
188 	}
189 #endif
190 	s->bit_buf  = bit_buf;
191 	s->bit_left = bit_left;
192 }
193 
put_bits_le(struct put_bits_context * s,int n,u32 value)194 static inline void put_bits_le(struct put_bits_context *s, int n, u32 value)
195 {
196 	u32 bit_buf;
197 	int bit_left;
198 
199 	bit_buf  = s->bit_buf;
200 	bit_left = s->bit_left;
201 
202 	bit_buf |= value << (32 - bit_left);
203 	if (n >= bit_left) {
204 		if (3 < s->buf_end - s->buf_ptr) {
205 			AV_WL32(s->buf_ptr, bit_buf);
206 			s->buf_ptr += 4;
207 		} else {
208 			pr_err("Internal error, put_bits buffer too small\n");
209 		}
210 		bit_buf     = value >> bit_left;
211 		bit_left   += 32;
212 	}
213 	bit_left -= n;
214 
215 	s->bit_buf  = bit_buf;
216 	s->bit_left = bit_left;
217 }
218 
av_mod_uintp2(u32 a,u32 p)219 static inline u32 av_mod_uintp2(u32 a, u32 p)
220 {
221 	return a & ((1 << p) - 1);
222 }
223 
put_sbits(struct put_bits_context * pb,int n,int32_t value)224 static inline void put_sbits(struct put_bits_context *pb, int n, int32_t value)
225 {
226 	put_bits(pb, n, av_mod_uintp2(value, n));
227 }
228 
229 /**
230  * Write exactly 32 bits into a bitstream.
231  */
put_bits32(struct put_bits_context * s,u32 value)232 static void put_bits32(struct put_bits_context *s, u32 value)
233 {
234 	u32 bit_buf;
235 	int bit_left;
236 
237 	bit_buf  = s->bit_buf;
238 	bit_left = s->bit_left;
239 
240 #ifdef BITSTREAM_WRITER_LE
241 	bit_buf |= value << (32 - bit_left);
242 	if (3 < s->buf_end - s->buf_ptr) {
243 		AV_WL32(s->buf_ptr, bit_buf);
244 		s->buf_ptr += 4;
245 	} else {
246 		pr_err("Internal error, put_bits buffer too small\n");
247 	}
248 	bit_buf     = (uint64_t)value >> bit_left;
249 #else
250 	bit_buf     = (uint64_t)bit_buf << bit_left;
251 	bit_buf    |= value >> (32 - bit_left);
252 	if (3 < s->buf_end - s->buf_ptr) {
253 		AV_WB32(s->buf_ptr, bit_buf);
254 		s->buf_ptr += 4;
255 	} else {
256 		pr_err("Internal error, put_bits buffer too small\n");
257 	}
258 	bit_buf     = value;
259 #endif
260 
261 	s->bit_buf  = bit_buf;
262 	s->bit_left = bit_left;
263 }
264 
265 /**
266  * Write up to 64 bits into a bitstream.
267  */
put_bits64(struct put_bits_context * s,int n,uint64_t value)268 static inline void put_bits64(struct put_bits_context *s, int n, uint64_t value)
269 {
270 	if (n < 32)
271 		put_bits(s, n, value);
272 	else if (n == 32)
273 		put_bits32(s, value);
274 	else if (n < 64) {
275 		u32 lo = value & 0xffffffff;
276 		u32 hi = value >> 32;
277 #ifdef BITSTREAM_WRITER_LE
278 		put_bits32(s, lo);
279 		put_bits(s, n - 32, hi);
280 #else
281 		put_bits(s, n - 32, hi);
282 		put_bits32(s, lo);
283 #endif
284 	} else {
285 		u32 lo = value & 0xffffffff;
286 		u32 hi = value >> 32;
287 #ifdef BITSTREAM_WRITER_LE
288 		put_bits32(s, lo);
289 		put_bits32(s, hi);
290 #else
291 		put_bits32(s, hi);
292 		put_bits32(s, lo);
293 #endif
294 	}
295 }
296 
297 /**
298  * Return the pointer to the byte where the bitstream writer will put
299  * the next bit.
300  */
put_bits_ptr(struct put_bits_context * s)301 static inline u8 *put_bits_ptr(struct put_bits_context *s)
302 {
303 	return s->buf_ptr;
304 }
305 
306 /**
307  * Skip the given number of bytes.
308  * struct put_bits_context must be flushed & aligned to a byte boundary before calling this.
309  */
skip_put_bytes(struct put_bits_context * s,int n)310 static inline void skip_put_bytes(struct put_bits_context *s, int n)
311 {
312 	s->buf_ptr += n;
313 }
314 
315 /**
316  * Skip the given number of bits.
317  * Must only be used if the actual values in the bitstream do not matter.
318  * If n is 0 the behavior is undefined.
319  */
skip_put_bits(struct put_bits_context * s,int n)320 static inline void skip_put_bits(struct put_bits_context *s, int n)
321 {
322 	s->bit_left -= n;
323 	s->buf_ptr  -= 4 * (s->bit_left >> 5);
324 	s->bit_left &= 31;
325 }
326 
327 /**
328  * Change the end of the buffer.
329  *
330  * @param size the new size in bytes of the buffer where to put bits
331  */
set_put_bits_buffer_size(struct put_bits_context * s,int size)332 static inline void set_put_bits_buffer_size(struct put_bits_context *s, int size)
333 {
334 	s->buf_end = s->buf + size;
335 	s->size_in_bits = 8*size;
336 }
337 
338 #endif /* AVCODEC_PUT_BITS_H */
339 
340