msvc: Add MSVC Project files for CLI programs.
[L-SMASH.git] / codecs / nalu.h
blob2348def464822555f7a0c8f475e9c6fc7235bc74
1 /*****************************************************************************
2 * nalu.h:
3 *****************************************************************************
4 * Copyright (C) 2013-2014 L-SMASH project
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *****************************************************************************/
21 /* This file is available under an ISC license. */
23 #define NALU_DEFAULT_BUFFER_SIZE (1<<16)
24 #define NALU_DEFAULT_NALU_LENGTH_SIZE 4 /* We always use 4 bytes length. */
25 #define NALU_SHORT_START_CODE_LENGTH 3
26 #define NALU_LONG_START_CODE_LENGTH 4
27 #define NALU_NO_START_CODE_FOUND UINT64_MAX
29 static inline uint64_t nalu_get_codeNum
31 lsmash_bits_t *bits
34 uint32_t leadingZeroBits = 0;
35 for( int b = 0; !b; leadingZeroBits++ )
36 b = lsmash_bits_get( bits, 1 );
37 --leadingZeroBits;
38 return ((uint64_t)1 << leadingZeroBits) - 1 + lsmash_bits_get( bits, leadingZeroBits );
41 static inline uint64_t nalu_decode_exp_golomb_ue
43 uint64_t codeNum
46 return codeNum;
49 static inline int64_t nalu_decode_exp_golomb_se
51 uint64_t codeNum
54 if( codeNum & 1 )
55 return (int64_t)((codeNum >> 1) + 1);
56 return -1 * (int64_t)(codeNum >> 1);
59 static inline uint64_t nalu_get_exp_golomb_ue
61 lsmash_bits_t *bits
64 uint64_t codeNum = nalu_get_codeNum( bits );
65 return nalu_decode_exp_golomb_ue( codeNum );
68 static inline uint64_t nalu_get_exp_golomb_se
70 lsmash_bits_t *bits
73 uint64_t codeNum = nalu_get_codeNum( bits );
74 return nalu_decode_exp_golomb_se( codeNum );
77 /* Convert EBSP (Encapsulated Byte Sequence Packets) to RBSP (Raw Byte Sequence Packets). */
78 static inline uint8_t *nalu_remove_emulation_prevention
80 uint8_t *src,
81 uint64_t src_length,
82 uint8_t *dst
85 uint8_t *src_end = src + src_length;
86 while( src < src_end )
87 if( ((src + 2) < src_end) && !src[0] && !src[1] && (src[2] == 0x03) )
89 /* 0x000003 -> 0x0000 */
90 *dst++ = *src++;
91 *dst++ = *src++;
92 src++; /* Skip emulation_prevention_three_byte (0x03). */
94 else
95 *dst++ = *src++;
96 return dst;
99 static inline int nalu_import_rbsp_from_ebsp
101 lsmash_bits_t *bits,
102 uint8_t *rbsp_buffer,
103 uint8_t *ebsp,
104 uint64_t ebsp_size
107 uint8_t *rbsp_start = rbsp_buffer;
108 uint8_t *rbsp_end = nalu_remove_emulation_prevention( ebsp, ebsp_size, rbsp_buffer );
109 uint64_t rbsp_length = rbsp_end - rbsp_start;
110 return lsmash_bits_import_data( bits, rbsp_start, rbsp_length );
113 static inline int nalu_check_more_rbsp_data
115 lsmash_bits_t *bits
118 lsmash_bs_t *bs = bits->bs;
119 lsmash_buffer_t *buffer = &bs->buffer;
120 if( buffer->pos < buffer->store && !(bits->store == 0 && (buffer->store == buffer->pos + 1)) )
121 return 1; /* rbsp_trailing_bits will be placed at the next or later byte.
122 * Note: bs->pos points at the next byte if bits->store isn't empty. */
123 if( bits->store == 0 )
125 if( buffer->store == buffer->pos + 1 )
126 return buffer->data[ buffer->pos ] != 0x80;
127 /* No rbsp_trailing_bits is present in RBSP data. */
128 bs->error = 1;
129 return 0;
131 /* Check whether remainder of bits is identical to rbsp_trailing_bits. */
132 uint8_t remainder_bits = bits->cache & ~(~0U << bits->store);
133 uint8_t rbsp_trailing_bits = 1U << (bits->store - 1);
134 return remainder_bits != rbsp_trailing_bits;
137 static inline int nalu_get_max_ps_length
139 lsmash_entry_list_t *ps_list,
140 uint32_t *max_ps_length
143 *max_ps_length = 0;
144 for( lsmash_entry_t *entry = ps_list->head; entry; entry = entry->next )
146 isom_dcr_ps_entry_t *ps = (isom_dcr_ps_entry_t *)entry->data;
147 if( !ps )
148 return LSMASH_ERR_NAMELESS;
149 if( ps->unused )
150 continue;
151 *max_ps_length = LSMASH_MAX( *max_ps_length, ps->nalUnitLength );
153 return 0;
156 static inline int nalu_get_ps_count
158 lsmash_entry_list_t *ps_list,
159 uint32_t *ps_count
162 *ps_count = 0;
163 for( lsmash_entry_t *entry = ps_list ? ps_list->head : NULL; entry; entry = entry->next )
165 isom_dcr_ps_entry_t *ps = (isom_dcr_ps_entry_t *)entry->data;
166 if( !ps )
167 return LSMASH_ERR_NAMELESS;
168 if( ps->unused )
169 continue;
170 ++(*ps_count);
172 return 0;
175 static inline int nalu_check_same_ps_existence
177 lsmash_entry_list_t *ps_list,
178 void *ps_data,
179 uint32_t ps_length
182 for( lsmash_entry_t *entry = ps_list->head; entry; entry = entry->next )
184 isom_dcr_ps_entry_t *ps = (isom_dcr_ps_entry_t *)entry->data;
185 if( !ps )
186 return LSMASH_ERR_NAMELESS;
187 if( ps->unused )
188 continue;
189 if( ps->nalUnitLength == ps_length && !memcmp( ps->nalUnit, ps_data, ps_length ) )
190 return 1; /* The same parameter set already exists. */
192 return 0;
195 static inline int nalu_get_dcr_ps
197 lsmash_bs_t *bs,
198 lsmash_entry_list_t *list,
199 uint8_t entry_count
202 for( uint8_t i = 0; i < entry_count; i++ )
204 isom_dcr_ps_entry_t *data = lsmash_malloc( sizeof(isom_dcr_ps_entry_t) );
205 if( !data )
206 return LSMASH_ERR_MEMORY_ALLOC;
207 if( lsmash_add_entry( list, data ) < 0 )
209 lsmash_free( data );
210 return LSMASH_ERR_MEMORY_ALLOC;
212 data->nalUnitLength = lsmash_bs_get_be16( bs );
213 data->nalUnit = lsmash_bs_get_bytes( bs, data->nalUnitLength );
214 if( !data->nalUnit )
216 lsmash_remove_entries( list, isom_remove_dcr_ps );
217 return LSMASH_ERR_NAMELESS;
220 return 0;
223 static inline int nalu_check_next_short_start_code
225 uint8_t *buf_pos,
226 uint8_t *buf_end
229 return ((buf_pos + 2) < buf_end) && !buf_pos[0] && !buf_pos[1] && (buf_pos[2] == 0x01);
232 /* Return the offset from the beginning of stream if a start code is found.
233 * Return NALU_NO_START_CODE_FOUND otherwise. */
234 static inline uint64_t nalu_find_first_start_code
236 lsmash_bs_t *bs
239 uint64_t first_sc_head_pos = 0;
240 while( 1 )
242 if( lsmash_bs_is_end( bs, first_sc_head_pos + NALU_LONG_START_CODE_LENGTH ) )
243 return NALU_NO_START_CODE_FOUND;
244 /* Invalid if encountered any value of non-zero before the first start code. */
245 if( lsmash_bs_show_byte( bs, first_sc_head_pos ) )
246 return NALU_NO_START_CODE_FOUND;
247 /* The first NALU of an AU in decoding order shall have long start code (0x00000001). */
248 if( 0x00000001 == lsmash_bs_show_be32( bs, first_sc_head_pos ) )
249 break;
250 ++first_sc_head_pos;
252 return first_sc_head_pos;