aggregator: Assert if the sink/src pad type that is to be used is not a GstAggregator...
[platform/upstream/gstreamer.git] / libs / gst / base / gstbitwriter.h
1 /*
2  *  gstbitwriter.h - bitstream writer
3  *
4  *  Copyright (C) 2013 Intel Corporation
5  *  Copyright (C) 2018 Igalia, S. L.
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public License
9  *  as published by the Free Software Foundation; either version 2.1
10  *  of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free
19  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301 USA
21  */
22
23 #ifndef GST_BIT_WRITER_H
24 #define GST_BIT_WRITER_H
25
26 #include <gst/gst.h>
27 #include <gst/base/base-prelude.h>
28
29 #include <string.h>
30
31 G_BEGIN_DECLS
32
33 #define GST_BIT_WRITER_DATA(writer)     ((writer)->data)
34 #define GST_BIT_WRITER_BIT_SIZE(writer) ((writer)->bit_size)
35 #define GST_BIT_WRITER(writer)          ((GstBitWriter *) (writer))
36
37 typedef struct _GstBitWriter GstBitWriter;
38
39 /**
40  * GstBitWriter:
41  * @data: Allocated @data for bit writer to write
42  * @bit_size: Size of written @data in bits
43  *
44  * A bit writer instance.
45  *
46  * Since: 1.16
47  */
48 struct _GstBitWriter
49 {
50   guint8 *data;
51   guint bit_size;
52
53   /*< private >*/
54   guint bit_capacity; /* Capacity of the allocated data */
55   gboolean auto_grow; /* Whether space can auto grow */
56   gboolean owned;
57   gpointer _gst_reserved[GST_PADDING];
58 };
59
60 GST_BASE_API
61 GstBitWriter *  gst_bit_writer_new              (void) G_GNUC_MALLOC;
62
63 GST_BASE_API
64 GstBitWriter *  gst_bit_writer_new_with_size    (guint32 size, gboolean fixed) G_GNUC_MALLOC;
65
66 GST_BASE_API
67 GstBitWriter *  gst_bit_writer_new_with_data    (guint8 *data, guint size,
68                                                  gboolean initialized) G_GNUC_MALLOC;
69
70 GST_BASE_API
71 void            gst_bit_writer_free             (GstBitWriter *bitwriter);
72
73 GST_BASE_API
74 guint8 *        gst_bit_writer_free_and_get_data (GstBitWriter *bitwriter);
75
76 GST_BASE_API
77 GstBuffer *     gst_bit_writer_free_and_get_buffer (GstBitWriter *bitwriter);
78
79 GST_BASE_API
80 void            gst_bit_writer_init             (GstBitWriter *bitwriter);
81
82 GST_BASE_API
83 void            gst_bit_writer_init_with_size   (GstBitWriter *bitwriter,
84                                                  guint32 size, gboolean fixed);
85
86 GST_BASE_API
87 void            gst_bit_writer_init_with_data   (GstBitWriter *bitwriter,  guint8 *data,
88                                                  guint size, gboolean initialized);
89
90 GST_BASE_API
91 void            gst_bit_writer_reset            (GstBitWriter *bitwriter);
92
93 GST_BASE_API
94 guint8 *        gst_bit_writer_reset_and_get_data (GstBitWriter *bitwriter);
95
96 GST_BASE_API
97 GstBuffer *     gst_bit_writer_reset_and_get_buffer (GstBitWriter *bitwriter);
98
99 GST_BASE_API
100 guint           gst_bit_writer_get_size         (const GstBitWriter *bitwriter);
101
102 GST_BASE_API
103 guint8 *        gst_bit_writer_get_data         (const GstBitWriter *bitwriter);
104
105 GST_BASE_API
106 gboolean        gst_bit_writer_set_pos          (GstBitWriter *bitwriter, guint pos);
107
108 GST_BASE_API
109 guint           gst_bit_writer_get_remaining    (const GstBitWriter *bitwriter);
110
111 GST_BASE_API
112 gboolean        gst_bit_writer_put_bits_uint8   (GstBitWriter *bitwriter, guint8 value,
113                                                  guint nbits);
114
115 GST_BASE_API
116 gboolean        gst_bit_writer_put_bits_uint16  (GstBitWriter *bitwriter, guint16 value,
117                                                  guint nbits);
118
119 GST_BASE_API
120 gboolean        gst_bit_writer_put_bits_uint32  (GstBitWriter *bitwriter, guint32 value,
121                                                  guint nbits);
122
123 GST_BASE_API
124 gboolean        gst_bit_writer_put_bits_uint64  (GstBitWriter *bitwriter, guint64 value,
125                                                  guint nbits);
126
127 GST_BASE_API
128 gboolean        gst_bit_writer_put_bytes        (GstBitWriter *bitwriter, const guint8 *data,
129                                                  guint nbytes);
130
131 GST_BASE_API
132 gboolean        gst_bit_writer_align_bytes      (GstBitWriter *bitwriter, guint8 trailing_bit);
133
134 static const guint8 _gst_bit_writer_bit_filling_mask[9] = {
135     0x00, 0x01, 0x03, 0x07,
136     0x0F, 0x1F, 0x3F, 0x7F,
137     0xFF
138 };
139
140 /* Aligned to 256 bytes */
141 #define __GST_BITS_WRITER_ALIGNMENT_MASK 2047
142 #define __GST_BITS_WRITER_ALIGNED(bitsize)                   \
143     (((bitsize) + __GST_BITS_WRITER_ALIGNMENT_MASK)&(~__GST_BITS_WRITER_ALIGNMENT_MASK))
144
145 static inline gboolean
146 _gst_bit_writer_check_remaining (GstBitWriter * bitwriter, guint32 bits)
147 {
148   guint32 new_bit_size = bits + bitwriter->bit_size;
149   guint32 clear_pos;
150
151   g_assert (bitwriter->bit_size <= bitwriter->bit_capacity);
152   if (new_bit_size <= bitwriter->bit_capacity)
153     return TRUE;
154
155   if (!bitwriter->auto_grow)
156     return FALSE;
157
158   /* auto grow space */
159   new_bit_size = __GST_BITS_WRITER_ALIGNED (new_bit_size);
160   g_assert (new_bit_size
161       && ((new_bit_size & __GST_BITS_WRITER_ALIGNMENT_MASK) == 0));
162   clear_pos = ((bitwriter->bit_size + 7) >> 3);
163   bitwriter->data = (guint8 *) g_realloc (bitwriter->data, (new_bit_size >> 3));
164   memset (bitwriter->data + clear_pos, 0, (new_bit_size >> 3) - clear_pos);
165   bitwriter->bit_capacity = new_bit_size;
166   return TRUE;
167 }
168
169 #undef __GST_BITS_WRITER_ALIGNMENT_MASK
170 #undef __GST_BITS_WRITER_ALIGNED
171
172 #define __GST_BIT_WRITER_WRITE_BITS_UNCHECKED(bits) \
173 static inline void \
174 gst_bit_writer_put_bits_uint##bits##_unchecked( \
175     GstBitWriter *bitwriter, \
176     guint##bits value, \
177     guint nbits \
178 ) \
179 { \
180     guint byte_pos, bit_offset; \
181     guint8  *cur_byte; \
182     guint fill_bits; \
183     \
184     byte_pos = (bitwriter->bit_size >> 3); \
185     bit_offset = (bitwriter->bit_size & 0x07); \
186     cur_byte = bitwriter->data + byte_pos; \
187     g_assert (nbits <= bits); \
188     g_assert( bit_offset < 8 && \
189             bitwriter->bit_size <= bitwriter->bit_capacity); \
190     \
191     while (nbits) { \
192         fill_bits = ((8 - bit_offset) < nbits ? (8 - bit_offset) : nbits); \
193         nbits -= fill_bits; \
194         bitwriter->bit_size += fill_bits; \
195         \
196         *cur_byte |= (((value >> nbits) & _gst_bit_writer_bit_filling_mask[fill_bits]) \
197                       << (8 - bit_offset - fill_bits)); \
198         ++cur_byte; \
199         bit_offset = 0; \
200     } \
201     g_assert(cur_byte <= \
202            (bitwriter->data + (bitwriter->bit_capacity >> 3))); \
203 }
204
205 __GST_BIT_WRITER_WRITE_BITS_UNCHECKED (8)
206 __GST_BIT_WRITER_WRITE_BITS_UNCHECKED (16)
207 __GST_BIT_WRITER_WRITE_BITS_UNCHECKED (32)
208 __GST_BIT_WRITER_WRITE_BITS_UNCHECKED (64)
209 #undef __GST_BIT_WRITER_WRITE_BITS_UNCHECKED
210
211 static inline guint
212 gst_bit_writer_get_size_unchecked (const GstBitWriter * bitwriter)
213 {
214   return GST_BIT_WRITER_BIT_SIZE (bitwriter);
215 }
216
217 static inline guint8 *
218 gst_bit_writer_get_data_unchecked (const GstBitWriter * bitwriter)
219 {
220   return GST_BIT_WRITER_DATA (bitwriter);
221 }
222
223 static inline gboolean
224 gst_bit_writer_set_pos_unchecked (GstBitWriter * bitwriter, guint pos)
225 {
226   GST_BIT_WRITER_BIT_SIZE (bitwriter) = pos;
227   return TRUE;
228 }
229
230 static inline guint
231 gst_bit_writer_get_remaining_unchecked (const GstBitWriter * bitwriter)
232 {
233   return bitwriter->bit_capacity - bitwriter->bit_size;
234 }
235
236 static inline void
237 gst_bit_writer_put_bytes_unchecked (GstBitWriter * bitwriter,
238     const guint8 * data, guint nbytes)
239 {
240   if ((bitwriter->bit_size & 0x07) == 0) {
241     memcpy (&bitwriter->data[bitwriter->bit_size >> 3], data, nbytes);
242     bitwriter->bit_size += (nbytes << 3);
243   } else {
244     g_assert (0);
245     while (nbytes) {
246       gst_bit_writer_put_bits_uint8_unchecked (bitwriter, *data, 8);
247       --nbytes;
248       ++data;
249     }
250   }
251 }
252
253 static inline void
254 gst_bit_writer_align_bytes_unchecked (GstBitWriter * bitwriter,
255     guint8 trailing_bit)
256 {
257   guint32 bit_offset, bit_left;
258   guint8 value = 0;
259
260   bit_offset = (bitwriter->bit_size & 0x07);
261   if (!bit_offset)
262     return;
263
264   bit_left = 8 - bit_offset;
265   if (trailing_bit)
266     value = _gst_bit_writer_bit_filling_mask[bit_left];
267   gst_bit_writer_put_bits_uint8_unchecked (bitwriter, value, bit_left);
268 }
269
270 #define __GST_BIT_WRITER_WRITE_BITS_INLINE(bits) \
271 static inline gboolean \
272 _gst_bit_writer_put_bits_uint##bits##_inline( \
273     GstBitWriter *bitwriter, \
274     guint##bits value, \
275     guint nbits \
276 ) \
277 { \
278     g_return_val_if_fail(bitwriter != NULL, FALSE); \
279     g_return_val_if_fail(nbits != 0, FALSE); \
280     g_return_val_if_fail(nbits <= bits, FALSE); \
281     \
282     if (!_gst_bit_writer_check_remaining(bitwriter, nbits)) \
283         return FALSE; \
284     gst_bit_writer_put_bits_uint##bits##_unchecked(bitwriter, value, nbits); \
285     return TRUE; \
286 }
287
288 __GST_BIT_WRITER_WRITE_BITS_INLINE (8)
289 __GST_BIT_WRITER_WRITE_BITS_INLINE (16)
290 __GST_BIT_WRITER_WRITE_BITS_INLINE (32)
291 __GST_BIT_WRITER_WRITE_BITS_INLINE (64)
292 #undef __GST_BIT_WRITER_WRITE_BITS_INLINE
293
294 static inline guint
295 _gst_bit_writer_get_size_inline (const GstBitWriter * bitwriter)
296 {
297   g_return_val_if_fail (bitwriter != NULL, 0);
298
299   return gst_bit_writer_get_size_unchecked (bitwriter);
300 }
301
302 static inline guint8 *
303 _gst_bit_writer_get_data_inline (const GstBitWriter * bitwriter)
304 {
305   g_return_val_if_fail (bitwriter != NULL, NULL);
306
307   return gst_bit_writer_get_data_unchecked (bitwriter);
308 }
309
310 static inline gboolean
311 _gst_bit_writer_set_pos_inline (GstBitWriter * bitwriter, guint pos)
312 {
313   g_return_val_if_fail (bitwriter != NULL, FALSE);
314   g_return_val_if_fail (pos <= bitwriter->bit_capacity, FALSE);
315
316   return gst_bit_writer_set_pos_unchecked (bitwriter, pos);
317 }
318
319 static inline guint
320 _gst_bit_writer_get_remaining_inline (const GstBitWriter * bitwriter)
321 {
322   g_return_val_if_fail (bitwriter != NULL, 0);
323   g_return_val_if_fail (bitwriter->bit_size < bitwriter->bit_capacity, 0);
324
325   return gst_bit_writer_get_remaining_unchecked (bitwriter);
326 }
327
328 static inline gboolean
329 _gst_bit_writer_put_bytes_inline (GstBitWriter * bitwriter,
330     const guint8 * data, guint nbytes)
331 {
332   g_return_val_if_fail (bitwriter != NULL, FALSE);
333   g_return_val_if_fail (data != NULL, FALSE);
334   g_return_val_if_fail (nbytes, FALSE);
335
336   if (!_gst_bit_writer_check_remaining (bitwriter, nbytes * 8))
337     return FALSE;
338
339   gst_bit_writer_put_bytes_unchecked (bitwriter, data, nbytes);
340   return TRUE;
341 }
342
343 static inline gboolean
344 _gst_bit_writer_align_bytes_inline (GstBitWriter * bitwriter,
345     guint8 trailing_bit)
346 {
347   g_return_val_if_fail (bitwriter != NULL, FALSE);
348   g_return_val_if_fail ((trailing_bit == 0 || trailing_bit == 1), FALSE);
349   g_return_val_if_fail (((bitwriter->bit_size + 7) & (~7)) <=
350       bitwriter->bit_capacity, FALSE);
351
352   gst_bit_writer_align_bytes_unchecked (bitwriter, trailing_bit);
353   return TRUE;
354 }
355
356 #ifndef GST_BIT_WRITER_DISABLE_INLINES
357 #define gst_bit_writer_get_size(bitwriter) \
358     _gst_bit_writer_get_size_inline(bitwriter)
359 #define gst_bit_writer_get_data(bitwriter) \
360     _gst_bit_writer_get_data_inline(bitwriter)
361 #define gst_bit_writer_set_pos(bitwriter, pos) \
362     G_LIKELY (_gst_bit_writer_set_pos_inline (bitwriter, pos))
363 #define gst_bit_writer_get_remaining(bitwriter) \
364     _gst_bit_writer_get_remaining_inline(bitwriter)
365
366 #define gst_bit_writer_put_bits_uint8(bitwriter, value, nbits) \
367     G_LIKELY (_gst_bit_writer_put_bits_uint8_inline (bitwriter, value, nbits))
368 #define gst_bit_writer_put_bits_uint16(bitwriter, value, nbits) \
369     G_LIKELY (_gst_bit_writer_put_bits_uint16_inline (bitwriter, value, nbits))
370 #define gst_bit_writer_put_bits_uint32(bitwriter, value, nbits) \
371     G_LIKELY (_gst_bit_writer_put_bits_uint32_inline (bitwriter, value, nbits))
372 #define gst_bit_writer_put_bits_uint64(bitwriter, value, nbits) \
373     G_LIKELY (_gst_bit_writer_put_bits_uint64_inline (bitwriter, value, nbits))
374
375 #define gst_bit_writer_put_bytes(bitwriter, data, nbytes) \
376     G_LIKELY (_gst_bit_writer_put_bytes_inline (bitwriter, data, nbytes))
377
378 #define gst_bit_writer_align_bytes(bitwriter, trailing_bit) \
379     G_LIKELY (_gst_bit_writer_align_bytes_inline(bitwriter, trailing_bit))
380 #endif
381
382 G_END_DECLS
383
384 #endif /* GST_BIT_WRITER_H */