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 <gst/base/gstbytereader.h> 39 #include <gst/base/gstbitreader.h> 40 #include <gst/base/gstbitwriter.h> 41 #include <string.h> 42 43 guint ceil_log2 (guint32 v); 44 45 typedef struct 46 { 47 const guint8 *data; 48 guint size; 49 50 guint n_epb; /* Number of emulation prevention bytes */ 51 guint byte; /* Byte position */ 52 guint bits_in_cache; /* bitpos in the cache of next bit */ 53 guint8 first_byte; 54 guint32 epb_cache; /* cache 3 bytes to check emulation prevention bytes */ 55 guint64 cache; /* cached bytes */ 56 } NalReader; 57 58 typedef struct 59 { 60 GstBitWriter bw; 61 62 guint nal_prefix_size; 63 gboolean packetized; 64 } NalWriter; 65 66 G_GNUC_INTERNAL 67 void nal_reader_init (NalReader * nr, const guint8 * data, guint size); 68 69 G_GNUC_INTERNAL 70 gboolean nal_reader_read (NalReader * nr, guint nbits); 71 72 G_GNUC_INTERNAL 73 gboolean nal_reader_skip (NalReader * nr, guint nbits); 74 75 G_GNUC_INTERNAL 76 gboolean nal_reader_skip_long (NalReader * nr, guint nbits); 77 78 G_GNUC_INTERNAL 79 guint nal_reader_get_pos (const NalReader * nr); 80 81 G_GNUC_INTERNAL 82 guint nal_reader_get_remaining (const NalReader * nr); 83 84 G_GNUC_INTERNAL 85 guint nal_reader_get_epb_count (const NalReader * nr); 86 87 G_GNUC_INTERNAL 88 gboolean nal_reader_is_byte_aligned (NalReader * nr); 89 90 G_GNUC_INTERNAL 91 gboolean nal_reader_has_more_data (NalReader * nr); 92 93 #define NAL_READER_READ_BITS_H(bits) \ 94 G_GNUC_INTERNAL \ 95 gboolean nal_reader_get_bits_uint##bits (NalReader *nr, guint##bits *val, guint nbits) 96 97 NAL_READER_READ_BITS_H (8); 98 NAL_READER_READ_BITS_H (16); 99 NAL_READER_READ_BITS_H (32); 100 101 #define NAL_READER_PEEK_BITS_H(bits) \ 102 G_GNUC_INTERNAL \ 103 gboolean nal_reader_peek_bits_uint##bits (const NalReader *nr, guint##bits *val, guint nbits) 104 105 NAL_READER_PEEK_BITS_H (8); 106 107 G_GNUC_INTERNAL 108 gboolean nal_reader_get_ue (NalReader * nr, guint32 * val); 109 110 G_GNUC_INTERNAL 111 gboolean nal_reader_get_se (NalReader * nr, gint32 * val); 112 113 #define CHECK_ALLOWED_MAX_WITH_DEBUG(dbg, val, max) { \ 114 if (val > max) { \ 115 GST_WARNING ("value for '" dbg "' greater than max. value: %d, max %d", \ 116 val, max); \ 117 goto error; \ 118 } \ 119 } 120 #define CHECK_ALLOWED_MAX(val, max) \ 121 CHECK_ALLOWED_MAX_WITH_DEBUG (G_STRINGIFY (val), val, max) 122 123 #define CHECK_ALLOWED_WITH_DEBUG(dbg, val, min, max) { \ 124 if (val < min || val > max) { \ 125 GST_WARNING ("value for '" dbg "' not in allowed range. value: %d, range %d-%d", \ 126 val, min, max); \ 127 goto error; \ 128 } \ 129 } 130 #define CHECK_ALLOWED(val, min, max) \ 131 CHECK_ALLOWED_WITH_DEBUG (G_STRINGIFY (val), val, min, max) 132 133 #define READ_UINT8(nr, val, nbits) { \ 134 if (!nal_reader_get_bits_uint8 (nr, &val, nbits)) { \ 135 GST_WARNING ("failed to read uint8 for '" G_STRINGIFY (val) "', nbits: %d", nbits); \ 136 goto error; \ 137 } \ 138 } 139 140 #define READ_UINT16(nr, val, nbits) { \ 141 if (!nal_reader_get_bits_uint16 (nr, &val, nbits)) { \ 142 GST_WARNING ("failed to read uint16 for '" G_STRINGIFY (val) "', nbits: %d", nbits); \ 143 goto error; \ 144 } \ 145 } 146 147 #define READ_UINT32(nr, val, nbits) { \ 148 if (!nal_reader_get_bits_uint32 (nr, &val, nbits)) { \ 149 GST_WARNING ("failed to read uint32 for '" G_STRINGIFY (val) "', nbits: %d", nbits); \ 150 goto error; \ 151 } \ 152 } 153 154 #define READ_UINT64(nr, val, nbits) { \ 155 if (!nal_reader_get_bits_uint64 (nr, &val, nbits)) { \ 156 GST_WARNING ("failed to read uint32 for '" G_STRINGIFY (val) "', nbits: %d", nbits); \ 157 goto error; \ 158 } \ 159 } 160 161 #define READ_UE(nr, val) { \ 162 if (!nal_reader_get_ue (nr, &val)) { \ 163 GST_DEBUG ("failed to read UE for '" G_STRINGIFY (val) "'"); \ 164 goto error; \ 165 } \ 166 } 167 168 #define READ_UE_ALLOWED(nr, val, min, max) { \ 169 guint32 tmp; \ 170 READ_UE (nr, tmp); \ 171 CHECK_ALLOWED_WITH_DEBUG (G_STRINGIFY (val), tmp, min, max); \ 172 val = tmp; \ 173 } 174 175 #define READ_UE_MAX(nr, val, max) { \ 176 guint32 tmp; \ 177 READ_UE (nr, tmp); \ 178 CHECK_ALLOWED_MAX_WITH_DEBUG (G_STRINGIFY (val), tmp, max); \ 179 val = tmp; \ 180 } 181 182 #define READ_SE(nr, val) { \ 183 if (!nal_reader_get_se (nr, &val)) { \ 184 GST_WARNING ("failed to read SE for '" G_STRINGIFY (val) "'"); \ 185 goto error; \ 186 } \ 187 } 188 189 #define READ_SE_ALLOWED(nr, val, min, max) { \ 190 gint32 tmp; \ 191 READ_SE (nr, tmp); \ 192 CHECK_ALLOWED_WITH_DEBUG (G_STRINGIFY (val), tmp, min, max); \ 193 val = tmp; \ 194 } 195 196 G_GNUC_INTERNAL 197 gint scan_for_start_codes (const guint8 * data, guint size); 198 199 G_GNUC_INTERNAL 200 void nal_writer_init (NalWriter * nw, guint nal_prefix_size, gboolean packetized); 201 202 G_GNUC_INTERNAL 203 void nal_writer_reset (NalWriter * nw); 204 205 G_GNUC_INTERNAL 206 gboolean nal_writer_do_rbsp_trailing_bits (NalWriter * nw); 207 208 G_GNUC_INTERNAL 209 GstMemory * nal_writer_reset_and_get_memory (NalWriter * nw); 210 211 G_GNUC_INTERNAL 212 gboolean nal_writer_put_bits_uint8 (NalWriter * nw, guint8 value, guint nbits); 213 214 G_GNUC_INTERNAL 215 gboolean nal_writer_put_bits_uint16 (NalWriter * nw, guint16 value, guint nbits); 216 217 G_GNUC_INTERNAL 218 gboolean nal_writer_put_bits_uint32 (NalWriter * nw, guint32 value, guint nbits); 219 220 G_GNUC_INTERNAL 221 gboolean nal_writer_put_bytes (NalWriter * nw, const guint8 * data, guint nbytes); 222 223 G_GNUC_INTERNAL 224 gboolean nal_writer_put_ue (NalWriter * nw, guint32 value); 225 226 G_GNUC_INTERNAL 227 gboolean count_exp_golomb_bits (guint32 value, guint * leading_zeros, guint * rest); 228 229 #define WRITE_UINT8(nw, val, nbits) { \ 230 if (!nal_writer_put_bits_uint8 (nw, val, nbits)) { \ 231 GST_WARNING ("failed to write uint8 for '" G_STRINGIFY (val) "', nbits: %d", nbits); \ 232 goto error; \ 233 } \ 234 } 235 236 #define WRITE_UINT16(nw, val, nbits) { \ 237 if (!nal_writer_put_bits_uint16 (nw, val, nbits)) { \ 238 GST_WARNING ("failed to write uint16 for '" G_STRINGIFY (val) "', nbits: %d", nbits); \ 239 goto error; \ 240 } \ 241 } 242 243 #define WRITE_UINT32(nw, val, nbits) { \ 244 if (!nal_writer_put_bits_uint32 (nw, val, nbits)) { \ 245 GST_WARNING ("failed to write uint32 for '" G_STRINGIFY (val) "', nbits: %d", nbits); \ 246 goto error; \ 247 } \ 248 } 249 250 #define WRITE_BYTES(nw, data, nbytes) { \ 251 if (!nal_writer_put_bytes (nw, data, nbytes)) { \ 252 GST_WARNING ("failed to write bytes for '" G_STRINGIFY (val) "', nbits: %d", nbytes); \ 253 goto error; \ 254 } \ 255 } 256 257 #define WRITE_UE(nw, val) { \ 258 if (!nal_writer_put_ue (nw, val)) { \ 259 GST_WARNING ("failed to write ue for '" G_STRINGIFY (val) "'"); \ 260 goto error; \ 261 } \ 262 } 263