1 /*****************************************************************************
2  * nalu.c
3  *****************************************************************************
4  * Copyright (C) 2010-2017 L-SMASH project
5  *
6  * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
7  *
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.
11  *
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  *****************************************************************************/
20 
21 /* This file is available under an ISC license. */
22 
23 #include "common/internal.h" /* must be placed first */
24 
25 #include <string.h>
26 
27 #include "core/box.h"
28 
29 #include "nalu.h"
30 
isom_create_ps_entry(uint8_t * ps,uint32_t ps_size)31 isom_dcr_ps_entry_t *isom_create_ps_entry
32 (
33     uint8_t *ps,
34     uint32_t ps_size
35 )
36 {
37     isom_dcr_ps_entry_t *entry = lsmash_malloc( sizeof(isom_dcr_ps_entry_t) );
38     if( !entry )
39         return NULL;
40     entry->nalUnit = lsmash_memdup( ps, ps_size );
41     if( !entry->nalUnit )
42     {
43         lsmash_free( entry );
44         return NULL;
45     }
46     entry->nalUnitLength = ps_size;
47     entry->unused        = 0;
48     return entry;
49 }
50 
isom_remove_dcr_ps(isom_dcr_ps_entry_t * ps)51 void isom_remove_dcr_ps
52 (
53     isom_dcr_ps_entry_t *ps
54 )
55 {
56     if( !ps )
57         return;
58     lsmash_free( ps->nalUnit );
59     lsmash_free( ps );
60 }
61 
62 /* Convert EBSP (Encapsulated Byte Sequence Packets) to RBSP (Raw Byte Sequence Packets). */
nalu_remove_emulation_prevention(uint8_t * src,uint64_t src_length,uint8_t * dst)63 uint8_t *nalu_remove_emulation_prevention
64 (
65     uint8_t *src,
66     uint64_t src_length,
67     uint8_t *dst
68 )
69 {
70     uint8_t *src_end = src + src_length;
71     while( src < src_end )
72         if( ((src + 2) < src_end) && !src[0] && !src[1] && (src[2] == 0x03) )
73         {
74             /* 0x000003 -> 0x0000 */
75             *dst++ = *src++;
76             *dst++ = *src++;
77             src++;  /* Skip emulation_prevention_three_byte (0x03). */
78         }
79         else
80             *dst++ = *src++;
81     return dst;
82 }
83 
nalu_import_rbsp_from_ebsp(lsmash_bits_t * bits,uint8_t * rbsp_buffer,uint8_t * ebsp,uint64_t ebsp_size)84 int nalu_import_rbsp_from_ebsp
85 (
86     lsmash_bits_t *bits,
87     uint8_t       *rbsp_buffer,
88     uint8_t       *ebsp,
89     uint64_t       ebsp_size
90 )
91 {
92     uint8_t *rbsp_start  = rbsp_buffer;
93     uint8_t *rbsp_end    = nalu_remove_emulation_prevention( ebsp, ebsp_size, rbsp_buffer );
94     uint64_t rbsp_length = rbsp_end - rbsp_start;
95     return lsmash_bits_import_data( bits, rbsp_start, rbsp_length );
96 }
97 
nalu_check_more_rbsp_data(lsmash_bits_t * bits)98 int nalu_check_more_rbsp_data
99 (
100     lsmash_bits_t *bits
101 )
102 {
103     lsmash_bs_t *bs = bits->bs;
104     lsmash_buffer_t *buffer = &bs->buffer;
105     if( buffer->pos < buffer->store && !(bits->store == 0 && (buffer->store == buffer->pos + 1)) )
106         return 1;       /* rbsp_trailing_bits will be placed at the next or later byte.
107                          * Note: bs->pos points at the next byte if bits->store isn't empty. */
108     if( bits->store == 0 )
109     {
110         if( buffer->store == buffer->pos + 1 )
111             return buffer->data[ buffer->pos ] != 0x80;
112         /* No rbsp_trailing_bits is present in RBSP data. */
113         bs->error = 1;
114         return 0;
115     }
116     /* Check whether remainder of bits is identical to rbsp_trailing_bits. */
117     uint8_t remainder_bits = bits->cache & ~(~0U << bits->store);
118     uint8_t rbsp_trailing_bits = 1U << (bits->store - 1);
119     return remainder_bits != rbsp_trailing_bits;
120 }
121 
nalu_get_max_ps_length(lsmash_entry_list_t * ps_list,uint32_t * max_ps_length)122 int nalu_get_max_ps_length
123 (
124     lsmash_entry_list_t *ps_list,
125     uint32_t            *max_ps_length
126 )
127 {
128     *max_ps_length = 0;
129     for( lsmash_entry_t *entry = ps_list->head; entry; entry = entry->next )
130     {
131         isom_dcr_ps_entry_t *ps = (isom_dcr_ps_entry_t *)entry->data;
132         if( !ps )
133             return LSMASH_ERR_NAMELESS;
134         if( ps->unused )
135             continue;
136         *max_ps_length = LSMASH_MAX( *max_ps_length, ps->nalUnitLength );
137     }
138     return 0;
139 }
140 
nalu_get_ps_count(lsmash_entry_list_t * ps_list,uint32_t * ps_count)141 int nalu_get_ps_count
142 (
143     lsmash_entry_list_t *ps_list,
144     uint32_t            *ps_count
145 )
146 {
147     *ps_count = 0;
148     for( lsmash_entry_t *entry = ps_list ? ps_list->head : NULL; entry; entry = entry->next )
149     {
150         isom_dcr_ps_entry_t *ps = (isom_dcr_ps_entry_t *)entry->data;
151         if( !ps )
152             return LSMASH_ERR_NAMELESS;
153         if( ps->unused )
154             continue;
155         ++(*ps_count);
156     }
157     return 0;
158 }
159 
nalu_check_same_ps_existence(lsmash_entry_list_t * ps_list,void * ps_data,uint32_t ps_length)160 int nalu_check_same_ps_existence
161 (
162     lsmash_entry_list_t *ps_list,
163     void                *ps_data,
164     uint32_t             ps_length
165 )
166 {
167     for( lsmash_entry_t *entry = ps_list->head; entry; entry = entry->next )
168     {
169         isom_dcr_ps_entry_t *ps = (isom_dcr_ps_entry_t *)entry->data;
170         if( !ps )
171             return LSMASH_ERR_NAMELESS;
172         if( ps->unused )
173             continue;
174         if( ps->nalUnitLength == ps_length && !memcmp( ps->nalUnit, ps_data, ps_length ) )
175             return 1;   /* The same parameter set already exists. */
176     }
177     return 0;
178 }
179 
nalu_get_dcr_ps(lsmash_bs_t * bs,lsmash_entry_list_t * list,uint8_t entry_count)180 int nalu_get_dcr_ps
181 (
182     lsmash_bs_t         *bs,
183     lsmash_entry_list_t *list,
184     uint8_t              entry_count
185 )
186 {
187     for( uint8_t i = 0; i < entry_count; i++ )
188     {
189         isom_dcr_ps_entry_t *data = lsmash_malloc( sizeof(isom_dcr_ps_entry_t) );
190         if( !data )
191             return LSMASH_ERR_MEMORY_ALLOC;
192         if( lsmash_list_add_entry( list, data ) < 0 )
193         {
194             lsmash_free( data );
195             return LSMASH_ERR_MEMORY_ALLOC;
196         }
197         data->nalUnitLength = lsmash_bs_get_be16( bs );
198         data->nalUnit       = lsmash_bs_get_bytes( bs, data->nalUnitLength );
199         if( !data->nalUnit )
200         {
201             lsmash_list_remove_entries( list );
202             return LSMASH_ERR_NAMELESS;
203         }
204     }
205     return 0;
206 }
207 
208 /* Return the offset from the beginning of stream if a start code is found.
209  * Return NALU_NO_START_CODE_FOUND otherwise. */
nalu_find_first_start_code(lsmash_bs_t * bs)210 uint64_t nalu_find_first_start_code
211 (
212     lsmash_bs_t *bs
213 )
214 {
215     uint64_t first_sc_head_pos = 0;
216     while( 1 )
217     {
218         if( lsmash_bs_is_error( bs ) )
219             return NALU_IO_ERROR;
220         if( lsmash_bs_is_end( bs, first_sc_head_pos + NALU_LONG_START_CODE_LENGTH ) )
221             return NALU_NO_START_CODE_FOUND;
222         /* Invalid if encountered any value of non-zero before the first start code. */
223         if( lsmash_bs_show_byte( bs, first_sc_head_pos ) )
224             return NALU_NO_START_CODE_FOUND;
225         /* The first NALU of an AU in decoding order shall have long start code (0x00000001). */
226         if( 0x00000001 == lsmash_bs_show_be32( bs, first_sc_head_pos ) )
227             break;
228         ++first_sc_head_pos;
229     }
230     return first_sc_head_pos;
231 }
232 
nalu_get_codeNum(lsmash_bits_t * bits)233 uint64_t nalu_get_codeNum
234 (
235     lsmash_bits_t *bits
236 )
237 {
238     uint32_t leadingZeroBits = 0;
239     for( int b = 0; !b; leadingZeroBits++ )
240         b = lsmash_bits_get( bits, 1 );
241     --leadingZeroBits;
242     return ((uint64_t)1 << leadingZeroBits) - 1 + lsmash_bits_get( bits, leadingZeroBits );
243 }
244 
nalu_update_bitrate(isom_stbl_t * stbl,isom_mdhd_t * mdhd,uint32_t sample_description_index)245 int nalu_update_bitrate( isom_stbl_t *stbl, isom_mdhd_t *mdhd, uint32_t sample_description_index )
246 {
247     isom_visual_entry_t *sample_entry = (isom_visual_entry_t *)lsmash_list_get_entry_data( &stbl->stsd->list, sample_description_index );
248     if( LSMASH_IS_NON_EXISTING_BOX( sample_entry ) )
249         return LSMASH_ERR_INVALID_DATA;
250     isom_btrt_t *btrt = (isom_btrt_t *)isom_get_extension_box_format( &sample_entry->extensions, ISOM_BOX_TYPE_BTRT );
251     if( LSMASH_IS_EXISTING_BOX( btrt ) )
252     {
253         uint32_t bufferSizeDB;
254         uint32_t maxBitrate;
255         uint32_t avgBitrate;
256         int err = isom_calculate_bitrate_description( stbl, mdhd, &bufferSizeDB, &maxBitrate, &avgBitrate, sample_description_index );
257         if( err < 0 )
258             return err;
259         btrt->bufferSizeDB = bufferSizeDB;
260         btrt->maxBitrate   = maxBitrate;
261         btrt->avgBitrate   = avgBitrate;
262     }
263     return 0;
264 }
265