add unittest for video360
[platform/upstream/gst-plugins-tizen.git] / wfdtsdemux / wfdnalutils.c
1 /* Gstreamer
2  * Copyright (C) <2011> Intel Corporation
3  * Copyright (C) <2011> Collabora Ltd.
4  * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
5  *
6  * Some bits C-c,C-v'ed and s/4/3 from h264parse and videoparsers/h264parse.c:
7  *    Copyright (C) <2010> Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
8  *    Copyright (C) <2010> Collabora Multimedia
9  *    Copyright (C) <2010> Nokia Corporation
10  *
11  *    (C) 2005 Michal Benes <michal.benes@itonis.tv>
12  *    (C) 2008 Wim Taymans <wim.taymans@gmail.com>
13  *
14  * This library is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU Library General Public
16  * License as published by the Free Software Foundation; either
17  * version 2 of the License, or (at your option) any later version.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22  * Library General Public License for more details.
23  *
24  * You should have received a copy of the GNU Library General Public
25  * License along with this library; if not, write to the
26  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
27  * Boston, MA 02110-1301, USA.
28  */
29
30 /**
31  * Common code for NAL parsing from h264 and h265 parsers.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #  include "config.h"
36 #endif
37
38 #include "wfdnalutils.h"
39
40 /* Compute Ceil(Log2(v)) */
41 /* Derived from branchless code for integer log2(v) from:
42    <http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog> */
43 guint
44 ceil_log2 (guint32 v)
45 {
46   guint r, shift;
47
48   v--;
49   r = (v > 0xFFFF) << 4;
50   v >>= r;
51   shift = (v > 0xFF) << 3;
52   v >>= shift;
53   r |= shift;
54   shift = (v > 0xF) << 2;
55   v >>= shift;
56   r |= shift;
57   shift = (v > 0x3) << 1;
58   v >>= shift;
59   r |= shift;
60   r |= (v >> 1);
61   return r + 1;
62 }
63
64 /****** Nal parser ******/
65
66 void
67 wfd_nal_reader_init (WFDNalReader * nr, const guint8 * data, guint size)
68 {
69   nr->data = data;
70   nr->size = size;
71   nr->n_epb = 0;
72
73   nr->byte = 0;
74   nr->bits_in_cache = 0;
75   /* fill with something other than 0 to detect emulation prevention bytes */
76   nr->first_byte = 0xff;
77   nr->cache = 0xff;
78 }
79
80 inline gboolean
81 wfd_nal_reader_read (WFDNalReader * nr, guint nbits)
82 {
83   if (G_UNLIKELY (nr->byte * 8 + (nbits - nr->bits_in_cache) > nr->size * 8)) {
84     GST_DEBUG ("Can not read %u bits, bits in cache %u, Byte * 8 %u, size in "
85         "bits %u", nbits, nr->bits_in_cache, nr->byte * 8, nr->size * 8);
86     return FALSE;
87   }
88
89   while (nr->bits_in_cache < nbits) {
90     guint8 byte;
91     gboolean check_three_byte;
92
93     check_three_byte = TRUE;
94   next_byte:
95     if (G_UNLIKELY (nr->byte >= nr->size))
96       return FALSE;
97
98     byte = nr->data[nr->byte++];
99
100     /* check if the byte is a emulation_prevention_three_byte */
101     if (check_three_byte && byte == 0x03 && nr->first_byte == 0x00 &&
102         ((nr->cache & 0xff) == 0)) {
103       /* next byte goes unconditionally to the cache, even if it's 0x03 */
104       check_three_byte = FALSE;
105       nr->n_epb++;
106       goto next_byte;
107     }
108     nr->cache = (nr->cache << 8) | nr->first_byte;
109     nr->first_byte = byte;
110     nr->bits_in_cache += 8;
111   }
112
113   return TRUE;
114 }
115
116 /* Skips the specified amount of bits. This is only suitable to a
117    cacheable number of bits */
118 inline gboolean
119 wfd_nal_reader_skip (WFDNalReader * nr, guint nbits)
120 {
121   g_assert (nbits <= 8 * sizeof (nr->cache));
122
123   if (G_UNLIKELY (!wfd_nal_reader_read (nr, nbits)))
124     return FALSE;
125
126   nr->bits_in_cache -= nbits;
127
128   return TRUE;
129 }
130
131 /* Generic version to skip any number of bits */
132 gboolean
133 wfd_nal_reader_skip_long (WFDNalReader * nr, guint nbits)
134 {
135   /* Leave out enough bits in the cache once we are finished */
136   const guint skip_size = 4 * sizeof (nr->cache);
137   guint remaining = nbits;
138
139   nbits %= skip_size;
140   while (remaining > 0) {
141     if (!wfd_nal_reader_skip (nr, nbits))
142       return FALSE;
143     remaining -= nbits;
144     nbits = skip_size;
145   }
146   return TRUE;
147 }
148
149 inline guint
150 wfd_nal_reader_get_pos (const WFDNalReader * nr)
151 {
152   return nr->byte * 8 - nr->bits_in_cache;
153 }
154
155 inline guint
156 wfd_nal_reader_get_remaining (const WFDNalReader * nr)
157 {
158   return (nr->size - nr->byte) * 8 + nr->bits_in_cache;
159 }
160
161 inline guint
162 wfd_nal_reader_get_epb_count (const WFDNalReader * nr)
163 {
164   return nr->n_epb;
165 }
166
167 #define WFD_NAL_READER_READ_BITS(bits) \
168 gboolean \
169 wfd_nal_reader_get_bits_uint##bits (WFDNalReader *nr, guint##bits *val, guint nbits) \
170 { \
171   guint shift; \
172   \
173   if (!wfd_nal_reader_read (nr, nbits)) \
174     return FALSE; \
175   \
176   /* bring the required bits down and truncate */ \
177   shift = nr->bits_in_cache - nbits; \
178   *val = nr->first_byte >> shift; \
179   \
180   *val |= nr->cache << (8 - shift); \
181   /* mask out required bits */ \
182   if (nbits < bits) \
183     *val &= ((guint##bits)1 << nbits) - 1; \
184   \
185   nr->bits_in_cache = shift; \
186   \
187   return TRUE; \
188 } \
189
190 WFD_NAL_READER_READ_BITS (8);
191 WFD_NAL_READER_READ_BITS (16);
192 WFD_NAL_READER_READ_BITS (32);
193
194 #define WFD_NAL_READER_PEEK_BITS(bits) \
195 gboolean \
196 wfd_nal_reader_peek_bits_uint##bits (const WFDNalReader *nr, guint##bits *val, guint nbits) \
197 { \
198   WFDNalReader tmp; \
199   \
200   tmp = *nr; \
201   return wfd_nal_reader_get_bits_uint##bits (&tmp, val, nbits); \
202 }
203
204 WFD_NAL_READER_PEEK_BITS (8);
205
206 gboolean
207 wfd_nal_reader_get_ue (WFDNalReader * nr, guint32 * val)
208 {
209   guint i = 0;
210   guint8 bit;
211   guint32 value;
212
213   if (G_UNLIKELY (!wfd_nal_reader_get_bits_uint8 (nr, &bit, 1))) {
214
215     return FALSE;
216   }
217
218   while (bit == 0) {
219     i++;
220     if G_UNLIKELY
221       ((!wfd_nal_reader_get_bits_uint8 (nr, &bit, 1)))
222           return FALSE;
223   }
224
225   if (G_UNLIKELY (i > 32))
226     return FALSE;
227
228   if (G_UNLIKELY (!wfd_nal_reader_get_bits_uint32 (nr, &value, i)))
229     return FALSE;
230
231   *val = (1 << i) - 1 + value;
232
233   return TRUE;
234 }
235
236 inline gboolean
237 wfd_nal_reader_get_se (WFDNalReader * nr, gint32 * val)
238 {
239   guint32 value;
240
241   if (G_UNLIKELY (!wfd_nal_reader_get_ue (nr, &value)))
242     return FALSE;
243
244   if (value % 2)
245     *val = (value / 2) + 1;
246   else
247     *val = -(value / 2);
248
249   return TRUE;
250 }
251
252 gboolean
253 wfd_nal_reader_is_byte_aligned (WFDNalReader * nr)
254 {
255   if (nr->bits_in_cache != 0)
256     return FALSE;
257   return TRUE;
258 }
259
260 gboolean
261 wfd_nal_reader_has_more_data (WFDNalReader * nr)
262 {
263   WFDNalReader nr_tmp;
264   guint remaining, nbits;
265   guint8 rbsp_stop_one_bit, zero_bits;
266
267   remaining = wfd_nal_reader_get_remaining (nr);
268   if (remaining == 0)
269     return FALSE;
270
271   nr_tmp = *nr;
272   nr = &nr_tmp;
273
274   /* The spec defines that more_rbsp_data() searches for the last bit
275      equal to 1, and that it is the rbsp_stop_one_bit. Subsequent bits
276      until byte boundary is reached shall be zero.
277
278      This means that more_rbsp_data() is FALSE if the next bit is 1
279      and the remaining bits until byte boundary are zero. One way to
280      be sure that this bit was the very last one, is that every other
281      bit after we reached byte boundary are also set to zero.
282      Otherwise, if the next bit is 0 or if there are non-zero bits
283      afterwards, then then we have more_rbsp_data() */
284   if (!wfd_nal_reader_get_bits_uint8 (nr, &rbsp_stop_one_bit, 1))
285     return FALSE;
286   if (!rbsp_stop_one_bit)
287     return TRUE;
288
289   nbits = --remaining % 8;
290   while (remaining > 0) {
291     if (!wfd_nal_reader_get_bits_uint8 (nr, &zero_bits, nbits))
292       return FALSE;
293     if (zero_bits != 0)
294       return TRUE;
295     remaining -= nbits;
296     nbits = 8;
297   }
298   return FALSE;
299 }
300
301 /***********  end of nal parser ***************/
302
303 inline gint
304 scan_for_start_codes (const guint8 * data, guint size)
305 {
306   GstByteReader br;
307   gst_byte_reader_init (&br, data, size);
308
309   /* NALU not empty, so we can at least expect 1 (even 2) bytes following sc */
310   return gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
311       0, size);
312 }