1 /*
2 *			GPAC - Multimedia Framework C SDK
3 *
4 *			Authors: Jean Le Feuvre
5 *			Copyright (c) Telecom ParisTech 2000-2012
6 *					All rights reserved
7 *
8 *  This file is part of GPAC / ISO Media File Format sub-project
9 *
10 *  GPAC is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License as published by
12 *  the Free Software Foundation; either version 2, or (at your option)
13 *  any later version.
14 *
15 *  GPAC is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *  GNU Lesser General Public License for more details.
19 *
20 *  You should have received a copy of the GNU Lesser General Public
21 *  License along with this library; see the file COPYING.  If not, write to
22 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25 
26 #include <gpac/internal/isomedia_dev.h>
27 
28 
29 
30 #ifndef GPAC_DISABLE_ISOM
31 
co64_del(GF_Box * s)32 void co64_del(GF_Box *s)
33 {
34 	GF_ChunkLargeOffsetBox *ptr;
35 	ptr = (GF_ChunkLargeOffsetBox *)s;
36 	if (ptr == NULL) return;
37 	if (ptr->offsets) gf_free(ptr->offsets);
38 	gf_free(ptr);
39 }
40 
co64_Read(GF_Box * s,GF_BitStream * bs)41 GF_Err co64_Read(GF_Box *s, GF_BitStream *bs)
42 {
43 	GF_Err e;
44 	u32 entries;
45 	GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *)s;
46 	e = gf_isom_full_box_read(s, bs);
47 	if (e) return e;
48 	ptr->nb_entries = gf_bs_read_u32(bs);
49 	ptr->offsets = (u64 *)gf_malloc(ptr->nb_entries * sizeof(u64));
50 	if (ptr->offsets == NULL) return GF_OUT_OF_MEM;
51 	ptr->alloc_size = ptr->nb_entries;
52 	for (entries = 0; entries < ptr->nb_entries; entries++) {
53 		ptr->offsets[entries] = gf_bs_read_u64(bs);
54 	}
55 	return GF_OK;
56 }
57 
co64_New()58 GF_Box *co64_New()
59 {
60 	ISOM_DECL_BOX_ALLOC(GF_ChunkLargeOffsetBox, GF_ISOM_BOX_TYPE_CO64);
61 	gf_isom_full_box_init((GF_Box *)tmp);
62 	return (GF_Box *)tmp;
63 }
64 
65 
66 #ifndef GPAC_DISABLE_ISOM_WRITE
67 
co64_Write(GF_Box * s,GF_BitStream * bs)68 GF_Err co64_Write(GF_Box *s, GF_BitStream *bs)
69 {
70 	GF_Err e;
71 	u32 i;
72 	GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *)s;
73 
74 	e = gf_isom_full_box_write(s, bs);
75 	if (e) return e;
76 	gf_bs_write_u32(bs, ptr->nb_entries);
77 	for (i = 0; i < ptr->nb_entries; i++) {
78 		gf_bs_write_u64(bs, ptr->offsets[i]);
79 	}
80 	return GF_OK;
81 }
82 
co64_Size(GF_Box * s)83 GF_Err co64_Size(GF_Box *s)
84 {
85 	GF_Err e;
86 	GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *)s;
87 	e = gf_isom_full_box_get_size(s);
88 	if (e) return e;
89 	ptr->size += 4 + (8 * ptr->nb_entries);
90 	return GF_OK;
91 }
92 
93 #endif /*GPAC_DISABLE_ISOM_WRITE*/
94 
cprt_del(GF_Box * s)95 void cprt_del(GF_Box *s)
96 {
97 	GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;
98 	if (ptr == NULL) return;
99 	if (ptr->notice)
100 		gf_free(ptr->notice);
101 	gf_free(ptr);
102 }
103 
104 
chpl_New()105 GF_Box *chpl_New()
106 {
107 	ISOM_DECL_BOX_ALLOC(GF_ChapterListBox, GF_ISOM_BOX_TYPE_CHPL);
108 	tmp->list = gf_list_new();
109 	gf_isom_full_box_init((GF_Box *)tmp);
110 	tmp->version = 1;
111 	return (GF_Box *)tmp;
112 }
113 
chpl_del(GF_Box * s)114 void chpl_del(GF_Box *s)
115 {
116 	GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;
117 	if (ptr == NULL) return;
118 	while (gf_list_count(ptr->list)) {
119 		GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, 0);
120 		if (ce->name) gf_free(ce->name);
121 		gf_free(ce);
122 		gf_list_rem(ptr->list, 0);
123 	}
124 	gf_list_del(ptr->list);
125 	gf_free(ptr);
126 }
127 
128 /*this is using chpl format according to some NeroRecode samples*/
chpl_Read(GF_Box * s,GF_BitStream * bs)129 GF_Err chpl_Read(GF_Box *s, GF_BitStream *bs)
130 {
131 	GF_Err e;
132 	GF_ChapterEntry *ce;
133 	u32 nb_chaps, len, i, count;
134 	GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;
135 
136 	e = gf_isom_full_box_read(s, bs);
137 	if (e) return e;
138 
139 	/*reserved or ???*/
140 	gf_bs_read_u32(bs);
141 	nb_chaps = gf_bs_read_u8(bs);
142 
143 	count = 0;
144 	while (nb_chaps) {
145 		GF_SAFEALLOC(ce, GF_ChapterEntry);
146 		if (!ce) return GF_OUT_OF_MEM;
147 		ce->start_time = gf_bs_read_u64(bs);
148 		len = gf_bs_read_u8(bs);
149 		if (len) {
150 			ce->name = (char *)gf_malloc(sizeof(char)*(len + 1));
151 			gf_bs_read_data(bs, ce->name, len);
152 			ce->name[len] = 0;
153 		}
154 		else {
155 			ce->name = gf_strdup("");
156 		}
157 
158 		for (i = 0; i<count; i++) {
159 			GF_ChapterEntry *ace = (GF_ChapterEntry *)gf_list_get(ptr->list, i);
160 			if (ace->start_time >= ce->start_time) {
161 				gf_list_insert(ptr->list, ce, i);
162 				ce = NULL;
163 				break;
164 			}
165 		}
166 		if (ce) gf_list_add(ptr->list, ce);
167 		count++;
168 		nb_chaps--;
169 	}
170 	return GF_OK;
171 }
172 
173 #ifndef GPAC_DISABLE_ISOM_WRITE
174 
chpl_Write(GF_Box * s,GF_BitStream * bs)175 GF_Err chpl_Write(GF_Box *s, GF_BitStream *bs)
176 {
177 	GF_Err e;
178 	u32 count, i;
179 	GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;
180 	e = gf_isom_full_box_write(s, bs);
181 	if (e) return e;
182 
183 	count = gf_list_count(ptr->list);
184 	gf_bs_write_u32(bs, 0);
185 	gf_bs_write_u8(bs, count);
186 	for (i = 0; i<count; i++) {
187 		u32 len;
188 		GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, i);
189 		gf_bs_write_u64(bs, ce->start_time);
190 		if (ce->name) {
191 			len = (u32)strlen(ce->name);
192 			if (len>255) len = 255;
193 			gf_bs_write_u8(bs, len);
194 			gf_bs_write_data(bs, ce->name, len);
195 		}
196 		else {
197 			gf_bs_write_u8(bs, 0);
198 		}
199 	}
200 	return GF_OK;
201 }
202 
chpl_Size(GF_Box * s)203 GF_Err chpl_Size(GF_Box *s)
204 {
205 	GF_Err e;
206 	u32 count, i;
207 	GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;
208 	e = gf_isom_full_box_get_size(s);
209 	if (e) return e;
210 	ptr->size += 5;
211 
212 	count = gf_list_count(ptr->list);
213 	for (i = 0; i<count; i++) {
214 		GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, i);
215 		ptr->size += 9; /*64bit time stamp + 8bit str len*/
216 		if (ce->name) ptr->size += strlen(ce->name);
217 	}
218 	return GF_OK;
219 }
220 
221 #endif /*GPAC_DISABLE_ISOM_WRITE*/
222 
223 
cprt_Read(GF_Box * s,GF_BitStream * bs)224 GF_Err cprt_Read(GF_Box *s, GF_BitStream *bs)
225 {
226 	GF_Err e;
227 	GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;
228 
229 	e = gf_isom_full_box_read(s, bs);
230 	if (e) return e;
231 	gf_bs_read_int(bs, 1);
232 	//the spec is unclear here, just says "the value 0 is interpreted as undetermined"
233 	ptr->packedLanguageCode[0] = gf_bs_read_int(bs, 5);
234 	ptr->packedLanguageCode[1] = gf_bs_read_int(bs, 5);
235 	ptr->packedLanguageCode[2] = gf_bs_read_int(bs, 5);
236 	ptr->size -= 2;
237 	//but before or after compaction ?? We assume before
238 	if (ptr->packedLanguageCode[0] || ptr->packedLanguageCode[1] || ptr->packedLanguageCode[2]) {
239 		ptr->packedLanguageCode[0] += 0x60;
240 		ptr->packedLanguageCode[1] += 0x60;
241 		ptr->packedLanguageCode[2] += 0x60;
242 	}
243 	else {
244 		ptr->packedLanguageCode[0] = 'u';
245 		ptr->packedLanguageCode[1] = 'n';
246 		ptr->packedLanguageCode[2] = 'd';
247 	}
248 	if (ptr->size) {
249 		u32 bytesToRead = (u32)ptr->size;
250 		ptr->notice = (char*)gf_malloc(bytesToRead * sizeof(char));
251 		if (ptr->notice == NULL) return GF_OUT_OF_MEM;
252 		gf_bs_read_data(bs, ptr->notice, bytesToRead);
253 	}
254 	return GF_OK;
255 }
256 
cprt_New()257 GF_Box *cprt_New()
258 {
259 	ISOM_DECL_BOX_ALLOC(GF_CopyrightBox, GF_ISOM_BOX_TYPE_CPRT);
260 
261 	gf_isom_full_box_init((GF_Box *)tmp);
262 	tmp->packedLanguageCode[0] = 'u';
263 	tmp->packedLanguageCode[1] = 'n';
264 	tmp->packedLanguageCode[2] = 'd';
265 
266 	return (GF_Box *)tmp;
267 }
268 
269 #ifndef GPAC_DISABLE_ISOM_WRITE
270 
cprt_Write(GF_Box * s,GF_BitStream * bs)271 GF_Err cprt_Write(GF_Box *s, GF_BitStream *bs)
272 {
273 	GF_Err e;
274 	GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;
275 
276 	e = gf_isom_full_box_write(s, bs);
277 	if (e) return e;
278 	gf_bs_write_int(bs, 0, 1);
279 	if (ptr->packedLanguageCode[0]) {
280 		gf_bs_write_int(bs, ptr->packedLanguageCode[0] - 0x60, 5);
281 		gf_bs_write_int(bs, ptr->packedLanguageCode[1] - 0x60, 5);
282 		gf_bs_write_int(bs, ptr->packedLanguageCode[2] - 0x60, 5);
283 	}
284 	else {
285 		gf_bs_write_int(bs, 0, 15);
286 	}
287 	if (ptr->notice) {
288 		gf_bs_write_data(bs, ptr->notice, (u32)(strlen(ptr->notice) + 1));
289 	}
290 	return GF_OK;
291 }
292 
cprt_Size(GF_Box * s)293 GF_Err cprt_Size(GF_Box *s)
294 {
295 	GF_Err e;
296 	GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;
297 	e = gf_isom_full_box_get_size(s);
298 	if (e) return e;
299 	ptr->size += 2;
300 	if (ptr->notice)
301 		ptr->size += strlen(ptr->notice) + 1;
302 	return GF_OK;
303 }
304 
305 #endif /*GPAC_DISABLE_ISOM_WRITE*/
306 
kind_del(GF_Box * s)307 void kind_del(GF_Box *s)
308 {
309 	GF_KindBox *ptr = (GF_KindBox *)s;
310 	if (ptr == NULL) return;
311 	if (ptr->schemeURI) gf_free(ptr->schemeURI);
312 	if (ptr->value) gf_free(ptr->value);
313 	gf_free(ptr);
314 }
315 
kind_Read(GF_Box * s,GF_BitStream * bs)316 GF_Err kind_Read(GF_Box *s, GF_BitStream *bs)
317 {
318 	GF_Err e;
319 	GF_KindBox *ptr = (GF_KindBox *)s;
320 
321 	e = gf_isom_full_box_read(s, bs);
322 	if (e) return e;
323 
324 	if (ptr->size) {
325 		u32 bytesToRead = (u32)ptr->size;
326 		char *data;
327 		u32 schemeURIlen;
328 		data = (char*)gf_malloc(bytesToRead * sizeof(char));
329 		if (data == NULL) return GF_OUT_OF_MEM;
330 		gf_bs_read_data(bs, data, bytesToRead);
331 		/*safety check in case the string is not null-terminated*/
332 		if (data[bytesToRead - 1]) {
333 			char *str = (char*)gf_malloc((u32)bytesToRead + 1);
334 			memcpy(str, data, (u32)bytesToRead);
335 			str[ptr->size] = 0;
336 			gf_free(data);
337 			data = str;
338 			bytesToRead++;
339 		}
340 		ptr->schemeURI = gf_strdup(data);
341 		schemeURIlen = (u32)strlen(data);
342 		if (bytesToRead > schemeURIlen + 1) {
343 			/* read the value */
344 			char *data_value = data + schemeURIlen + 1;
345 			ptr->value = gf_strdup(data_value);
346 		}
347 		gf_free(data);
348 	}
349 	return GF_OK;
350 }
351 
kind_New()352 GF_Box *kind_New()
353 {
354 	ISOM_DECL_BOX_ALLOC(GF_KindBox, GF_ISOM_BOX_TYPE_KIND);
355 	gf_isom_full_box_init((GF_Box *)tmp);
356 	return (GF_Box *)tmp;
357 }
358 
359 #ifndef GPAC_DISABLE_ISOM_WRITE
360 
kind_Write(GF_Box * s,GF_BitStream * bs)361 GF_Err kind_Write(GF_Box *s, GF_BitStream *bs)
362 {
363 	GF_Err e;
364 	GF_KindBox *ptr = (GF_KindBox *)s;
365 
366 	e = gf_isom_full_box_write(s, bs);
367 	if (e) return e;
368 	gf_bs_write_data(bs, ptr->schemeURI, (u32)(strlen(ptr->schemeURI) + 1));
369 	if (ptr->value) {
370 		gf_bs_write_data(bs, ptr->value, (u32)(strlen(ptr->value) + 1));
371 	}
372 	return GF_OK;
373 }
374 
kind_Size(GF_Box * s)375 GF_Err kind_Size(GF_Box *s)
376 {
377 	GF_Err e;
378 	GF_KindBox *ptr = (GF_KindBox *)s;
379 	e = gf_isom_full_box_get_size(s);
380 	if (e) return e;
381 	ptr->size += strlen(ptr->schemeURI) + 1;
382 	if (ptr->value) {
383 		ptr->size += strlen(ptr->value) + 1;
384 	}
385 	return GF_OK;
386 }
387 
388 #endif /*GPAC_DISABLE_ISOM_WRITE*/
389 
ctts_del(GF_Box * s)390 void ctts_del(GF_Box *s)
391 {
392 	GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
393 	if (ptr->entries) gf_free(ptr->entries);
394 	gf_free(ptr);
395 }
396 
397 
398 
ctts_Read(GF_Box * s,GF_BitStream * bs)399 GF_Err ctts_Read(GF_Box *s, GF_BitStream *bs)
400 {
401 	GF_Err e;
402 	u32 i;
403 	u32 sampleCount;
404 	GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
405 
406 	e = gf_isom_full_box_read(s, bs);
407 	if (e) return e;
408 	ptr->nb_entries = gf_bs_read_u32(bs);
409 	ptr->alloc_size = ptr->nb_entries;
410 	ptr->entries = (GF_DttsEntry *)gf_malloc(sizeof(GF_DttsEntry)*ptr->alloc_size);
411 	if (!ptr->entries) return GF_OUT_OF_MEM;
412 	sampleCount = 0;
413 	for (i = 0; i<ptr->nb_entries; i++) {
414 		ptr->entries[i].sampleCount = gf_bs_read_u32(bs);
415 		if (ptr->version)
416 			ptr->entries[i].decodingOffset = gf_bs_read_int(bs, 32);
417 		else
418 			ptr->entries[i].decodingOffset = (s32)gf_bs_read_u32(bs);
419 		sampleCount += ptr->entries[i].sampleCount;
420 	}
421 #ifndef GPAC_DISABLE_ISOM_WRITE
422 	ptr->w_LastSampleNumber = sampleCount;
423 #endif
424 	return GF_OK;
425 }
426 
ctts_New()427 GF_Box *ctts_New()
428 {
429 	ISOM_DECL_BOX_ALLOC(GF_CompositionOffsetBox, GF_ISOM_BOX_TYPE_CTTS);
430 
431 	gf_isom_full_box_init((GF_Box *)tmp);
432 	return (GF_Box *)tmp;
433 }
434 
435 
436 
437 #ifndef GPAC_DISABLE_ISOM_WRITE
438 
ctts_Write(GF_Box * s,GF_BitStream * bs)439 GF_Err ctts_Write(GF_Box *s, GF_BitStream *bs)
440 {
441 	GF_Err e;
442 	u32 i;
443 	GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
444 
445 	e = gf_isom_full_box_write(s, bs);
446 	if (e) return e;
447 	gf_bs_write_u32(bs, ptr->nb_entries);
448 	for (i = 0; i<ptr->nb_entries; i++) {
449 		gf_bs_write_u32(bs, ptr->entries[i].sampleCount);
450 		if (ptr->version) {
451 			gf_bs_write_int(bs, ptr->entries[i].decodingOffset, 32);
452 		}
453 		else {
454 			gf_bs_write_u32(bs, (u32)ptr->entries[i].decodingOffset);
455 		}
456 	}
457 	return GF_OK;
458 }
459 
ctts_Size(GF_Box * s)460 GF_Err ctts_Size(GF_Box *s)
461 {
462 	GF_Err e;
463 	GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
464 
465 	e = gf_isom_full_box_get_size(s);
466 	if (e) return e;
467 	ptr->size += 4 + (8 * ptr->nb_entries);
468 	return GF_OK;
469 }
470 
471 #endif /*GPAC_DISABLE_ISOM_WRITE*/
472 
cslg_del(GF_Box * s)473 void cslg_del(GF_Box *s)
474 {
475 	GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
476 	if (ptr == NULL) return;
477 	gf_free(ptr);
478 	return;
479 }
480 
cslg_Read(GF_Box * s,GF_BitStream * bs)481 GF_Err cslg_Read(GF_Box *s, GF_BitStream *bs)
482 {
483 	GF_Err e;
484 	GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
485 
486 	e = gf_isom_full_box_read(s, bs);
487 	if (e) return e;
488 	ptr->compositionToDTSShift = gf_bs_read_int(bs, 32);
489 	ptr->leastDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
490 	ptr->greatestDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
491 	ptr->compositionStartTime = gf_bs_read_int(bs, 32);
492 	ptr->compositionEndTime = gf_bs_read_int(bs, 32);
493 	return GF_OK;
494 }
495 
cslg_New()496 GF_Box *cslg_New()
497 {
498 	ISOM_DECL_BOX_ALLOC(GF_CompositionToDecodeBox, GF_ISOM_BOX_TYPE_CSLG);
499 
500 	gf_isom_full_box_init((GF_Box *)tmp);
501 	return (GF_Box *)tmp;
502 }
503 
504 #ifndef GPAC_DISABLE_ISOM_WRITE
505 
cslg_Write(GF_Box * s,GF_BitStream * bs)506 GF_Err cslg_Write(GF_Box *s, GF_BitStream *bs)
507 {
508 	GF_Err e;
509 	GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
510 
511 	e = gf_isom_full_box_write(s, bs);
512 	if (e) return e;
513 	gf_bs_write_int(bs, ptr->compositionToDTSShift, 32);
514 	gf_bs_write_int(bs, ptr->leastDecodeToDisplayDelta, 32);
515 	gf_bs_write_int(bs, ptr->greatestDecodeToDisplayDelta, 32);
516 	gf_bs_write_int(bs, ptr->compositionStartTime, 32);
517 	gf_bs_write_int(bs, ptr->compositionEndTime, 32);
518 	return GF_OK;
519 }
520 
cslg_Size(GF_Box * s)521 GF_Err cslg_Size(GF_Box *s)
522 {
523 	GF_Err e;
524 	GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
525 
526 	e = gf_isom_full_box_get_size(s);
527 	if (e) return e;
528 	ptr->size += 20;
529 	return GF_OK;
530 }
531 
532 #endif /*GPAC_DISABLE_ISOM_WRITE*/
533 
url_del(GF_Box * s)534 void url_del(GF_Box *s)
535 {
536 	GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
537 	if (ptr == NULL) return;
538 	if (ptr->location) gf_free(ptr->location);
539 	gf_free(ptr);
540 	return;
541 }
542 
543 
url_Read(GF_Box * s,GF_BitStream * bs)544 GF_Err url_Read(GF_Box *s, GF_BitStream *bs)
545 {
546 	GF_Err e;
547 	GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
548 
549 	e = gf_isom_full_box_read(s, bs);
550 	if (e) return e;
551 	if (ptr->size) {
552 		ptr->location = (char*)gf_malloc((u32)ptr->size);
553 		if (!ptr->location) return GF_OUT_OF_MEM;
554 		gf_bs_read_data(bs, ptr->location, (u32)ptr->size);
555 	}
556 	return GF_OK;
557 }
558 
url_New()559 GF_Box *url_New()
560 {
561 	ISOM_DECL_BOX_ALLOC(GF_DataEntryURLBox, GF_ISOM_BOX_TYPE_URL);
562 	gf_isom_full_box_init((GF_Box *)tmp);
563 	return (GF_Box *)tmp;
564 }
565 
566 #ifndef GPAC_DISABLE_ISOM_WRITE
567 
url_Write(GF_Box * s,GF_BitStream * bs)568 GF_Err url_Write(GF_Box *s, GF_BitStream *bs)
569 {
570 	GF_Err e;
571 	GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
572 
573 	e = gf_isom_full_box_write(s, bs);
574 	if (e) return e;
575 	//the flag set indicates we have a string (WE HAVE TO for URLs)
576 	if (!(ptr->flags & 1)) {
577 		if (ptr->location) {
578 			gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1);
579 		}
580 	}
581 	return GF_OK;
582 }
583 
url_Size(GF_Box * s)584 GF_Err url_Size(GF_Box *s)
585 {
586 	GF_Err e;
587 	GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
588 
589 	e = gf_isom_full_box_get_size(s);
590 	if (e) return e;
591 	if (!(ptr->flags & 1)) {
592 		if (ptr->location) ptr->size += 1 + strlen(ptr->location);
593 	}
594 	return GF_OK;
595 }
596 
597 #endif /*GPAC_DISABLE_ISOM_WRITE*/
598 
urn_del(GF_Box * s)599 void urn_del(GF_Box *s)
600 {
601 	GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
602 	if (ptr == NULL) return;
603 	if (ptr->location) gf_free(ptr->location);
604 	if (ptr->nameURN) gf_free(ptr->nameURN);
605 	gf_free(ptr);
606 }
607 
608 
urn_Read(GF_Box * s,GF_BitStream * bs)609 GF_Err urn_Read(GF_Box *s, GF_BitStream *bs)
610 {
611 	GF_Err e;
612 	u32 i, to_read;
613 	char *tmpName;
614 	GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
615 	e = gf_isom_full_box_read(s, bs);
616 	if (e) return e;
617 	if (!ptr->size) return GF_OK;
618 
619 	//here we have to handle that in a clever way
620 	to_read = (u32)ptr->size;
621 	tmpName = (char*)gf_malloc(sizeof(char) * to_read);
622 	if (!tmpName) return GF_OUT_OF_MEM;
623 	//get the data
624 	gf_bs_read_data(bs, tmpName, to_read);
625 
626 	//then get the break
627 	i = 0;
628 	while ((tmpName[i] != 0) && (i < to_read)) {
629 		i++;
630 	}
631 	//check the data is consistent
632 	if (i == to_read) {
633 		gf_free(tmpName);
634 		return GF_ISOM_INVALID_FILE;
635 	}
636 	//no NULL char, URL is not specified
637 	if (i == to_read - 1) {
638 		ptr->nameURN = tmpName;
639 		ptr->location = NULL;
640 		return GF_OK;
641 	}
642 	//OK, this has both URN and URL
643 	ptr->nameURN = (char*)gf_malloc(sizeof(char) * (i + 1));
644 	if (!ptr->nameURN) {
645 		gf_free(tmpName);
646 		return GF_OUT_OF_MEM;
647 	}
648 	ptr->location = (char*)gf_malloc(sizeof(char) * (to_read - i - 1));
649 	if (!ptr->location) {
650 		gf_free(tmpName);
651 		gf_free(ptr->nameURN);
652 		ptr->nameURN = NULL;
653 		return GF_OUT_OF_MEM;
654 	}
655 	memcpy(ptr->nameURN, tmpName, i + 1);
656 	memcpy(ptr->location, tmpName + i + 1, (to_read - i - 1));
657 	gf_free(tmpName);
658 	return GF_OK;
659 }
660 
urn_New()661 GF_Box *urn_New()
662 {
663 	ISOM_DECL_BOX_ALLOC(GF_DataEntryURNBox, GF_ISOM_BOX_TYPE_URN);
664 	gf_isom_full_box_init((GF_Box *)tmp);
665 	return (GF_Box *)tmp;
666 }
667 
668 #ifndef GPAC_DISABLE_ISOM_WRITE
669 
670 
urn_Write(GF_Box * s,GF_BitStream * bs)671 GF_Err urn_Write(GF_Box *s, GF_BitStream *bs)
672 {
673 	GF_Err e;
674 	GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
675 
676 	e = gf_isom_full_box_write(s, bs);
677 	if (e) return e;
678 	//the flag set indicates we have a string (WE HAVE TO for URLs)
679 	if (!(ptr->flags & 1)) {
680 		//to check, the spec says: First name, then location
681 		if (ptr->nameURN) {
682 			gf_bs_write_data(bs, ptr->nameURN, (u32)strlen(ptr->nameURN) + 1);
683 		}
684 		if (ptr->location) {
685 			gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1);
686 		}
687 	}
688 	return GF_OK;
689 }
690 
urn_Size(GF_Box * s)691 GF_Err urn_Size(GF_Box *s)
692 {
693 	GF_Err e;
694 	GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
695 
696 	e = gf_isom_full_box_get_size(s);
697 	if (e) return e;
698 	if (!(ptr->flags & 1)) {
699 		if (ptr->nameURN) ptr->size += 1 + strlen(ptr->nameURN);
700 		if (ptr->location) ptr->size += 1 + strlen(ptr->location);
701 	}
702 	return GF_OK;
703 }
704 
705 #endif /*GPAC_DISABLE_ISOM_WRITE*/
706 
defa_del(GF_Box * s)707 void defa_del(GF_Box *s)
708 {
709 	GF_UnknownBox *ptr = (GF_UnknownBox *)s;
710 	if (!s) return;
711 	if (ptr->data) gf_free(ptr->data);
712 	gf_free(ptr);
713 }
714 
715 
defa_Read(GF_Box * s,GF_BitStream * bs)716 GF_Err defa_Read(GF_Box *s, GF_BitStream *bs)
717 {
718 	u32 bytesToRead;
719 	GF_UnknownBox *ptr = (GF_UnknownBox *)s;
720 	if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE;
721 	bytesToRead = (u32)(ptr->size);
722 
723 	if (!bytesToRead) return GF_OK;
724 	if (bytesToRead>1000000) {
725 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Unknown box %s (0x%08X) with payload larger than 1 MBytes, ignoring\n", gf_4cc_to_str(ptr->type), ptr->type));
726 		gf_bs_skip_bytes(bs, ptr->dataSize);
727 		return GF_OK;
728 	}
729 
730 	ptr->data = (char*)gf_malloc(bytesToRead);
731 	if (ptr->data == NULL) return GF_OUT_OF_MEM;
732 	ptr->dataSize = bytesToRead;
733 	gf_bs_read_data(bs, ptr->data, ptr->dataSize);
734 	return GF_OK;
735 }
736 
737 //warning: we don't have any boxType, trick has to be done while creating..
defa_New()738 GF_Box *defa_New()
739 {
740 	ISOM_DECL_BOX_ALLOC(GF_UnknownBox, 0);
741 	return (GF_Box *)tmp;
742 }
743 
744 #ifndef GPAC_DISABLE_ISOM_WRITE
745 
defa_Write(GF_Box * s,GF_BitStream * bs)746 GF_Err defa_Write(GF_Box *s, GF_BitStream *bs)
747 {
748 	GF_Err e;
749 	GF_UnknownBox *ptr = (GF_UnknownBox *)s;
750 	if (!s) return GF_BAD_PARAM;
751 
752 	e = gf_isom_box_write_header(s, bs);
753 	if (e) return e;
754 
755 	if (ptr->dataSize && ptr->data) {
756 		gf_bs_write_data(bs, ptr->data, ptr->dataSize);
757 	}
758 	return GF_OK;
759 }
760 
defa_Size(GF_Box * s)761 GF_Err defa_Size(GF_Box *s)
762 {
763 	GF_Err e;
764 	GF_UnknownBox *ptr = (GF_UnknownBox *)s;
765 	e = gf_isom_box_get_size(s);
766 	if (e) return e;
767 
768 	if (ptr->dataSize && ptr->data) {
769 		ptr->size += ptr->dataSize;
770 	}
771 	return GF_OK;
772 }
773 
774 #endif /*GPAC_DISABLE_ISOM_WRITE*/
775 
776 
uuid_del(GF_Box * s)777 void uuid_del(GF_Box *s)
778 {
779 	GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *)s;
780 	if (!s) return;
781 	if (ptr->data) gf_free(ptr->data);
782 	gf_free(ptr);
783 }
784 
785 
uuid_Read(GF_Box * s,GF_BitStream * bs)786 GF_Err uuid_Read(GF_Box *s, GF_BitStream *bs)
787 {
788 	u32 bytesToRead;
789 	GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *)s;
790 	if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE;
791 	bytesToRead = (u32)(ptr->size);
792 
793 	if (bytesToRead) {
794 		ptr->data = (char*)gf_malloc(bytesToRead);
795 		if (ptr->data == NULL) return GF_OUT_OF_MEM;
796 		ptr->dataSize = bytesToRead;
797 		gf_bs_read_data(bs, ptr->data, ptr->dataSize);
798 	}
799 	return GF_OK;
800 }
801 
uuid_New()802 GF_Box *uuid_New()
803 {
804 	ISOM_DECL_BOX_ALLOC(GF_UnknownUUIDBox, GF_ISOM_BOX_TYPE_UUID);
805 	return (GF_Box *)tmp;
806 }
807 
808 #ifndef GPAC_DISABLE_ISOM_WRITE
809 
uuid_Write(GF_Box * s,GF_BitStream * bs)810 GF_Err uuid_Write(GF_Box *s, GF_BitStream *bs)
811 {
812 	GF_Err e;
813 	GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox*)s;
814 	if (!s) return GF_BAD_PARAM;
815 
816 	e = gf_isom_box_write_header(s, bs);
817 	if (e) return e;
818 	if (ptr->data) {
819 		gf_bs_write_data(bs, ptr->data, ptr->dataSize);
820 	}
821 	return GF_OK;
822 }
823 
uuid_Size(GF_Box * s)824 GF_Err uuid_Size(GF_Box *s)
825 {
826 	GF_Err e;
827 	GF_UnknownUUIDBox*ptr = (GF_UnknownUUIDBox*)s;
828 	e = gf_isom_box_get_size(s);
829 	if (e) return e;
830 	ptr->size += ptr->dataSize;
831 	return GF_OK;
832 }
833 
834 #endif /*GPAC_DISABLE_ISOM_WRITE*/
835 
836 
dinf_del(GF_Box * s)837 void dinf_del(GF_Box *s)
838 {
839 	GF_DataInformationBox *ptr = (GF_DataInformationBox *)s;
840 	if (ptr == NULL) return;
841 	gf_isom_box_del((GF_Box *)ptr->dref);
842 	gf_free(ptr);
843 }
844 
845 
dinf_AddBox(GF_Box * s,GF_Box * a)846 GF_Err dinf_AddBox(GF_Box *s, GF_Box *a)
847 {
848 	GF_DataInformationBox *ptr = (GF_DataInformationBox *)s;
849 	switch (a->type) {
850 	case GF_ISOM_BOX_TYPE_DREF:
851 		if (ptr->dref) ERROR_ON_DUPLICATED_BOX(a, ptr)
852 
853 			ptr->dref = (GF_DataReferenceBox *)a;
854 		return GF_OK;
855 	default:
856 		return gf_isom_box_add_default(s, a);
857 	}
858 	return GF_OK;
859 }
860 
dinf_Read(GF_Box * s,GF_BitStream * bs)861 GF_Err dinf_Read(GF_Box *s, GF_BitStream *bs)
862 {
863 	GF_Err e = gf_isom_read_box_list(s, bs, dinf_AddBox);
864 	if (e) {
865 		return e;
866 	}
867 	if (!((GF_DataInformationBox *)s)->dref) {
868 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("Missing dref box in dinf\n"));
869 		((GF_DataInformationBox *)s)->dref = (GF_DataReferenceBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_DREF);
870 	}
871 	return GF_OK;
872 }
873 
dinf_New()874 GF_Box *dinf_New()
875 {
876 	ISOM_DECL_BOX_ALLOC(GF_DataInformationBox, GF_ISOM_BOX_TYPE_DINF);
877 	return (GF_Box *)tmp;
878 }
879 
880 #ifndef GPAC_DISABLE_ISOM_WRITE
881 
dinf_Write(GF_Box * s,GF_BitStream * bs)882 GF_Err dinf_Write(GF_Box *s, GF_BitStream *bs)
883 {
884 	GF_Err e;
885 	GF_DataInformationBox *ptr = (GF_DataInformationBox *)s;
886 
887 	e = gf_isom_box_write_header(s, bs);
888 	if (e) return e;
889 	if (ptr->dref) {
890 		e = gf_isom_box_write((GF_Box *)ptr->dref, bs);
891 		if (e) return e;
892 	}
893 	return GF_OK;
894 }
895 
dinf_Size(GF_Box * s)896 GF_Err dinf_Size(GF_Box *s)
897 {
898 	GF_Err e;
899 	GF_DataInformationBox *ptr = (GF_DataInformationBox *)s;
900 	e = gf_isom_box_get_size(s);
901 	if (e) return e;
902 	if (ptr->dref) {
903 		e = gf_isom_box_size((GF_Box *)ptr->dref);
904 		if (e) return e;
905 		ptr->size += ptr->dref->size;
906 	}
907 	return GF_OK;
908 }
909 
910 #endif /*GPAC_DISABLE_ISOM_WRITE*/
911 
dref_del(GF_Box * s)912 void dref_del(GF_Box *s)
913 {
914 	GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
915 	if (ptr == NULL) return;
916 	gf_free(ptr);
917 }
918 
919 
dref_AddDataEntry(GF_Box * ptr,GF_Box * entry)920 GF_Err dref_AddDataEntry(GF_Box *ptr, GF_Box *entry)
921 {
922 	if (entry->type == GF_4CC('a', 'l', 'i', 's')) {
923 		GF_DataEntryURLBox *urle = (GF_DataEntryURLBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_URL);
924 		urle->flags = 1;
925 		gf_isom_box_del(entry);
926 		gf_isom_box_add_default(ptr, (GF_Box *)urle);
927 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[iso file] Apple \'alis\' box found, not supported - converting to self-pointing \'url \' \n"));
928 	}
929 	else {
930 		return gf_isom_box_add_default(ptr, entry);
931 	}
932 	return GF_OK;
933 }
934 
dref_Read(GF_Box * s,GF_BitStream * bs)935 GF_Err dref_Read(GF_Box *s, GF_BitStream *bs)
936 {
937 	GF_Err e;
938 	//u32 count;
939 	GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
940 
941 	if (ptr == NULL) return GF_BAD_PARAM;
942 	e = gf_isom_full_box_read(s, bs);
943 	if (e) return e;
944 	//count =
945 	gf_bs_read_u32(bs);
946 	ptr->size -= 4;
947 
948 	return gf_isom_read_box_list(s, bs, dref_AddDataEntry);
949 }
950 
dref_New()951 GF_Box *dref_New()
952 {
953 	ISOM_DECL_BOX_ALLOC(GF_DataReferenceBox, GF_ISOM_BOX_TYPE_DREF);
954 	gf_isom_full_box_init((GF_Box *)tmp);
955 	return (GF_Box *)tmp;
956 }
957 
958 
959 #ifndef GPAC_DISABLE_ISOM_WRITE
960 
dref_Write(GF_Box * s,GF_BitStream * bs)961 GF_Err dref_Write(GF_Box *s, GF_BitStream *bs)
962 {
963 	GF_Err e;
964 	u32 count;
965 	GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
966 	if (!s) return GF_BAD_PARAM;
967 
968 	e = gf_isom_full_box_write(s, bs);
969 	if (e) return e;
970 	count = ptr->other_boxes ? gf_list_count(ptr->other_boxes) : 0;
971 	gf_bs_write_u32(bs, count);
972 	return GF_OK;
973 }
974 
dref_Size(GF_Box * s)975 GF_Err dref_Size(GF_Box *s)
976 {
977 	GF_Err e;
978 	GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
979 	if (!s) return GF_BAD_PARAM;
980 
981 	e = gf_isom_full_box_get_size(s);
982 	if (e) return e;
983 	ptr->size += 4;
984 	return GF_OK;
985 }
986 
987 #endif /*GPAC_DISABLE_ISOM_WRITE*/
988 
edts_del(GF_Box * s)989 void edts_del(GF_Box *s)
990 {
991 	GF_EditBox *ptr = (GF_EditBox *)s;
992 	gf_isom_box_del((GF_Box *)ptr->editList);
993 	gf_free(ptr);
994 }
995 
996 
edts_AddBox(GF_Box * s,GF_Box * a)997 GF_Err edts_AddBox(GF_Box *s, GF_Box *a)
998 {
999 	GF_EditBox *ptr = (GF_EditBox *)s;
1000 	if (a->type == GF_ISOM_BOX_TYPE_ELST) {
1001 		if (ptr->editList) return GF_BAD_PARAM;
1002 		ptr->editList = (GF_EditListBox *)a;
1003 		return GF_OK;
1004 	}
1005 	else {
1006 		return gf_isom_box_add_default(s, a);
1007 	}
1008 	return GF_OK;
1009 }
1010 
1011 
edts_Read(GF_Box * s,GF_BitStream * bs)1012 GF_Err edts_Read(GF_Box *s, GF_BitStream *bs)
1013 {
1014 	return gf_isom_read_box_list(s, bs, edts_AddBox);
1015 }
1016 
edts_New()1017 GF_Box *edts_New()
1018 {
1019 	ISOM_DECL_BOX_ALLOC(GF_EditBox, GF_ISOM_BOX_TYPE_EDTS);
1020 	return (GF_Box *)tmp;
1021 }
1022 
1023 #ifndef GPAC_DISABLE_ISOM_WRITE
1024 
edts_Write(GF_Box * s,GF_BitStream * bs)1025 GF_Err edts_Write(GF_Box *s, GF_BitStream *bs)
1026 {
1027 	GF_Err e;
1028 	GF_EditBox *ptr = (GF_EditBox *)s;
1029 
1030 	//here we have a trick: if editList is empty, skip the box
1031 	if (ptr->editList && gf_list_count(ptr->editList->entryList)) {
1032 		e = gf_isom_box_write_header(s, bs);
1033 		if (e) return e;
1034 		e = gf_isom_box_write((GF_Box *)ptr->editList, bs);
1035 		if (e) return e;
1036 	}
1037 	return GF_OK;
1038 }
1039 
edts_Size(GF_Box * s)1040 GF_Err edts_Size(GF_Box *s)
1041 {
1042 	GF_Err e;
1043 	GF_EditBox *ptr = (GF_EditBox *)s;
1044 
1045 	//here we have a trick: if editList is empty, skip the box
1046 	if (!ptr->editList || !gf_list_count(ptr->editList->entryList)) {
1047 		ptr->size = 0;
1048 	}
1049 	else {
1050 		e = gf_isom_box_get_size(s);
1051 		if (e) return e;
1052 		e = gf_isom_box_size((GF_Box *)ptr->editList);
1053 		if (e) return e;
1054 		ptr->size += ptr->editList->size;
1055 	}
1056 	return GF_OK;
1057 }
1058 
1059 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1060 
elst_del(GF_Box * s)1061 void elst_del(GF_Box *s)
1062 {
1063 	GF_EditListBox *ptr;
1064 	GF_EdtsEntry *p;
1065 	u32 nb_entries;
1066 	u32 i;
1067 
1068 	ptr = (GF_EditListBox *)s;
1069 	if (ptr == NULL) return;
1070 	nb_entries = gf_list_count(ptr->entryList);
1071 	for (i = 0; i < nb_entries; i++) {
1072 		p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
1073 		if (p) gf_free(p);
1074 	}
1075 	gf_list_del(ptr->entryList);
1076 	gf_free(ptr);
1077 }
1078 
1079 
1080 
1081 
elst_Read(GF_Box * s,GF_BitStream * bs)1082 GF_Err elst_Read(GF_Box *s, GF_BitStream *bs)
1083 {
1084 	GF_Err e;
1085 	u32 entries;
1086 	s32 tr;
1087 	u32 nb_entries;
1088 	GF_EdtsEntry *p;
1089 	GF_EditListBox *ptr = (GF_EditListBox *)s;
1090 
1091 	e = gf_isom_full_box_read(s, bs);
1092 	if (e) return e;
1093 	nb_entries = gf_bs_read_u32(bs);
1094 
1095 	for (entries = 0; entries < nb_entries; entries++) {
1096 		p = (GF_EdtsEntry *)gf_malloc(sizeof(GF_EdtsEntry));
1097 		if (!p) return GF_OUT_OF_MEM;
1098 		if (ptr->version == 1) {
1099 			p->segmentDuration = gf_bs_read_u64(bs);
1100 			p->mediaTime = (s64)gf_bs_read_u64(bs);
1101 		}
1102 		else {
1103 			p->segmentDuration = gf_bs_read_u32(bs);
1104 			tr = gf_bs_read_u32(bs);
1105 			p->mediaTime = (s64)tr;
1106 		}
1107 		p->mediaRate = gf_bs_read_u16(bs);
1108 		gf_bs_read_u16(bs);
1109 		gf_list_add(ptr->entryList, p);
1110 	}
1111 	return GF_OK;
1112 }
1113 
elst_New()1114 GF_Box *elst_New()
1115 {
1116 	ISOM_DECL_BOX_ALLOC(GF_EditListBox, GF_ISOM_BOX_TYPE_ELST);
1117 
1118 	gf_isom_full_box_init((GF_Box *)tmp);
1119 	tmp->entryList = gf_list_new();
1120 	if (!tmp->entryList) {
1121 		gf_free(tmp);
1122 		return NULL;
1123 	}
1124 	return (GF_Box *)tmp;
1125 }
1126 
1127 #ifndef GPAC_DISABLE_ISOM_WRITE
1128 
elst_Write(GF_Box * s,GF_BitStream * bs)1129 GF_Err elst_Write(GF_Box *s, GF_BitStream *bs)
1130 {
1131 	GF_Err e;
1132 	u32 i;
1133 	u32 nb_entries;
1134 	GF_EdtsEntry *p;
1135 	GF_EditListBox *ptr = (GF_EditListBox *)s;
1136 	if (!ptr) return GF_BAD_PARAM;
1137 
1138 	nb_entries = gf_list_count(ptr->entryList);
1139 	e = gf_isom_full_box_write(s, bs);
1140 	if (e) return e;
1141 	gf_bs_write_u32(bs, nb_entries);
1142 	for (i = 0; i < nb_entries; i++) {
1143 		p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
1144 		if (ptr->version == 1) {
1145 			gf_bs_write_u64(bs, p->segmentDuration);
1146 			gf_bs_write_u64(bs, p->mediaTime);
1147 		}
1148 		else {
1149 			gf_bs_write_u32(bs, (u32)p->segmentDuration);
1150 			gf_bs_write_u32(bs, (s32)p->mediaTime);
1151 		}
1152 		gf_bs_write_u16(bs, p->mediaRate);
1153 		gf_bs_write_u16(bs, 0);
1154 	}
1155 	return GF_OK;
1156 }
1157 
elst_Size(GF_Box * s)1158 GF_Err elst_Size(GF_Box *s)
1159 {
1160 	GF_Err e;
1161 	u32 durtimebytes;
1162 	u32 i, nb_entries;
1163 	GF_EditListBox *ptr = (GF_EditListBox *)s;
1164 
1165 	e = gf_isom_full_box_get_size(s);
1166 	if (e) return e;
1167 	//entry count
1168 	ptr->size += 4;
1169 	nb_entries = gf_list_count(ptr->entryList);
1170 	ptr->version = 0;
1171 	for (i = 0; i<nb_entries; i++) {
1172 		GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
1173 		if ((p->segmentDuration>0xFFFFFFFF) || (p->mediaTime>0xFFFFFFFF)) {
1174 			ptr->version = 1;
1175 			break;
1176 		}
1177 	}
1178 	durtimebytes = (ptr->version == 1 ? 16 : 8) + 4;
1179 	ptr->size += (nb_entries * durtimebytes);
1180 	return GF_OK;
1181 }
1182 
1183 
1184 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1185 
esds_del(GF_Box * s)1186 void esds_del(GF_Box *s)
1187 {
1188 	GF_ESDBox *ptr = (GF_ESDBox *)s;
1189 	if (ptr == NULL)	return;
1190 	if (ptr->desc) gf_odf_desc_del((GF_Descriptor *)ptr->desc);
1191 	gf_free(ptr);
1192 }
1193 
1194 
esds_Read(GF_Box * s,GF_BitStream * bs)1195 GF_Err esds_Read(GF_Box *s, GF_BitStream *bs)
1196 {
1197 	GF_Err e;
1198 	u32 descSize;
1199 	char *enc_desc;
1200 	u32 SLIsPredefined(GF_SLConfig *sl);
1201 	GF_ESDBox *ptr = (GF_ESDBox *)s;
1202 
1203 	e = gf_isom_full_box_read(s, bs);
1204 	if (e) return e;
1205 	descSize = (u32)(ptr->size);
1206 
1207 	if (descSize) {
1208 		enc_desc = (char*)gf_malloc(sizeof(char) * descSize);
1209 		if (!enc_desc) return GF_OUT_OF_MEM;
1210 		//get the payload
1211 		gf_bs_read_data(bs, enc_desc, descSize);
1212 		//send it to the OD Codec
1213 		e = gf_odf_desc_read(enc_desc, descSize, (GF_Descriptor **)&ptr->desc);
1214 		//OK, free our desc
1215 		gf_free(enc_desc);
1216 		//we do not abbort on error, but skip the descritpor
1217 		if (e) {
1218 			ptr->desc = NULL;
1219 		}
1220 		else {
1221 			/*fix broken files*/
1222 			if (!ptr->desc->URLString) {
1223 				if (!ptr->desc->slConfig) {
1224 					ptr->desc->slConfig = (GF_SLConfig *)gf_odf_desc_new(GF_ODF_SLC_TAG);
1225 					ptr->desc->slConfig->predefined = SLPredef_MP4;
1226 				}
1227 				else if (ptr->desc->slConfig->predefined != SLPredef_MP4) {
1228 					ptr->desc->slConfig->predefined = SLPredef_MP4;
1229 					gf_odf_slc_set_pref(ptr->desc->slConfig);
1230 				}
1231 			}
1232 		}
1233 	}
1234 	return GF_OK;
1235 }
1236 
esds_New()1237 GF_Box *esds_New()
1238 {
1239 	ISOM_DECL_BOX_ALLOC(GF_ESDBox, GF_ISOM_BOX_TYPE_ESDS);
1240 
1241 	gf_isom_full_box_init((GF_Box *)tmp);
1242 	return (GF_Box *)tmp;
1243 }
1244 
1245 
1246 #ifndef GPAC_DISABLE_ISOM_WRITE
1247 
esds_Write(GF_Box * s,GF_BitStream * bs)1248 GF_Err esds_Write(GF_Box *s, GF_BitStream *bs)
1249 {
1250 	GF_Err e;
1251 	char *enc_desc;
1252 	u32 descSize = 0;
1253 	GF_ESDBox *ptr = (GF_ESDBox *)s;
1254 
1255 	e = gf_isom_full_box_write(s, bs);
1256 	if (e) return e;
1257 	e = gf_odf_desc_write((GF_Descriptor *)ptr->desc, &enc_desc, &descSize);
1258 	if (e) return e;
1259 	gf_bs_write_data(bs, enc_desc, descSize);
1260 	//free our buffer
1261 	gf_free(enc_desc);
1262 	return GF_OK;
1263 }
1264 
esds_Size(GF_Box * s)1265 GF_Err esds_Size(GF_Box *s)
1266 {
1267 	GF_Err e;
1268 	u32 descSize = 0;
1269 	GF_ESDBox *ptr = (GF_ESDBox *)s;
1270 	e = gf_isom_full_box_get_size(s);
1271 	if (e) return e;
1272 	descSize = gf_odf_desc_size((GF_Descriptor *)ptr->desc);
1273 	ptr->size += descSize;
1274 	return GF_OK;
1275 }
1276 
1277 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1278 
free_del(GF_Box * s)1279 void free_del(GF_Box *s)
1280 {
1281 	GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
1282 	if (ptr->data) gf_free(ptr->data);
1283 	gf_free(ptr);
1284 }
1285 
1286 
free_Read(GF_Box * s,GF_BitStream * bs)1287 GF_Err free_Read(GF_Box *s, GF_BitStream *bs)
1288 {
1289 	u32 bytesToRead;
1290 	GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
1291 
1292 	if (ptr->size > 0xFFFFFFFF) return GF_IO_ERR;
1293 
1294 	bytesToRead = (u32)(ptr->size);
1295 
1296 	if (bytesToRead) {
1297 		ptr->data = (char*)gf_malloc(bytesToRead * sizeof(char));
1298 		gf_bs_read_data(bs, ptr->data, bytesToRead);
1299 		ptr->dataSize = bytesToRead;
1300 	}
1301 	return GF_OK;
1302 }
1303 
free_New()1304 GF_Box *free_New()
1305 {
1306 	ISOM_DECL_BOX_ALLOC(GF_FreeSpaceBox, GF_ISOM_BOX_TYPE_FREE);
1307 	return (GF_Box *)tmp;
1308 }
1309 
1310 #ifndef GPAC_DISABLE_ISOM_WRITE
1311 
free_Write(GF_Box * s,GF_BitStream * bs)1312 GF_Err free_Write(GF_Box *s, GF_BitStream *bs)
1313 {
1314 	GF_Err e;
1315 	GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
1316 	if (ptr->original_4cc) {
1317 		u32 t = s->type;
1318 		s->type = ptr->original_4cc;
1319 		e = gf_isom_box_write_header(s, bs);
1320 		s->type = t;
1321 	}
1322 	else {
1323 		e = gf_isom_box_write_header(s, bs);
1324 	}
1325 	if (e) return e;
1326 	if (ptr->dataSize) {
1327 		if (ptr->data) {
1328 			gf_bs_write_data(bs, ptr->data, ptr->dataSize);
1329 		}
1330 		else {
1331 			u32 i = 0;
1332 			while (i<ptr->dataSize) {
1333 				gf_bs_write_u8(bs, 0);
1334 				i++;
1335 			}
1336 		}
1337 	}
1338 	return GF_OK;
1339 }
1340 
free_Size(GF_Box * s)1341 GF_Err free_Size(GF_Box *s)
1342 {
1343 	GF_Err e;
1344 	GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
1345 	e = gf_isom_box_get_size(s);
1346 	if (e) return e;
1347 	ptr->size += ptr->dataSize;
1348 	return GF_OK;
1349 }
1350 
1351 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1352 
ftyp_del(GF_Box * s)1353 void ftyp_del(GF_Box *s)
1354 {
1355 	GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;
1356 	if (ptr->altBrand) gf_free(ptr->altBrand);
1357 	gf_free(ptr);
1358 }
1359 
ftyp_New()1360 GF_Box *ftyp_New()
1361 {
1362 	ISOM_DECL_BOX_ALLOC(GF_FileTypeBox, GF_ISOM_BOX_TYPE_FTYP);
1363 	return (GF_Box *)tmp;
1364 }
1365 
ftyp_Read(GF_Box * s,GF_BitStream * bs)1366 GF_Err ftyp_Read(GF_Box *s, GF_BitStream *bs)
1367 {
1368 	u32 i;
1369 	GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;
1370 
1371 	if (ptr->size < 8) {
1372 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Found ftyp with size < 8, likely broken!\n"));
1373 		return GF_BAD_PARAM;
1374 	}
1375 	ptr->majorBrand = gf_bs_read_u32(bs);
1376 	ptr->minorVersion = gf_bs_read_u32(bs);
1377 	ptr->size -= 8;
1378 
1379 	ptr->altCount = ((u32)(ptr->size)) / 4;
1380 	if (!ptr->altCount) return GF_OK;
1381 	if (ptr->altCount * 4 != (u32)(ptr->size)) return GF_ISOM_INVALID_FILE;
1382 
1383 	ptr->altBrand = (u32*)gf_malloc(sizeof(u32)*ptr->altCount);
1384 	for (i = 0; i<ptr->altCount; i++) {
1385 		ptr->altBrand[i] = gf_bs_read_u32(bs);
1386 	}
1387 	return GF_OK;
1388 }
1389 
1390 
1391 
1392 #ifndef GPAC_DISABLE_ISOM_WRITE
1393 
ftyp_Write(GF_Box * s,GF_BitStream * bs)1394 GF_Err ftyp_Write(GF_Box *s, GF_BitStream *bs)
1395 {
1396 	GF_Err e;
1397 	u32 i;
1398 	GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;
1399 
1400 	e = gf_isom_box_write_header(s, bs);
1401 	if (e) return e;
1402 	gf_bs_write_u32(bs, ptr->majorBrand);
1403 	gf_bs_write_u32(bs, ptr->minorVersion);
1404 	for (i = 0; i<ptr->altCount; i++) {
1405 		gf_bs_write_u32(bs, ptr->altBrand[i]);
1406 	}
1407 	return GF_OK;
1408 }
1409 
ftyp_Size(GF_Box * s)1410 GF_Err ftyp_Size(GF_Box *s)
1411 {
1412 	GF_Err e;
1413 	GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;
1414 
1415 	e = gf_isom_box_get_size(s);
1416 	if (e) return e;
1417 	ptr->size += 8 + ptr->altCount * 4;
1418 	return GF_OK;
1419 }
1420 
1421 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1422 
1423 
1424 
gnrm_del(GF_Box * s)1425 void gnrm_del(GF_Box *s)
1426 {
1427 	GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
1428 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
1429 	if (ptr->data) gf_free(ptr->data);
1430 	gf_free(ptr);
1431 }
1432 
gnrm_New()1433 GF_Box *gnrm_New()
1434 {
1435 	ISOM_DECL_BOX_ALLOC(GF_GenericSampleEntryBox, GF_ISOM_BOX_TYPE_GNRM);
1436 
1437 	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
1438 	return (GF_Box *)tmp;
1439 }
1440 
1441 
1442 #ifndef GPAC_DISABLE_ISOM_WRITE
1443 
gnrm_Write(GF_Box * s,GF_BitStream * bs)1444 GF_Err gnrm_Write(GF_Box *s, GF_BitStream *bs)
1445 {
1446 	GF_Err e;
1447 	GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
1448 
1449 	//carefull we are not writing the box type but the entry type so switch for write
1450 	ptr->type = ptr->EntryType;
1451 	e = gf_isom_box_write_header(s, bs);
1452 	if (e) return e;
1453 	ptr->type = GF_ISOM_BOX_TYPE_GNRM;
1454 	gf_bs_write_data(bs, ptr->reserved, 6);
1455 	gf_bs_write_u16(bs, ptr->dataReferenceIndex);
1456 	gf_bs_write_data(bs, ptr->data, ptr->data_size);
1457 	return GF_OK;
1458 }
1459 
gnrm_Size(GF_Box * s)1460 GF_Err gnrm_Size(GF_Box *s)
1461 {
1462 	GF_Err e;
1463 	GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
1464 	s->type = ptr->EntryType;
1465 	e = gf_isom_box_get_size(s);
1466 	s->type = GF_ISOM_BOX_TYPE_GNRM;
1467 	if (e) return e;
1468 	ptr->size += 8 + ptr->data_size;
1469 	return GF_OK;
1470 }
1471 
1472 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1473 
1474 
gnrv_del(GF_Box * s)1475 void gnrv_del(GF_Box *s)
1476 {
1477 	GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
1478 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
1479 	if (ptr->data) gf_free(ptr->data);
1480 	gf_free(ptr);
1481 }
1482 
gnrv_New()1483 GF_Box *gnrv_New()
1484 {
1485 	ISOM_DECL_BOX_ALLOC(GF_GenericVisualSampleEntryBox, GF_ISOM_BOX_TYPE_GNRV);
1486 	gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox*)tmp);
1487 	return (GF_Box *)tmp;
1488 }
1489 
1490 
1491 #ifndef GPAC_DISABLE_ISOM_WRITE
1492 
gnrv_Write(GF_Box * s,GF_BitStream * bs)1493 GF_Err gnrv_Write(GF_Box *s, GF_BitStream *bs)
1494 {
1495 	GF_Err e;
1496 	GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
1497 
1498 	//carefull we are not writing the box type but the entry type so switch for write
1499 	ptr->type = ptr->EntryType;
1500 	e = gf_isom_box_write_header(s, bs);
1501 	if (e) return e;
1502 	ptr->type = GF_ISOM_BOX_TYPE_GNRV;
1503 
1504 	gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)ptr, bs);
1505 	gf_bs_write_data(bs, ptr->data, ptr->data_size);
1506 	return GF_OK;
1507 }
1508 
gnrv_Size(GF_Box * s)1509 GF_Err gnrv_Size(GF_Box *s)
1510 {
1511 	GF_Err e;
1512 	GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
1513 	s->type = ptr->EntryType;
1514 	e = gf_isom_box_get_size(s);
1515 	s->type = GF_ISOM_BOX_TYPE_GNRV;
1516 	if (e) return e;
1517 	gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);
1518 	ptr->size += ptr->data_size;
1519 	return GF_OK;
1520 }
1521 
1522 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1523 
1524 
1525 
gnra_del(GF_Box * s)1526 void gnra_del(GF_Box *s)
1527 {
1528 	GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
1529 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
1530 	if (ptr->data) gf_free(ptr->data);
1531 	gf_free(ptr);
1532 }
1533 
gnra_New()1534 GF_Box *gnra_New()
1535 {
1536 	ISOM_DECL_BOX_ALLOC(GF_GenericAudioSampleEntryBox, GF_ISOM_BOX_TYPE_GNRA);
1537 	gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
1538 	return (GF_Box *)tmp;
1539 }
1540 
1541 
1542 #ifndef GPAC_DISABLE_ISOM_WRITE
1543 
1544 
gnra_Write(GF_Box * s,GF_BitStream * bs)1545 GF_Err gnra_Write(GF_Box *s, GF_BitStream *bs)
1546 {
1547 	GF_Err e;
1548 	GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
1549 
1550 	//carefull we are not writing the box type but the entry type so switch for write
1551 	ptr->type = ptr->EntryType;
1552 	e = gf_isom_box_write_header(s, bs);
1553 	if (e) return e;
1554 	ptr->type = GF_ISOM_BOX_TYPE_GNRA;
1555 
1556 	gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox *)ptr, bs);
1557 	if (ptr->data) {
1558 		gf_bs_write_data(bs, ptr->data, ptr->data_size);
1559 	}
1560 	return GF_OK;
1561 }
1562 
gnra_Size(GF_Box * s)1563 GF_Err gnra_Size(GF_Box *s)
1564 {
1565 	GF_Err e;
1566 	GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
1567 	s->type = ptr->EntryType;
1568 	e = gf_isom_box_get_size(s);
1569 	s->type = GF_ISOM_BOX_TYPE_GNRA;
1570 	if (e) return e;
1571 	gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox *)s);
1572 	ptr->size += ptr->data_size;
1573 	return GF_OK;
1574 }
1575 
1576 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1577 
hdlr_del(GF_Box * s)1578 void hdlr_del(GF_Box *s)
1579 {
1580 	GF_HandlerBox *ptr = (GF_HandlerBox *)s;
1581 	if (ptr == NULL) return;
1582 	if (ptr->nameUTF8) gf_free(ptr->nameUTF8);
1583 	gf_free(ptr);
1584 }
1585 
1586 
hdlr_Read(GF_Box * s,GF_BitStream * bs)1587 GF_Err hdlr_Read(GF_Box *s, GF_BitStream *bs)
1588 {
1589 	GF_Err e;
1590 	GF_HandlerBox *ptr = (GF_HandlerBox *)s;
1591 
1592 	e = gf_isom_full_box_read(s, bs);
1593 	if (e) return e;
1594 	ptr->reserved1 = gf_bs_read_u32(bs);
1595 	ptr->handlerType = gf_bs_read_u32(bs);
1596 	gf_bs_read_data(bs, (char*)ptr->reserved2, 12);
1597 	ptr->size -= 20;
1598 	if (ptr->size) {
1599 		ptr->nameUTF8 = (char*)gf_malloc((u32)ptr->size);
1600 		if (ptr->nameUTF8 == NULL) return GF_OUT_OF_MEM;
1601 		gf_bs_read_data(bs, ptr->nameUTF8, (u32)ptr->size);
1602 		/*safety check in case the string is not null-terminated*/
1603 		if (ptr->nameUTF8[ptr->size - 1]) {
1604 			char *str = (char*)gf_malloc((u32)ptr->size + 1);
1605 			memcpy(str, ptr->nameUTF8, (u32)ptr->size);
1606 			str[ptr->size] = 0;
1607 			gf_free(ptr->nameUTF8);
1608 			ptr->nameUTF8 = str;
1609 		}
1610 	}
1611 	return GF_OK;
1612 }
1613 
hdlr_New()1614 GF_Box *hdlr_New()
1615 {
1616 	ISOM_DECL_BOX_ALLOC(GF_HandlerBox, GF_ISOM_BOX_TYPE_HDLR);
1617 	gf_isom_full_box_init((GF_Box *)tmp);
1618 	return (GF_Box *)tmp;
1619 }
1620 
1621 
1622 #ifndef GPAC_DISABLE_ISOM_WRITE
1623 
hdlr_Write(GF_Box * s,GF_BitStream * bs)1624 GF_Err hdlr_Write(GF_Box *s, GF_BitStream *bs)
1625 {
1626 	GF_Err e;
1627 	GF_HandlerBox *ptr = (GF_HandlerBox *)s;
1628 	e = gf_isom_full_box_write(s, bs);
1629 	if (e) return e;
1630 	gf_bs_write_u32(bs, ptr->reserved1);
1631 	gf_bs_write_u32(bs, ptr->handlerType);
1632 	gf_bs_write_data(bs, (char*)ptr->reserved2, 12);
1633 	if (ptr->nameUTF8) gf_bs_write_data(bs, ptr->nameUTF8, (u32)strlen(ptr->nameUTF8));
1634 	/*NULL-terminated string is written*/
1635 	gf_bs_write_u8(bs, 0);
1636 	return GF_OK;
1637 }
1638 
hdlr_Size(GF_Box * s)1639 GF_Err hdlr_Size(GF_Box *s)
1640 {
1641 	GF_Err e;
1642 	GF_HandlerBox *ptr = (GF_HandlerBox *)s;
1643 	e = gf_isom_full_box_get_size(s);
1644 	if (e) return e;
1645 	ptr->size += 20 + 1;
1646 	if (ptr->nameUTF8) ptr->size += strlen(ptr->nameUTF8);
1647 	return GF_OK;
1648 }
1649 
1650 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1651 
1652 
hinf_del(GF_Box * s)1653 void hinf_del(GF_Box *s)
1654 {
1655 	GF_HintInfoBox *hinf = (GF_HintInfoBox *)s;
1656 	gf_free(hinf);
1657 }
1658 
hinf_New()1659 GF_Box *hinf_New()
1660 {
1661 	ISOM_DECL_BOX_ALLOC(GF_HintInfoBox, GF_ISOM_BOX_TYPE_HINF);
1662 
1663 	tmp->other_boxes = gf_list_new();
1664 	return (GF_Box *)tmp;
1665 }
1666 
hinf_AddBox(GF_Box * s,GF_Box * a)1667 GF_Err hinf_AddBox(GF_Box *s, GF_Box *a)
1668 {
1669 	GF_MAXRBox *maxR;
1670 	GF_HintInfoBox *hinf = (GF_HintInfoBox *)s;
1671 	u32 i;
1672 	switch (a->type) {
1673 	case GF_ISOM_BOX_TYPE_MAXR:
1674 		i = 0;
1675 		while ((maxR = (GF_MAXRBox *)gf_list_enum(hinf->other_boxes, &i))) {
1676 			if ((maxR->type == GF_ISOM_BOX_TYPE_MAXR) && (maxR->granularity == ((GF_MAXRBox *)a)->granularity))
1677 				return GF_ISOM_INVALID_FILE;
1678 		}
1679 		break;
1680 	}
1681 	return gf_isom_box_add_default(s, a);
1682 }
1683 
1684 
hinf_Read(GF_Box * s,GF_BitStream * bs)1685 GF_Err hinf_Read(GF_Box *s, GF_BitStream *bs)
1686 {
1687 	return gf_isom_read_box_list(s, bs, hinf_AddBox);
1688 }
1689 
1690 #ifndef GPAC_DISABLE_ISOM_WRITE
1691 
hinf_Write(GF_Box * s,GF_BitStream * bs)1692 GF_Err hinf_Write(GF_Box *s, GF_BitStream *bs)
1693 {
1694 	//	GF_HintInfoBox *ptr = (GF_HintInfoBox *)s;
1695 	if (!s) return GF_BAD_PARAM;
1696 	return gf_isom_box_write_header(s, bs);
1697 }
1698 
hinf_Size(GF_Box * s)1699 GF_Err hinf_Size(GF_Box *s)
1700 {
1701 	//	GF_HintInfoBox *ptr = (GF_HintInfoBox *)s;
1702 	return gf_isom_box_get_size(s);
1703 }
1704 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1705 
hmhd_del(GF_Box * s)1706 void hmhd_del(GF_Box *s)
1707 {
1708 	GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
1709 	if (ptr == NULL) return;
1710 	gf_free(ptr);
1711 }
1712 
1713 
hmhd_Read(GF_Box * s,GF_BitStream * bs)1714 GF_Err hmhd_Read(GF_Box *s, GF_BitStream *bs)
1715 {
1716 	GF_Err e;
1717 	GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
1718 
1719 	e = gf_isom_full_box_read(s, bs);
1720 	if (e) return e;
1721 	ptr->maxPDUSize = gf_bs_read_u16(bs);
1722 	ptr->avgPDUSize = gf_bs_read_u16(bs);
1723 	ptr->maxBitrate = gf_bs_read_u32(bs);
1724 	ptr->avgBitrate = gf_bs_read_u32(bs);
1725 	ptr->slidingAverageBitrate = gf_bs_read_u32(bs);
1726 	return GF_OK;
1727 }
1728 
hmhd_New()1729 GF_Box *hmhd_New()
1730 {
1731 	ISOM_DECL_BOX_ALLOC(GF_HintMediaHeaderBox, GF_ISOM_BOX_TYPE_HMHD);
1732 
1733 	gf_isom_full_box_init((GF_Box *)tmp);
1734 	return (GF_Box *)tmp;
1735 }
1736 
1737 
1738 #ifndef GPAC_DISABLE_ISOM_WRITE
1739 
hmhd_Write(GF_Box * s,GF_BitStream * bs)1740 GF_Err hmhd_Write(GF_Box *s, GF_BitStream *bs)
1741 {
1742 	GF_Err e;
1743 	GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
1744 
1745 	e = gf_isom_full_box_write(s, bs);
1746 	if (e) return e;
1747 	gf_bs_write_u16(bs, ptr->maxPDUSize);
1748 	gf_bs_write_u16(bs, ptr->avgPDUSize);
1749 	gf_bs_write_u32(bs, ptr->maxBitrate);
1750 	gf_bs_write_u32(bs, ptr->avgBitrate);
1751 	gf_bs_write_u32(bs, ptr->slidingAverageBitrate);
1752 	return GF_OK;
1753 }
1754 
hmhd_Size(GF_Box * s)1755 GF_Err hmhd_Size(GF_Box *s)
1756 {
1757 	GF_Err e;
1758 	GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
1759 	e = gf_isom_full_box_get_size(s);
1760 	if (e) return e;
1761 	ptr->size += 16;
1762 	return GF_OK;
1763 }
1764 
1765 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1766 
hnti_New()1767 GF_Box *hnti_New()
1768 {
1769 	ISOM_DECL_BOX_ALLOC(GF_HintTrackInfoBox, GF_ISOM_BOX_TYPE_HNTI);
1770 
1771 	tmp->hints = gf_list_new();
1772 	if (!tmp->hints) {
1773 		gf_free(tmp);
1774 		return NULL;
1775 	}
1776 	return (GF_Box *)tmp;
1777 }
1778 
hnti_del(GF_Box * a)1779 void hnti_del(GF_Box *a)
1780 {
1781 	GF_Box *t;
1782 	GF_RTPBox *rtp;
1783 	GF_HintTrackInfoBox *ptr = (GF_HintTrackInfoBox *)a;
1784 	while (gf_list_count(ptr->hints)) {
1785 		t = (GF_Box*)gf_list_get(ptr->hints, 0);
1786 		if (t->type != GF_ISOM_BOX_TYPE_RTP) {
1787 			gf_isom_box_del(t);
1788 		}
1789 		else {
1790 			rtp = (GF_RTPBox *)t;
1791 			if (rtp->sdpText) gf_free(rtp->sdpText);
1792 			gf_free(rtp);
1793 		}
1794 		gf_list_rem(ptr->hints, 0);
1795 	}
1796 	gf_list_del(ptr->hints);
1797 	gf_free(ptr);
1798 }
1799 
hnti_AddBox(GF_HintTrackInfoBox * hnti,GF_Box * a)1800 GF_Err hnti_AddBox(GF_HintTrackInfoBox *hnti, GF_Box *a)
1801 {
1802 	if (!hnti || !a) return GF_BAD_PARAM;
1803 
1804 	switch (a->type) {
1805 		//this is the value for GF_RTPBox - same as HintSampleEntry for RTP !!!
1806 	case GF_ISOM_BOX_TYPE_RTP:
1807 	case GF_ISOM_BOX_TYPE_SDP:
1808 		if (hnti->SDP) return GF_BAD_PARAM;
1809 		hnti->SDP = a;
1810 		break;
1811 	default:
1812 		break;
1813 	}
1814 	return gf_list_add(hnti->hints, a);
1815 }
1816 
hnti_Read(GF_Box * s,GF_BitStream * bs)1817 GF_Err hnti_Read(GF_Box *s, GF_BitStream *bs)
1818 {
1819 	u32 type;
1820 	u32 length;
1821 	GF_Err e;
1822 	GF_Box *a;
1823 	GF_RTPBox *rtp;
1824 
1825 	GF_HintTrackInfoBox *ptr = (GF_HintTrackInfoBox *)s;
1826 	if (ptr == NULL) return GF_BAD_PARAM;
1827 
1828 	//WARNING: because of the HNTI at movie level, we cannot use the generic parsing scheme!
1829 	//this because the child SDP box at the movie level has a type of RTP, used for
1830 	//the HintSampleEntry !
1831 	while (ptr->size) {
1832 		//get the type of the box (4 bytes after our current position in the bitstream)
1833 		//before parsing...
1834 		type = gf_bs_peek_bits(bs, 32, 4);
1835 		if (type != GF_ISOM_BOX_TYPE_RTP) {
1836 			e = gf_isom_parse_box(&a, bs);
1837 			if (e) return e;
1838 			e = hnti_AddBox(ptr, a);
1839 			if (e) return e;
1840 			if (ptr->size<a->size) return GF_ISOM_INVALID_FILE;
1841 			ptr->size -= a->size;
1842 		}
1843 		else {
1844 			u32 sr;
1845 			rtp = (GF_RTPBox*)gf_malloc(sizeof(GF_RTPBox));
1846 			if (!rtp) return GF_OUT_OF_MEM;
1847 			rtp->size = gf_bs_read_u32(bs);
1848 			rtp->type = gf_bs_read_u32(bs);
1849 			sr = 8;
1850 			//"ITS LENGTH IS CALCULATED BY SUBSTRACTING 8 (or 12) from the box size" - QT specs
1851 			//this means that we don't have any NULL char as a delimiter in QT ...
1852 			if (rtp->size == 1) return GF_BAD_PARAM;
1853 			rtp->subType = gf_bs_read_u32(bs);
1854 			sr += 4;
1855 			if (rtp->subType != GF_ISOM_BOX_TYPE_SDP) return GF_NOT_SUPPORTED;
1856 			if (rtp->size < sr) return GF_ISOM_INVALID_FILE;
1857 			length = (u32)(rtp->size - sr);
1858 			rtp->sdpText = (char*)gf_malloc(sizeof(char) * (length + 1));
1859 			if (!rtp->sdpText) {
1860 				gf_free(rtp);
1861 				return GF_OUT_OF_MEM;
1862 			}
1863 			gf_bs_read_data(bs, rtp->sdpText, length);
1864 			rtp->sdpText[length] = 0;
1865 			//			sr += length;
1866 			e = hnti_AddBox(ptr, (GF_Box *)rtp);
1867 			if (e) return e;
1868 			if (ptr->size<rtp->size) return GF_ISOM_INVALID_FILE;
1869 			ptr->size -= rtp->size;
1870 		}
1871 	}
1872 	return GF_OK;
1873 }
1874 
1875 #ifndef GPAC_DISABLE_ISOM_WRITE
hnti_Write(GF_Box * s,GF_BitStream * bs)1876 GF_Err hnti_Write(GF_Box *s, GF_BitStream *bs)
1877 {
1878 	GF_Err e;
1879 	u32 i, count;
1880 	GF_Box *a;
1881 	GF_RTPBox *rtp;
1882 
1883 	GF_HintTrackInfoBox *ptr = (GF_HintTrackInfoBox *)s;
1884 	if (ptr == NULL) return GF_BAD_PARAM;
1885 
1886 	e = gf_isom_box_write_header(s, bs);
1887 	if (e) return e;
1888 
1889 	count = gf_list_count(ptr->hints);
1890 	for (i = 0; i < count; i++) {
1891 		a = (GF_Box*)gf_list_get(ptr->hints, i);
1892 		if (a->type != GF_ISOM_BOX_TYPE_RTP) {
1893 			e = gf_isom_box_write(a, bs);
1894 			if (e) return e;
1895 		}
1896 		else {
1897 			//write the GF_RTPBox by hand
1898 			rtp = (GF_RTPBox *)a;
1899 			e = gf_isom_box_write_header(a, bs);
1900 			if (e) return e;
1901 			gf_bs_write_u32(bs, rtp->subType);
1902 			//don't write the NULL char
1903 			gf_bs_write_data(bs, rtp->sdpText, (u32)strlen(rtp->sdpText));
1904 		}
1905 	}
1906 	return GF_OK;
1907 }
1908 
1909 
hnti_Size(GF_Box * s)1910 GF_Err hnti_Size(GF_Box *s)
1911 {
1912 	GF_Err e;
1913 	u32 i, count;
1914 	GF_Box *a;
1915 	GF_RTPBox *rtp;
1916 
1917 	GF_HintTrackInfoBox *ptr = (GF_HintTrackInfoBox *)s;
1918 	if (ptr == NULL) return GF_BAD_PARAM;
1919 
1920 	e = gf_isom_box_get_size(s);
1921 	if (e) return e;
1922 
1923 	count = gf_list_count(ptr->hints);
1924 	for (i = 0; i < count; i++) {
1925 		a = (GF_Box*)gf_list_get(ptr->hints, i);
1926 		if (a->type != GF_ISOM_BOX_TYPE_RTP) {
1927 			e = gf_isom_box_size(a);
1928 			if (e) return e;
1929 		}
1930 		else {
1931 			//get the GF_RTPBox size by hand
1932 			rtp = (GF_RTPBox *)a;
1933 			e = gf_isom_box_get_size(a);
1934 			if (e) return e;
1935 			//don't count the NULL char...
1936 			rtp->size += 4 + strlen(rtp->sdpText);
1937 		}
1938 		ptr->size += a->size;
1939 	}
1940 	return GF_OK;
1941 }
1942 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1943 
1944 /**********************************************************
1945 GF_SDPBox
1946 **********************************************************/
1947 
sdp_del(GF_Box * s)1948 void sdp_del(GF_Box *s)
1949 {
1950 	GF_SDPBox *ptr = (GF_SDPBox *)s;
1951 	if (ptr->sdpText) gf_free(ptr->sdpText);
1952 	gf_free(ptr);
1953 
1954 }
sdp_Read(GF_Box * s,GF_BitStream * bs)1955 GF_Err sdp_Read(GF_Box *s, GF_BitStream *bs)
1956 {
1957 	u32 length;
1958 	GF_SDPBox *ptr = (GF_SDPBox *)s;
1959 	if (ptr == NULL) return GF_BAD_PARAM;
1960 
1961 	length = (u32)(ptr->size);
1962 	//sdp text has no delimiter !!!
1963 	ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length + 1));
1964 	if (!ptr->sdpText) return GF_OUT_OF_MEM;
1965 
1966 	gf_bs_read_data(bs, ptr->sdpText, length);
1967 	ptr->sdpText[length] = 0;
1968 	return GF_OK;
1969 }
sdp_New()1970 GF_Box *sdp_New()
1971 {
1972 	ISOM_DECL_BOX_ALLOC(GF_SDPBox, GF_ISOM_BOX_TYPE_SDP);
1973 	return (GF_Box *)tmp;
1974 }
1975 #ifndef GPAC_DISABLE_ISOM_WRITE
sdp_Write(GF_Box * s,GF_BitStream * bs)1976 GF_Err sdp_Write(GF_Box *s, GF_BitStream *bs)
1977 {
1978 	GF_Err e;
1979 	GF_SDPBox *ptr = (GF_SDPBox *)s;
1980 	if (ptr == NULL) return GF_BAD_PARAM;
1981 	e = gf_isom_box_write_header(s, bs);
1982 	if (e) return e;
1983 	//don't write the NULL char!!!
1984 	gf_bs_write_data(bs, ptr->sdpText, (u32)strlen(ptr->sdpText));
1985 	return GF_OK;
1986 }
sdp_Size(GF_Box * s)1987 GF_Err sdp_Size(GF_Box *s)
1988 {
1989 	GF_Err e;
1990 	GF_SDPBox *ptr = (GF_SDPBox *)s;
1991 	e = gf_isom_box_get_size(s);
1992 	if (e) return e;
1993 	//don't count the NULL char!!!
1994 	ptr->size += strlen(ptr->sdpText);
1995 	return GF_OK;
1996 }
1997 
1998 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1999 
2000 
2001 /**********************************************************
2002 TRPY GF_Box
2003 **********************************************************/
2004 
trpy_del(GF_Box * s)2005 void trpy_del(GF_Box *s)
2006 {
2007 	gf_free((GF_TRPYBox *)s);
2008 }
trpy_Read(GF_Box * s,GF_BitStream * bs)2009 GF_Err trpy_Read(GF_Box *s, GF_BitStream *bs)
2010 {
2011 	GF_TRPYBox *ptr = (GF_TRPYBox *)s;
2012 	ptr->nbBytes = gf_bs_read_u64(bs);
2013 	return GF_OK;
2014 }
trpy_New()2015 GF_Box *trpy_New()
2016 {
2017 	ISOM_DECL_BOX_ALLOC(GF_TRPYBox, GF_ISOM_BOX_TYPE_TRPY);
2018 	return (GF_Box *)tmp;
2019 }
2020 #ifndef GPAC_DISABLE_ISOM_WRITE
2021 
trpy_Write(GF_Box * s,GF_BitStream * bs)2022 GF_Err trpy_Write(GF_Box *s, GF_BitStream *bs)
2023 {
2024 	GF_Err e;
2025 	GF_TRPYBox *ptr = (GF_TRPYBox *)s;
2026 	if (ptr == NULL) return GF_BAD_PARAM;
2027 
2028 	e = gf_isom_box_write_header(s, bs);
2029 	if (e) return e;
2030 	gf_bs_write_u64(bs, ptr->nbBytes);
2031 	return GF_OK;
2032 }
trpy_Size(GF_Box * s)2033 GF_Err trpy_Size(GF_Box *s)
2034 {
2035 	GF_Err e;
2036 	e = gf_isom_box_get_size(s);
2037 	if (e) return e;
2038 	s->size += 8;
2039 	return GF_OK;
2040 }
2041 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2042 
2043 /**********************************************************
2044 TOTL GF_Box
2045 **********************************************************/
2046 
totl_del(GF_Box * s)2047 void totl_del(GF_Box *s)
2048 {
2049 	gf_free((GF_TRPYBox *)s);
2050 }
totl_Read(GF_Box * s,GF_BitStream * bs)2051 GF_Err totl_Read(GF_Box *s, GF_BitStream *bs)
2052 {
2053 	GF_TOTLBox *ptr = (GF_TOTLBox *)s;
2054 	ptr->nbBytes = gf_bs_read_u32(bs);
2055 	return GF_OK;
2056 }
totl_New()2057 GF_Box *totl_New()
2058 {
2059 	ISOM_DECL_BOX_ALLOC(GF_TOTLBox, GF_ISOM_BOX_TYPE_TOTL);
2060 	return (GF_Box *)tmp;
2061 }
2062 
2063 #ifndef GPAC_DISABLE_ISOM_WRITE
2064 
totl_Write(GF_Box * s,GF_BitStream * bs)2065 GF_Err totl_Write(GF_Box *s, GF_BitStream *bs)
2066 {
2067 	GF_Err e;
2068 	GF_TOTLBox *ptr = (GF_TOTLBox *)s;
2069 	if (ptr == NULL) return GF_BAD_PARAM;
2070 	e = gf_isom_box_write_header(s, bs);
2071 	if (e) return e;
2072 	gf_bs_write_u32(bs, ptr->nbBytes);
2073 	return GF_OK;
2074 }
totl_Size(GF_Box * s)2075 GF_Err totl_Size(GF_Box *s)
2076 {
2077 	GF_Err e;
2078 	e = gf_isom_box_get_size(s);
2079 	if (e) return e;
2080 	s->size += 4;
2081 	return GF_OK;
2082 }
2083 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2084 
2085 
2086 /**********************************************************
2087 NUMP GF_Box
2088 **********************************************************/
2089 
nump_del(GF_Box * s)2090 void nump_del(GF_Box *s)
2091 {
2092 	gf_free((GF_NUMPBox *)s);
2093 }
nump_Read(GF_Box * s,GF_BitStream * bs)2094 GF_Err nump_Read(GF_Box *s, GF_BitStream *bs)
2095 {
2096 	GF_NUMPBox *ptr = (GF_NUMPBox *)s;
2097 	ptr->nbPackets = gf_bs_read_u64(bs);
2098 	return GF_OK;
2099 }
nump_New()2100 GF_Box *nump_New()
2101 {
2102 	ISOM_DECL_BOX_ALLOC(GF_NUMPBox, GF_ISOM_BOX_TYPE_NUMP);
2103 	return (GF_Box *)tmp;
2104 }
2105 
2106 #ifndef GPAC_DISABLE_ISOM_WRITE
nump_Write(GF_Box * s,GF_BitStream * bs)2107 GF_Err nump_Write(GF_Box *s, GF_BitStream *bs)
2108 {
2109 	GF_Err e;
2110 	GF_NUMPBox *ptr = (GF_NUMPBox *)s;
2111 	if (ptr == NULL) return GF_BAD_PARAM;
2112 	e = gf_isom_box_write_header(s, bs);
2113 	if (e) return e;
2114 	gf_bs_write_u64(bs, ptr->nbPackets);
2115 	return GF_OK;
2116 }
nump_Size(GF_Box * s)2117 GF_Err nump_Size(GF_Box *s)
2118 {
2119 	GF_Err e;
2120 	e = gf_isom_box_get_size(s);
2121 	if (e) return e;
2122 	s->size += 8;
2123 	return GF_OK;
2124 }
2125 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2126 
2127 
2128 /**********************************************************
2129 NPCK GF_Box
2130 **********************************************************/
2131 
npck_del(GF_Box * s)2132 void npck_del(GF_Box *s)
2133 {
2134 	gf_free((GF_NPCKBox *)s);
2135 }
npck_Read(GF_Box * s,GF_BitStream * bs)2136 GF_Err npck_Read(GF_Box *s, GF_BitStream *bs)
2137 {
2138 	GF_NPCKBox *ptr = (GF_NPCKBox *)s;
2139 	ptr->nbPackets = gf_bs_read_u32(bs);
2140 	return GF_OK;
2141 }
npck_New()2142 GF_Box *npck_New()
2143 {
2144 	ISOM_DECL_BOX_ALLOC(GF_NPCKBox, GF_ISOM_BOX_TYPE_NPCK);
2145 	return (GF_Box *)tmp;
2146 }
2147 #ifndef GPAC_DISABLE_ISOM_WRITE
npck_Write(GF_Box * s,GF_BitStream * bs)2148 GF_Err npck_Write(GF_Box *s, GF_BitStream *bs)
2149 {
2150 	GF_Err e;
2151 	GF_NPCKBox *ptr = (GF_NPCKBox *)s;
2152 	if (ptr == NULL) return GF_BAD_PARAM;
2153 	e = gf_isom_box_write_header(s, bs);
2154 	if (e) return e;
2155 	gf_bs_write_u32(bs, ptr->nbPackets);
2156 	return GF_OK;
2157 }
npck_Size(GF_Box * s)2158 GF_Err npck_Size(GF_Box *s)
2159 {
2160 	GF_Err e;
2161 	e = gf_isom_box_get_size(s);
2162 	if (e) return e;
2163 	s->size += 4;
2164 	return GF_OK;
2165 }
2166 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2167 
2168 
2169 /**********************************************************
2170 TPYL GF_Box
2171 **********************************************************/
2172 
tpyl_del(GF_Box * s)2173 void tpyl_del(GF_Box *s)
2174 {
2175 	gf_free((GF_NTYLBox *)s);
2176 }
tpyl_Read(GF_Box * s,GF_BitStream * bs)2177 GF_Err tpyl_Read(GF_Box *s, GF_BitStream *bs)
2178 {
2179 	GF_NTYLBox *ptr = (GF_NTYLBox *)s;
2180 	if (ptr == NULL) return GF_BAD_PARAM;
2181 	ptr->nbBytes = gf_bs_read_u64(bs);
2182 	return GF_OK;
2183 }
tpyl_New()2184 GF_Box *tpyl_New()
2185 {
2186 	ISOM_DECL_BOX_ALLOC(GF_NTYLBox, GF_ISOM_BOX_TYPE_TPYL);
2187 	return (GF_Box *)tmp;
2188 }
2189 #ifndef GPAC_DISABLE_ISOM_WRITE
tpyl_Write(GF_Box * s,GF_BitStream * bs)2190 GF_Err tpyl_Write(GF_Box *s, GF_BitStream *bs)
2191 {
2192 	GF_Err e;
2193 	GF_NTYLBox *ptr = (GF_NTYLBox *)s;
2194 	if (ptr == NULL) return GF_BAD_PARAM;
2195 	e = gf_isom_box_write_header(s, bs);
2196 	if (e) return e;
2197 	gf_bs_write_u64(bs, ptr->nbBytes);
2198 	return GF_OK;
2199 }
tpyl_Size(GF_Box * s)2200 GF_Err tpyl_Size(GF_Box *s)
2201 {
2202 	GF_Err e;
2203 	e = gf_isom_box_get_size(s);
2204 	if (e) return e;
2205 	s->size += 8;
2206 	return GF_OK;
2207 }
2208 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2209 
2210 /**********************************************************
2211 TPAY GF_Box
2212 **********************************************************/
2213 
tpay_del(GF_Box * s)2214 void tpay_del(GF_Box *s)
2215 {
2216 	gf_free((GF_TPAYBox *)s);
2217 }
tpay_Read(GF_Box * s,GF_BitStream * bs)2218 GF_Err tpay_Read(GF_Box *s, GF_BitStream *bs)
2219 {
2220 	GF_TPAYBox *ptr = (GF_TPAYBox *)s;
2221 	ptr->nbBytes = gf_bs_read_u32(bs);
2222 	return GF_OK;
2223 }
tpay_New()2224 GF_Box *tpay_New()
2225 {
2226 	ISOM_DECL_BOX_ALLOC(GF_TPAYBox, GF_ISOM_BOX_TYPE_TPAY);
2227 	return (GF_Box *)tmp;
2228 }
2229 #ifndef GPAC_DISABLE_ISOM_WRITE
tpay_Write(GF_Box * s,GF_BitStream * bs)2230 GF_Err tpay_Write(GF_Box *s, GF_BitStream *bs)
2231 {
2232 	GF_Err e;
2233 	GF_TPAYBox *ptr = (GF_TPAYBox *)s;
2234 	if (ptr == NULL) return GF_BAD_PARAM;
2235 	e = gf_isom_box_write_header(s, bs);
2236 	if (e) return e;
2237 	gf_bs_write_u32(bs, ptr->nbBytes);
2238 	return GF_OK;
2239 }
tpay_Size(GF_Box * s)2240 GF_Err tpay_Size(GF_Box *s)
2241 {
2242 	GF_Err e;
2243 	e = gf_isom_box_get_size(s);
2244 	if (e) return e;
2245 	s->size += 4;
2246 	return GF_OK;
2247 }
2248 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2249 
2250 
2251 /**********************************************************
2252 MAXR GF_Box
2253 **********************************************************/
2254 
maxr_del(GF_Box * s)2255 void maxr_del(GF_Box *s)
2256 {
2257 	gf_free((GF_MAXRBox *)s);
2258 }
maxr_Read(GF_Box * s,GF_BitStream * bs)2259 GF_Err maxr_Read(GF_Box *s, GF_BitStream *bs)
2260 {
2261 	GF_MAXRBox *ptr = (GF_MAXRBox *)s;
2262 	if (ptr == NULL) return GF_BAD_PARAM;
2263 	ptr->granularity = gf_bs_read_u32(bs);
2264 	ptr->maxDataRate = gf_bs_read_u32(bs);
2265 	return GF_OK;
2266 }
maxr_New()2267 GF_Box *maxr_New()
2268 {
2269 	ISOM_DECL_BOX_ALLOC(GF_MAXRBox, GF_ISOM_BOX_TYPE_MAXR);
2270 	return (GF_Box *)tmp;
2271 }
2272 #ifndef GPAC_DISABLE_ISOM_WRITE
maxr_Write(GF_Box * s,GF_BitStream * bs)2273 GF_Err maxr_Write(GF_Box *s, GF_BitStream *bs)
2274 {
2275 	GF_Err e;
2276 	GF_MAXRBox *ptr = (GF_MAXRBox *)s;
2277 	if (ptr == NULL) return GF_BAD_PARAM;
2278 	e = gf_isom_box_write_header(s, bs);
2279 	if (e) return e;
2280 	gf_bs_write_u32(bs, ptr->granularity);
2281 	gf_bs_write_u32(bs, ptr->maxDataRate);
2282 	return GF_OK;
2283 }
maxr_Size(GF_Box * s)2284 GF_Err maxr_Size(GF_Box *s)
2285 {
2286 	GF_Err e;
2287 	e = gf_isom_box_get_size(s);
2288 	if (e) return e;
2289 	s->size += 8;
2290 	return GF_OK;
2291 }
2292 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2293 
2294 
2295 /**********************************************************
2296 DMED GF_Box
2297 **********************************************************/
2298 
dmed_del(GF_Box * s)2299 void dmed_del(GF_Box *s)
2300 {
2301 	gf_free((GF_DMEDBox *)s);
2302 }
dmed_Read(GF_Box * s,GF_BitStream * bs)2303 GF_Err dmed_Read(GF_Box *s, GF_BitStream *bs)
2304 {
2305 	GF_DMEDBox *ptr = (GF_DMEDBox *)s;
2306 	ptr->nbBytes = gf_bs_read_u64(bs);
2307 	return GF_OK;
2308 }
dmed_New()2309 GF_Box *dmed_New()
2310 {
2311 	ISOM_DECL_BOX_ALLOC(GF_DMEDBox, GF_ISOM_BOX_TYPE_DMED);
2312 	return (GF_Box *)tmp;
2313 }
2314 #ifndef GPAC_DISABLE_ISOM_WRITE
dmed_Write(GF_Box * s,GF_BitStream * bs)2315 GF_Err dmed_Write(GF_Box *s, GF_BitStream *bs)
2316 {
2317 	GF_Err e;
2318 	GF_DMEDBox *ptr = (GF_DMEDBox *)s;
2319 	if (ptr == NULL) return GF_BAD_PARAM;
2320 	e = gf_isom_box_write_header(s, bs);
2321 	if (e) return e;
2322 	gf_bs_write_u64(bs, ptr->nbBytes);
2323 	return GF_OK;
2324 }
dmed_Size(GF_Box * s)2325 GF_Err dmed_Size(GF_Box *s)
2326 {
2327 	GF_Err e;
2328 	e = gf_isom_box_get_size(s);
2329 	if (e) return e;
2330 	s->size += 8;
2331 	return GF_OK;
2332 }
2333 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2334 
2335 /**********************************************************
2336 DIMM GF_Box
2337 **********************************************************/
2338 
dimm_del(GF_Box * s)2339 void dimm_del(GF_Box *s)
2340 {
2341 	gf_free((GF_DIMMBox *)s);
2342 }
dimm_Read(GF_Box * s,GF_BitStream * bs)2343 GF_Err dimm_Read(GF_Box *s, GF_BitStream *bs)
2344 {
2345 	GF_DIMMBox *ptr = (GF_DIMMBox *)s;
2346 	ptr->nbBytes = gf_bs_read_u64(bs);
2347 	return GF_OK;
2348 }
dimm_New()2349 GF_Box *dimm_New()
2350 {
2351 	ISOM_DECL_BOX_ALLOC(GF_DIMMBox, GF_ISOM_BOX_TYPE_DIMM);
2352 	return (GF_Box *)tmp;
2353 }
2354 #ifndef GPAC_DISABLE_ISOM_WRITE
dimm_Write(GF_Box * s,GF_BitStream * bs)2355 GF_Err dimm_Write(GF_Box *s, GF_BitStream *bs)
2356 {
2357 	GF_Err e;
2358 	GF_DIMMBox *ptr = (GF_DIMMBox *)s;
2359 	if (ptr == NULL) return GF_BAD_PARAM;
2360 	e = gf_isom_box_write_header(s, bs);
2361 	if (e) return e;
2362 	gf_bs_write_u64(bs, ptr->nbBytes);
2363 	return GF_OK;
2364 }
dimm_Size(GF_Box * s)2365 GF_Err dimm_Size(GF_Box *s)
2366 {
2367 	GF_Err e;
2368 	e = gf_isom_box_get_size(s);
2369 	if (e) return e;
2370 	s->size += 8;
2371 	return GF_OK;
2372 }
2373 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2374 
2375 /**********************************************************
2376 DREP GF_Box
2377 **********************************************************/
2378 
drep_del(GF_Box * s)2379 void drep_del(GF_Box *s)
2380 {
2381 	gf_free((GF_DREPBox *)s);
2382 }
drep_Read(GF_Box * s,GF_BitStream * bs)2383 GF_Err drep_Read(GF_Box *s, GF_BitStream *bs)
2384 {
2385 	GF_DREPBox *ptr = (GF_DREPBox *)s;
2386 	ptr->nbBytes = gf_bs_read_u64(bs);
2387 	return GF_OK;
2388 }
drep_New()2389 GF_Box *drep_New()
2390 {
2391 	ISOM_DECL_BOX_ALLOC(GF_DREPBox, GF_ISOM_BOX_TYPE_DREP);
2392 	return (GF_Box *)tmp;
2393 }
2394 #ifndef GPAC_DISABLE_ISOM_WRITE
drep_Write(GF_Box * s,GF_BitStream * bs)2395 GF_Err drep_Write(GF_Box *s, GF_BitStream *bs)
2396 {
2397 	GF_Err e;
2398 	GF_DREPBox *ptr = (GF_DREPBox *)s;
2399 	if (ptr == NULL) return GF_BAD_PARAM;
2400 	e = gf_isom_box_write_header(s, bs);
2401 	if (e) return e;
2402 	gf_bs_write_u64(bs, ptr->nbBytes);
2403 	return GF_OK;
2404 }
drep_Size(GF_Box * s)2405 GF_Err drep_Size(GF_Box *s)
2406 {
2407 	GF_Err e;
2408 	e = gf_isom_box_get_size(s);
2409 	if (e) return e;
2410 	s->size += 8;
2411 	return GF_OK;
2412 }
2413 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2414 
2415 
2416 
2417 /**********************************************************
2418 TMIN GF_Box
2419 **********************************************************/
2420 
tmin_del(GF_Box * s)2421 void tmin_del(GF_Box *s)
2422 {
2423 	gf_free((GF_TMINBox *)s);
2424 }
tmin_Read(GF_Box * s,GF_BitStream * bs)2425 GF_Err tmin_Read(GF_Box *s, GF_BitStream *bs)
2426 {
2427 	GF_TMINBox *ptr = (GF_TMINBox *)s;
2428 	ptr->minTime = gf_bs_read_u32(bs);
2429 	return GF_OK;
2430 }
tmin_New()2431 GF_Box *tmin_New()
2432 {
2433 	ISOM_DECL_BOX_ALLOC(GF_TMINBox, GF_ISOM_BOX_TYPE_TMIN);
2434 	return (GF_Box *)tmp;
2435 }
2436 #ifndef GPAC_DISABLE_ISOM_WRITE
tmin_Write(GF_Box * s,GF_BitStream * bs)2437 GF_Err tmin_Write(GF_Box *s, GF_BitStream *bs)
2438 {
2439 	GF_Err e;
2440 	GF_TMINBox *ptr = (GF_TMINBox *)s;
2441 	if (ptr == NULL) return GF_BAD_PARAM;
2442 	e = gf_isom_box_write_header(s, bs);
2443 	if (e) return e;
2444 	gf_bs_write_u32(bs, ptr->minTime);
2445 	return GF_OK;
2446 }
tmin_Size(GF_Box * s)2447 GF_Err tmin_Size(GF_Box *s)
2448 {
2449 	GF_Err e;
2450 	e = gf_isom_box_get_size(s);
2451 	if (e) return e;
2452 	s->size += 4;
2453 	return GF_OK;
2454 }
2455 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2456 
2457 
2458 /**********************************************************
2459 TMAX GF_Box
2460 **********************************************************/
2461 
tmax_del(GF_Box * s)2462 void tmax_del(GF_Box *s)
2463 {
2464 	gf_free((GF_TMAXBox *)s);
2465 }
tmax_Read(GF_Box * s,GF_BitStream * bs)2466 GF_Err tmax_Read(GF_Box *s, GF_BitStream *bs)
2467 {
2468 	GF_TMAXBox *ptr = (GF_TMAXBox *)s;
2469 	ptr->maxTime = gf_bs_read_u32(bs);
2470 	return GF_OK;
2471 }
tmax_New()2472 GF_Box *tmax_New()
2473 {
2474 	ISOM_DECL_BOX_ALLOC(GF_TMAXBox, GF_ISOM_BOX_TYPE_TMAX);
2475 	return (GF_Box *)tmp;
2476 }
2477 #ifndef GPAC_DISABLE_ISOM_WRITE
tmax_Write(GF_Box * s,GF_BitStream * bs)2478 GF_Err tmax_Write(GF_Box *s, GF_BitStream *bs)
2479 {
2480 	GF_Err e;
2481 	GF_TMAXBox *ptr = (GF_TMAXBox *)s;
2482 	if (ptr == NULL) return GF_BAD_PARAM;
2483 	e = gf_isom_box_write_header(s, bs);
2484 	if (e) return e;
2485 	gf_bs_write_u32(bs, ptr->maxTime);
2486 	return GF_OK;
2487 }
tmax_Size(GF_Box * s)2488 GF_Err tmax_Size(GF_Box *s)
2489 {
2490 	GF_Err e;
2491 	e = gf_isom_box_get_size(s);
2492 	if (e) return e;
2493 	s->size += 4;
2494 	return GF_OK;
2495 }
2496 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2497 
2498 
2499 /**********************************************************
2500 PMAX GF_Box
2501 **********************************************************/
2502 
pmax_del(GF_Box * s)2503 void pmax_del(GF_Box *s)
2504 {
2505 	gf_free((GF_PMAXBox *)s);
2506 }
pmax_Read(GF_Box * s,GF_BitStream * bs)2507 GF_Err pmax_Read(GF_Box *s, GF_BitStream *bs)
2508 {
2509 	GF_PMAXBox *ptr = (GF_PMAXBox *)s;
2510 	ptr->maxSize = gf_bs_read_u32(bs);
2511 	return GF_OK;
2512 }
pmax_New()2513 GF_Box *pmax_New()
2514 {
2515 	ISOM_DECL_BOX_ALLOC(GF_PMAXBox, GF_ISOM_BOX_TYPE_PMAX);
2516 	return (GF_Box *)tmp;
2517 }
2518 #ifndef GPAC_DISABLE_ISOM_WRITE
pmax_Write(GF_Box * s,GF_BitStream * bs)2519 GF_Err pmax_Write(GF_Box *s, GF_BitStream *bs)
2520 {
2521 	GF_Err e;
2522 	GF_PMAXBox *ptr = (GF_PMAXBox *)s;
2523 	if (ptr == NULL) return GF_BAD_PARAM;
2524 	e = gf_isom_box_write_header(s, bs);
2525 	if (e) return e;
2526 	gf_bs_write_u32(bs, ptr->maxSize);
2527 	return GF_OK;
2528 }
pmax_Size(GF_Box * s)2529 GF_Err pmax_Size(GF_Box *s)
2530 {
2531 	GF_Err e;
2532 	e = gf_isom_box_get_size(s);
2533 	if (e) return e;
2534 	s->size += 4;
2535 	return GF_OK;
2536 }
2537 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2538 
2539 
2540 /**********************************************************
2541 DMAX GF_Box
2542 **********************************************************/
2543 
dmax_del(GF_Box * s)2544 void dmax_del(GF_Box *s)
2545 {
2546 	gf_free((GF_DMAXBox *)s);
2547 }
dmax_Read(GF_Box * s,GF_BitStream * bs)2548 GF_Err dmax_Read(GF_Box *s, GF_BitStream *bs)
2549 {
2550 	GF_DMAXBox *ptr = (GF_DMAXBox *)s;
2551 	ptr->maxDur = gf_bs_read_u32(bs);
2552 	return GF_OK;
2553 }
dmax_New()2554 GF_Box *dmax_New()
2555 {
2556 	ISOM_DECL_BOX_ALLOC(GF_DMAXBox, GF_ISOM_BOX_TYPE_DMAX);
2557 	return (GF_Box *)tmp;
2558 }
2559 #ifndef GPAC_DISABLE_ISOM_WRITE
dmax_Write(GF_Box * s,GF_BitStream * bs)2560 GF_Err dmax_Write(GF_Box *s, GF_BitStream *bs)
2561 {
2562 	GF_Err e;
2563 	GF_DMAXBox *ptr = (GF_DMAXBox *)s;
2564 	if (ptr == NULL) return GF_BAD_PARAM;
2565 	e = gf_isom_box_write_header(s, bs);
2566 	if (e) return e;
2567 	gf_bs_write_u32(bs, ptr->maxDur);
2568 	return GF_OK;
2569 }
dmax_Size(GF_Box * s)2570 GF_Err dmax_Size(GF_Box *s)
2571 {
2572 	GF_Err e;
2573 	e = gf_isom_box_get_size(s);
2574 	if (e) return e;
2575 	s->size += 4;
2576 	return GF_OK;
2577 }
2578 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2579 
2580 
2581 /**********************************************************
2582 PAYT GF_Box
2583 **********************************************************/
2584 
payt_del(GF_Box * s)2585 void payt_del(GF_Box *s)
2586 {
2587 	GF_PAYTBox *payt = (GF_PAYTBox *)s;
2588 	if (payt->payloadString) gf_free(payt->payloadString);
2589 	gf_free(payt);
2590 }
payt_Read(GF_Box * s,GF_BitStream * bs)2591 GF_Err payt_Read(GF_Box *s, GF_BitStream *bs)
2592 {
2593 	u32 length;
2594 	GF_PAYTBox *ptr = (GF_PAYTBox *)s;
2595 
2596 	ptr->payloadCode = gf_bs_read_u32(bs);
2597 	length = gf_bs_read_u8(bs);
2598 	ptr->payloadString = (char*)gf_malloc(sizeof(char) * (length + 1));
2599 	if (!ptr->payloadString) return GF_OUT_OF_MEM;
2600 	gf_bs_read_data(bs, ptr->payloadString, length);
2601 	ptr->payloadString[length] = 0;
2602 	ptr->size -= 4 + length + 1;
2603 	return GF_OK;
2604 }
payt_New()2605 GF_Box *payt_New()
2606 {
2607 	ISOM_DECL_BOX_ALLOC(GF_PAYTBox, GF_ISOM_BOX_TYPE_PAYT);
2608 	return (GF_Box *)tmp;
2609 }
2610 #ifndef GPAC_DISABLE_ISOM_WRITE
payt_Write(GF_Box * s,GF_BitStream * bs)2611 GF_Err payt_Write(GF_Box *s, GF_BitStream *bs)
2612 {
2613 	u32 len;
2614 	GF_Err e;
2615 	GF_PAYTBox *ptr = (GF_PAYTBox *)s;
2616 	if (ptr == NULL) return GF_BAD_PARAM;
2617 	e = gf_isom_box_write_header(s, bs);
2618 	if (e) return e;
2619 	gf_bs_write_u32(bs, ptr->payloadCode);
2620 	len = (u32)strlen(ptr->payloadString);
2621 	gf_bs_write_u8(bs, len);
2622 	if (len) gf_bs_write_data(bs, ptr->payloadString, len);
2623 	return GF_OK;
2624 }
payt_Size(GF_Box * s)2625 GF_Err payt_Size(GF_Box *s)
2626 {
2627 	GF_Err e;
2628 	GF_PAYTBox *ptr = (GF_PAYTBox *)s;
2629 	e = gf_isom_box_get_size(s);
2630 	if (e) return e;
2631 	s->size += 4;
2632 	if (ptr->payloadString) ptr->size += strlen(ptr->payloadString) + 1;
2633 	return GF_OK;
2634 }
2635 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2636 
2637 
2638 /**********************************************************
2639 PAYT GF_Box
2640 **********************************************************/
2641 
name_del(GF_Box * s)2642 void name_del(GF_Box *s)
2643 {
2644 	GF_NameBox *name = (GF_NameBox *)s;
2645 	if (name->string) gf_free(name->string);
2646 	gf_free(name);
2647 }
name_Read(GF_Box * s,GF_BitStream * bs)2648 GF_Err name_Read(GF_Box *s, GF_BitStream *bs)
2649 {
2650 	u32 length;
2651 	GF_NameBox *ptr = (GF_NameBox *)s;
2652 
2653 	length = (u32)(ptr->size);
2654 	ptr->string = (char*)gf_malloc(sizeof(char) * length);
2655 	if (!ptr->string) return GF_OUT_OF_MEM;
2656 
2657 	gf_bs_read_data(bs, ptr->string, length);
2658 	return GF_OK;
2659 }
name_New()2660 GF_Box *name_New()
2661 {
2662 	ISOM_DECL_BOX_ALLOC(GF_NameBox, GF_ISOM_BOX_TYPE_NAME);
2663 	return (GF_Box *)tmp;
2664 }
2665 #ifndef GPAC_DISABLE_ISOM_WRITE
name_Write(GF_Box * s,GF_BitStream * bs)2666 GF_Err name_Write(GF_Box *s, GF_BitStream *bs)
2667 {
2668 	GF_Err e;
2669 	GF_NameBox *ptr = (GF_NameBox *)s;
2670 	if (ptr == NULL) return GF_BAD_PARAM;
2671 	e = gf_isom_box_write_header(s, bs);
2672 	if (e) return e;
2673 	if (ptr->string) {
2674 		gf_bs_write_data(bs, ptr->string, (u32)strlen(ptr->string) + 1);
2675 	}
2676 	return GF_OK;
2677 }
name_Size(GF_Box * s)2678 GF_Err name_Size(GF_Box *s)
2679 {
2680 	GF_Err e;
2681 	GF_NameBox *ptr = (GF_NameBox *)s;
2682 	e = gf_isom_box_get_size(s);
2683 	if (e) return e;
2684 	if (ptr->string) ptr->size += strlen(ptr->string) + 1;
2685 	return GF_OK;
2686 }
2687 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2688 
iods_del(GF_Box * s)2689 void iods_del(GF_Box *s)
2690 {
2691 	GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
2692 	if (ptr == NULL) return;
2693 	if (ptr->descriptor) gf_odf_desc_del(ptr->descriptor);
2694 	gf_free(ptr);
2695 }
2696 
2697 
iods_Read(GF_Box * s,GF_BitStream * bs)2698 GF_Err iods_Read(GF_Box *s, GF_BitStream *bs)
2699 {
2700 	GF_Err e;
2701 	u32 descSize;
2702 	char *desc;
2703 	GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
2704 
2705 	e = gf_isom_full_box_read(s, bs);
2706 	if (e) return e;
2707 	//use the OD codec...
2708 	descSize = (u32)(ptr->size);
2709 	desc = (char*)gf_malloc(sizeof(char) * descSize);
2710 	gf_bs_read_data(bs, desc, descSize);
2711 	e = gf_odf_desc_read(desc, descSize, &ptr->descriptor);
2712 	//OK, free our desc
2713 	gf_free(desc);
2714 	return e;
2715 }
2716 
iods_New()2717 GF_Box *iods_New()
2718 {
2719 	ISOM_DECL_BOX_ALLOC(GF_ObjectDescriptorBox, GF_ISOM_BOX_TYPE_IODS);
2720 	gf_isom_full_box_init((GF_Box *)tmp);
2721 	return (GF_Box *)tmp;
2722 }
2723 
2724 
2725 
2726 #ifndef GPAC_DISABLE_ISOM_WRITE
2727 
iods_Write(GF_Box * s,GF_BitStream * bs)2728 GF_Err iods_Write(GF_Box *s, GF_BitStream *bs)
2729 {
2730 	GF_Err e;
2731 	u32 descSize;
2732 	char *desc;
2733 	GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
2734 	e = gf_isom_full_box_write(s, bs);
2735 	if (e) return e;
2736 	//call our OD codec
2737 	e = gf_odf_desc_write(ptr->descriptor, &desc, &descSize);
2738 	if (e) return e;
2739 	gf_bs_write_data(bs, desc, descSize);
2740 	//and free our stuff maybe!!
2741 	gf_free(desc);
2742 	return GF_OK;
2743 }
2744 
iods_Size(GF_Box * s)2745 GF_Err iods_Size(GF_Box *s)
2746 {
2747 	GF_Err e;
2748 	GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
2749 	e = gf_isom_full_box_get_size(s);
2750 	if (e) return e;
2751 	ptr->size += gf_odf_desc_size(ptr->descriptor);
2752 	return GF_OK;
2753 }
2754 
2755 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2756 
mdat_del(GF_Box * s)2757 void mdat_del(GF_Box *s)
2758 {
2759 	GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
2760 	if (!s) return;
2761 
2762 	if (ptr->data) gf_free(ptr->data);
2763 	gf_free(ptr);
2764 }
2765 
2766 
mdat_Read(GF_Box * s,GF_BitStream * bs)2767 GF_Err mdat_Read(GF_Box *s, GF_BitStream *bs)
2768 {
2769 	GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
2770 	if (ptr == NULL) return GF_BAD_PARAM;
2771 
2772 	ptr->dataSize = s->size;
2773 	//then skip these bytes
2774 	gf_bs_skip_bytes(bs, ptr->dataSize);
2775 	return GF_OK;
2776 }
2777 
mdat_New()2778 GF_Box *mdat_New()
2779 {
2780 	ISOM_DECL_BOX_ALLOC(GF_MediaDataBox, GF_ISOM_BOX_TYPE_MDAT);
2781 	return (GF_Box *)tmp;
2782 }
2783 
2784 #ifndef GPAC_DISABLE_ISOM_WRITE
2785 
mdat_Write(GF_Box * s,GF_BitStream * bs)2786 GF_Err mdat_Write(GF_Box *s, GF_BitStream *bs)
2787 {
2788 	GF_Err e;
2789 	GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
2790 	e = gf_isom_box_write_header(s, bs);
2791 	if (e) return e;
2792 
2793 	//make sure we have some data ...
2794 	//if not, we handle that independantly (edit files)
2795 	if (ptr->data) {
2796 		gf_bs_write_data(bs, ptr->data, (u32)ptr->dataSize);
2797 	}
2798 	return GF_OK;
2799 }
2800 
mdat_Size(GF_Box * s)2801 GF_Err mdat_Size(GF_Box *s)
2802 {
2803 	GF_Err e;
2804 	GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
2805 	e = gf_isom_box_get_size(s);
2806 	if (e) return e;
2807 
2808 	ptr->size += ptr->dataSize;
2809 	return GF_OK;
2810 }
2811 
2812 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2813 
mdhd_del(GF_Box * s)2814 void mdhd_del(GF_Box *s)
2815 {
2816 	GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
2817 	if (ptr == NULL) return;
2818 	gf_free(ptr);
2819 }
2820 
mdhd_Read(GF_Box * s,GF_BitStream * bs)2821 GF_Err mdhd_Read(GF_Box *s, GF_BitStream *bs)
2822 {
2823 	GF_Err e;
2824 	GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
2825 
2826 	e = gf_isom_full_box_read(s, bs);
2827 	if (e) return e;
2828 	if (ptr->version == 1) {
2829 		ptr->creationTime = gf_bs_read_u64(bs);
2830 		ptr->modificationTime = gf_bs_read_u64(bs);
2831 		ptr->timeScale = gf_bs_read_u32(bs);
2832 		ptr->duration = gf_bs_read_u64(bs);
2833 	}
2834 	else {
2835 		ptr->creationTime = gf_bs_read_u32(bs);
2836 		ptr->modificationTime = gf_bs_read_u32(bs);
2837 		ptr->timeScale = gf_bs_read_u32(bs);
2838 		ptr->duration = gf_bs_read_u32(bs);
2839 	}
2840 	if (!ptr->timeScale) {
2841 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Media header timescale is invalid (0) - defaulting to 90000\n"));
2842 		ptr->timeScale = 90000;
2843 	}
2844 
2845 	ptr->original_duration = ptr->duration;
2846 
2847 	//our padding bit
2848 	gf_bs_read_int(bs, 1);
2849 	//the spec is unclear here, just says "the value 0 is interpreted as undetermined"
2850 	ptr->packedLanguage[0] = gf_bs_read_int(bs, 5);
2851 	ptr->packedLanguage[1] = gf_bs_read_int(bs, 5);
2852 	ptr->packedLanguage[2] = gf_bs_read_int(bs, 5);
2853 	//but before or after compaction ?? We assume before
2854 	if (ptr->packedLanguage[0] || ptr->packedLanguage[1] || ptr->packedLanguage[2]) {
2855 		ptr->packedLanguage[0] += 0x60;
2856 		ptr->packedLanguage[1] += 0x60;
2857 		ptr->packedLanguage[2] += 0x60;
2858 	}
2859 	else {
2860 		ptr->packedLanguage[0] = 'u';
2861 		ptr->packedLanguage[1] = 'n';
2862 		ptr->packedLanguage[2] = 'd';
2863 	}
2864 	ptr->reserved = gf_bs_read_u16(bs);
2865 	return GF_OK;
2866 }
2867 
mdhd_New()2868 GF_Box *mdhd_New()
2869 {
2870 	ISOM_DECL_BOX_ALLOC(GF_MediaHeaderBox, GF_ISOM_BOX_TYPE_MDHD);
2871 
2872 	gf_isom_full_box_init((GF_Box *)tmp);
2873 
2874 	tmp->packedLanguage[0] = 'u';
2875 	tmp->packedLanguage[1] = 'n';
2876 	tmp->packedLanguage[2] = 'd';
2877 	return (GF_Box *)tmp;
2878 }
2879 
2880 
2881 #ifndef GPAC_DISABLE_ISOM_WRITE
2882 
mdhd_Write(GF_Box * s,GF_BitStream * bs)2883 GF_Err mdhd_Write(GF_Box *s, GF_BitStream *bs)
2884 {
2885 	GF_Err e;
2886 	GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
2887 	e = gf_isom_full_box_write(s, bs);
2888 	if (e) return e;
2889 	if (ptr->version == 1) {
2890 		gf_bs_write_u64(bs, ptr->creationTime);
2891 		gf_bs_write_u64(bs, ptr->modificationTime);
2892 		gf_bs_write_u32(bs, ptr->timeScale);
2893 		gf_bs_write_u64(bs, ptr->duration);
2894 	}
2895 	else {
2896 		gf_bs_write_u32(bs, (u32)ptr->creationTime);
2897 		gf_bs_write_u32(bs, (u32)ptr->modificationTime);
2898 		gf_bs_write_u32(bs, ptr->timeScale);
2899 		gf_bs_write_u32(bs, (u32)ptr->duration);
2900 	}
2901 	//SPECS: BIT(1) of padding
2902 	gf_bs_write_int(bs, 0, 1);
2903 	gf_bs_write_int(bs, ptr->packedLanguage[0] - 0x60, 5);
2904 	gf_bs_write_int(bs, ptr->packedLanguage[1] - 0x60, 5);
2905 	gf_bs_write_int(bs, ptr->packedLanguage[2] - 0x60, 5);
2906 	gf_bs_write_u16(bs, ptr->reserved);
2907 	return GF_OK;
2908 }
2909 
mdhd_Size(GF_Box * s)2910 GF_Err mdhd_Size(GF_Box *s)
2911 {
2912 	GF_Err e;
2913 	GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
2914 	ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
2915 	e = gf_isom_full_box_get_size(s);
2916 	if (e) return e;
2917 	ptr->size += 4;
2918 	ptr->size += (ptr->version == 1) ? 28 : 16;
2919 	return GF_OK;
2920 }
2921 
2922 #endif /*GPAC_DISABLE_ISOM_WRITE*/
2923 
2924 
mdia_del(GF_Box * s)2925 void mdia_del(GF_Box *s)
2926 {
2927 	GF_MediaBox *ptr = (GF_MediaBox *)s;
2928 	if (ptr == NULL) return;
2929 	if (ptr->mediaHeader) gf_isom_box_del((GF_Box *)ptr->mediaHeader);
2930 	if (ptr->information) gf_isom_box_del((GF_Box *)ptr->information);
2931 	if (ptr->handler) gf_isom_box_del((GF_Box *)ptr->handler);
2932 	gf_free(ptr);
2933 }
2934 
2935 
mdia_AddBox(GF_Box * s,GF_Box * a)2936 GF_Err mdia_AddBox(GF_Box *s, GF_Box *a)
2937 {
2938 	GF_MediaBox *ptr = (GF_MediaBox *)s;
2939 	switch (a->type) {
2940 	case GF_ISOM_BOX_TYPE_MDHD:
2941 		if (ptr->mediaHeader) ERROR_ON_DUPLICATED_BOX(a, ptr)
2942 
2943 			ptr->mediaHeader = (GF_MediaHeaderBox *)a;
2944 		return GF_OK;
2945 
2946 	case GF_ISOM_BOX_TYPE_HDLR:
2947 		if (ptr->handler) ERROR_ON_DUPLICATED_BOX(a, ptr)
2948 
2949 			ptr->handler = (GF_HandlerBox *)a;
2950 		return GF_OK;
2951 
2952 	case GF_ISOM_BOX_TYPE_MINF:
2953 		if (ptr->information) ERROR_ON_DUPLICATED_BOX(a, ptr)
2954 
2955 			ptr->information = (GF_MediaInformationBox *)a;
2956 		return GF_OK;
2957 	default:
2958 		return gf_isom_box_add_default(s, a);
2959 	}
2960 	return GF_OK;
2961 }
2962 
2963 
mdia_Read(GF_Box * s,GF_BitStream * bs)2964 GF_Err mdia_Read(GF_Box *s, GF_BitStream *bs)
2965 {
2966 	return gf_isom_read_box_list(s, bs, mdia_AddBox);
2967 }
2968 
mdia_New()2969 GF_Box *mdia_New()
2970 {
2971 	ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_MDIA);
2972 	return (GF_Box *)tmp;
2973 }
2974 
2975 #ifndef GPAC_DISABLE_ISOM_WRITE
2976 
mdia_Write(GF_Box * s,GF_BitStream * bs)2977 GF_Err mdia_Write(GF_Box *s, GF_BitStream *bs)
2978 {
2979 	GF_Err e;
2980 	GF_MediaBox *ptr = (GF_MediaBox *)s;
2981 	e = gf_isom_box_write_header(s, bs);
2982 	if (e) return e;
2983 	//Header first
2984 	if (ptr->mediaHeader) {
2985 		e = gf_isom_box_write((GF_Box *)ptr->mediaHeader, bs);
2986 		if (e) return e;
2987 	}
2988 	//then handler
2989 	if (ptr->handler) {
2990 		e = gf_isom_box_write((GF_Box *)ptr->handler, bs);
2991 		if (e) return e;
2992 	}
2993 	if (ptr->information) {
2994 		e = gf_isom_box_write((GF_Box *)ptr->information, bs);
2995 		if (e) return e;
2996 	}
2997 	return GF_OK;
2998 }
2999 
mdia_Size(GF_Box * s)3000 GF_Err mdia_Size(GF_Box *s)
3001 {
3002 	GF_Err e;
3003 	GF_MediaBox *ptr = (GF_MediaBox *)s;
3004 	e = gf_isom_box_get_size(s);
3005 	if (e) return e;
3006 
3007 	if (ptr->mediaHeader) {
3008 		e = gf_isom_box_size((GF_Box *)ptr->mediaHeader);
3009 		if (e) return e;
3010 		ptr->size += ptr->mediaHeader->size;
3011 	}
3012 	if (ptr->handler) {
3013 		e = gf_isom_box_size((GF_Box *)ptr->handler);
3014 		if (e) return e;
3015 		ptr->size += ptr->handler->size;
3016 	}
3017 	if (ptr->information) {
3018 		e = gf_isom_box_size((GF_Box *)ptr->information);
3019 		if (e) return e;
3020 		ptr->size += ptr->information->size;
3021 	}
3022 	return GF_OK;
3023 }
3024 
3025 #endif /*GPAC_DISABLE_ISOM_WRITE*/
3026 
mfra_del(GF_Box * s)3027 void mfra_del(GF_Box *s)
3028 {
3029 	GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
3030 	if (ptr == NULL) return;
3031 	gf_isom_box_array_del(ptr->tfra_list);
3032 	gf_free(ptr);
3033 }
3034 
mfra_New()3035 GF_Box *mfra_New()
3036 {
3037 	ISOM_DECL_BOX_ALLOC(GF_MovieFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_MFRA);
3038 	tmp->tfra_list = gf_list_new();
3039 	return (GF_Box *)tmp;
3040 }
3041 
mfra_AddBox(GF_Box * s,GF_Box * a)3042 GF_Err mfra_AddBox(GF_Box *s, GF_Box *a)
3043 {
3044 	GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
3045 	switch (a->type) {
3046 	case GF_ISOM_BOX_TYPE_TFRA:
3047 		return gf_list_add(ptr->tfra_list, a);
3048 	default:
3049 		return gf_isom_box_add_default(s, a);
3050 	}
3051 	return GF_OK;
3052 }
3053 
mfra_Read(GF_Box * s,GF_BitStream * bs)3054 GF_Err mfra_Read(GF_Box *s, GF_BitStream *bs)
3055 {
3056 	return gf_isom_read_box_list(s, bs, mfra_AddBox);
3057 }
3058 
tfra_del(GF_Box * s)3059 void tfra_del(GF_Box *s)
3060 {
3061 	GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
3062 	if (ptr == NULL) return;
3063 	if (ptr->entries) gf_free(ptr->entries);
3064 	gf_free(ptr);
3065 }
3066 
tfra_New()3067 GF_Box *tfra_New()
3068 {
3069 	ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_TFRA);
3070 	return (GF_Box *)tmp;
3071 }
3072 
tfra_Read(GF_Box * s,GF_BitStream * bs)3073 GF_Err tfra_Read(GF_Box *s, GF_BitStream *bs)
3074 {
3075 	GF_Err e;
3076 	u32 i;
3077 	GF_RandomAccessEntry *p = 0;
3078 	GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
3079 
3080 	e = gf_isom_full_box_read(s, bs);
3081 	if (e) return e;
3082 
3083 	ptr->track_id = gf_bs_read_u32(bs);
3084 
3085 	if (gf_bs_read_int(bs, 26) != 0) return GF_ISOM_INVALID_FILE;
3086 	ptr->traf_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
3087 	ptr->trun_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
3088 	ptr->sample_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
3089 	ptr->nb_entries = gf_bs_read_u32(bs);
3090 
3091 	if (ptr->nb_entries)
3092 	{
3093 		p = (GF_RandomAccessEntry *)gf_malloc(sizeof(GF_RandomAccessEntry) * ptr->nb_entries);
3094 		if (!p) return GF_OUT_OF_MEM;
3095 	}
3096 
3097 	ptr->entries = p;
3098 
3099 	for (i = 0; i<ptr->nb_entries; i++) {
3100 		memset(p, 0, sizeof(GF_RandomAccessEntry));
3101 
3102 		if (ptr->version == 1) {
3103 			p->time = gf_bs_read_u64(bs);
3104 			p->moof_offset = gf_bs_read_u64(bs);
3105 		}
3106 		else
3107 		{
3108 			p->time = gf_bs_read_u32(bs);
3109 			p->moof_offset = gf_bs_read_u32(bs);
3110 		}
3111 		p->traf_number = gf_bs_read_int(bs, ptr->traf_bits);
3112 		p->trun_number = gf_bs_read_int(bs, ptr->trun_bits);
3113 		p->sample_number = gf_bs_read_int(bs, ptr->sample_bits);
3114 
3115 		++p;
3116 	}
3117 	return GF_OK;
3118 }
3119 
elng_del(GF_Box * s)3120 void elng_del(GF_Box *s)
3121 {
3122 	GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
3123 	if (ptr == NULL) return;
3124 	if (ptr->extended_language) gf_free(ptr->extended_language);
3125 	gf_free(ptr);
3126 }
3127 
elng_Read(GF_Box * s,GF_BitStream * bs)3128 GF_Err elng_Read(GF_Box *s, GF_BitStream *bs)
3129 {
3130 	GF_Err e;
3131 	GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
3132 
3133 	e = gf_isom_full_box_read(s, bs);
3134 	if (e) return e;
3135 	if (ptr->size) {
3136 		ptr->extended_language = (char*)gf_malloc((u32)ptr->size);
3137 		if (ptr->extended_language == NULL) return GF_OUT_OF_MEM;
3138 		gf_bs_read_data(bs, ptr->extended_language, (u32)ptr->size);
3139 		/*safety check in case the string is not null-terminated*/
3140 		if (ptr->extended_language[ptr->size - 1]) {
3141 			char *str = (char*)gf_malloc((u32)ptr->size + 1);
3142 			memcpy(str, ptr->extended_language, (u32)ptr->size);
3143 			str[ptr->size] = 0;
3144 			gf_free(ptr->extended_language);
3145 			ptr->extended_language = str;
3146 		}
3147 	}
3148 	return GF_OK;
3149 }
3150 
elng_New()3151 GF_Box *elng_New()
3152 {
3153 	ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_ELNG);
3154 	return (GF_Box *)tmp;
3155 }
3156 
3157 #ifndef GPAC_DISABLE_ISOM_WRITE
3158 
elng_Write(GF_Box * s,GF_BitStream * bs)3159 GF_Err elng_Write(GF_Box *s, GF_BitStream *bs)
3160 {
3161 	GF_Err e;
3162 	GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
3163 	e = gf_isom_full_box_write(s, bs);
3164 	if (e) return e;
3165 	if (ptr->extended_language) {
3166 		gf_bs_write_data(bs, ptr->extended_language, (u32)(strlen(ptr->extended_language) + 1));
3167 	}
3168 	return GF_OK;
3169 }
3170 
elng_Size(GF_Box * s)3171 GF_Err elng_Size(GF_Box *s)
3172 {
3173 	GF_Err e;
3174 	GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
3175 	e = gf_isom_box_get_size(s);
3176 	if (e) return e;
3177 	ptr->size += 4;
3178 	if (ptr->extended_language) {
3179 		ptr->size += strlen(ptr->extended_language) + 1;
3180 	}
3181 	return GF_OK;
3182 }
3183 
3184 #endif /*GPAC_DISABLE_ISOM_WRITE*/
3185 
3186 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
3187 
mfhd_del(GF_Box * s)3188 void mfhd_del(GF_Box *s)
3189 {
3190 	GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
3191 	if (ptr == NULL) return;
3192 	gf_free(ptr);
3193 }
3194 
mfhd_Read(GF_Box * s,GF_BitStream * bs)3195 GF_Err mfhd_Read(GF_Box *s, GF_BitStream *bs)
3196 {
3197 	GF_Err e;
3198 	GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
3199 	e = gf_isom_full_box_read(s, bs);
3200 	if (e) return e;
3201 	ptr->sequence_number = gf_bs_read_u32(bs);
3202 	return GF_OK;
3203 }
3204 
mfhd_New()3205 GF_Box *mfhd_New()
3206 {
3207 	ISOM_DECL_BOX_ALLOC(GF_MovieFragmentHeaderBox, GF_ISOM_BOX_TYPE_MFHD);
3208 	return (GF_Box *)tmp;
3209 }
3210 
3211 
3212 #ifndef GPAC_DISABLE_ISOM_WRITE
3213 
3214 
mfhd_Write(GF_Box * s,GF_BitStream * bs)3215 GF_Err mfhd_Write(GF_Box *s, GF_BitStream *bs)
3216 {
3217 	GF_Err e;
3218 	GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
3219 	if (!s) return GF_BAD_PARAM;
3220 
3221 	e = gf_isom_full_box_write(s, bs);
3222 	if (e) return e;
3223 	gf_bs_write_u32(bs, ptr->sequence_number);
3224 	return GF_OK;
3225 }
3226 
mfhd_Size(GF_Box * s)3227 GF_Err mfhd_Size(GF_Box *s)
3228 {
3229 	GF_Err e;
3230 	GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
3231 	e = gf_isom_full_box_get_size(s);
3232 	if (e) return e;
3233 	ptr->size += 4;
3234 	return GF_OK;
3235 }
3236 
3237 
3238 
3239 #endif /*GPAC_DISABLE_ISOM_WRITE*/
3240 
3241 #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
3242 
3243 
minf_del(GF_Box * s)3244 void minf_del(GF_Box *s)
3245 {
3246 	GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
3247 	if (ptr == NULL) return;
3248 
3249 	//if we have a Handler not self-contained, delete it (the self-contained belongs to the movie)
3250 	if (ptr->dataHandler) {
3251 		gf_isom_datamap_close(ptr);
3252 	}
3253 	if (ptr->InfoHeader) gf_isom_box_del((GF_Box *)ptr->InfoHeader);
3254 	if (ptr->dataInformation) gf_isom_box_del((GF_Box *)ptr->dataInformation);
3255 	if (ptr->sampleTable) gf_isom_box_del((GF_Box *)ptr->sampleTable);
3256 	gf_free(ptr);
3257 }
3258 
minf_AddBox(GF_Box * s,GF_Box * a)3259 GF_Err minf_AddBox(GF_Box *s, GF_Box *a)
3260 {
3261 	GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
3262 	switch (a->type) {
3263 	case GF_ISOM_BOX_TYPE_NMHD:
3264 	case GF_ISOM_BOX_TYPE_STHD:
3265 	case GF_ISOM_BOX_TYPE_VMHD:
3266 	case GF_ISOM_BOX_TYPE_SMHD:
3267 	case GF_ISOM_BOX_TYPE_HMHD:
3268 	case GF_ISOM_BOX_TYPE_GMHD:
3269 		if (ptr->InfoHeader) ERROR_ON_DUPLICATED_BOX(a, ptr)
3270 
3271 			ptr->InfoHeader = a;
3272 		return GF_OK;
3273 
3274 	case GF_ISOM_BOX_TYPE_DINF:
3275 		if (ptr->dataInformation) ERROR_ON_DUPLICATED_BOX(a, ptr)
3276 
3277 			ptr->dataInformation = (GF_DataInformationBox *)a;
3278 		return GF_OK;
3279 
3280 	case GF_ISOM_BOX_TYPE_STBL:
3281 		if (ptr->sampleTable) ERROR_ON_DUPLICATED_BOX(a, ptr)
3282 
3283 			ptr->sampleTable = (GF_SampleTableBox *)a;
3284 		return GF_OK;
3285 	default:
3286 		return gf_isom_box_add_default(s, a);
3287 	}
3288 	return GF_OK;
3289 }
3290 
3291 
minf_Read(GF_Box * s,GF_BitStream * bs)3292 GF_Err minf_Read(GF_Box *s, GF_BitStream *bs)
3293 {
3294 	return gf_isom_read_box_list(s, bs, minf_AddBox);
3295 }
3296 
minf_New()3297 GF_Box *minf_New()
3298 {
3299 	ISOM_DECL_BOX_ALLOC(GF_MediaInformationBox, GF_ISOM_BOX_TYPE_MINF);
3300 	return (GF_Box *)tmp;
3301 }
3302 
3303 
3304 #ifndef GPAC_DISABLE_ISOM_WRITE
3305 
minf_Write(GF_Box * s,GF_BitStream * bs)3306 GF_Err minf_Write(GF_Box *s, GF_BitStream *bs)
3307 {
3308 	GF_Err e;
3309 	GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
3310 	if (!s) return GF_BAD_PARAM;
3311 
3312 	e = gf_isom_box_write_header(s, bs);
3313 	if (e) return e;
3314 
3315 	//Header first
3316 	if (ptr->InfoHeader) {
3317 		e = gf_isom_box_write((GF_Box *)ptr->InfoHeader, bs);
3318 		if (e) return e;
3319 	}
3320 	//then dataInfo
3321 	if (ptr->dataInformation) {
3322 		e = gf_isom_box_write((GF_Box *)ptr->dataInformation, bs);
3323 		if (e) return e;
3324 	}
3325 	//then sampleTable
3326 	if (ptr->sampleTable) {
3327 		e = gf_isom_box_write((GF_Box *)ptr->sampleTable, bs);
3328 		if (e) return e;
3329 	}
3330 	return GF_OK;
3331 }
3332 
minf_Size(GF_Box * s)3333 GF_Err minf_Size(GF_Box *s)
3334 {
3335 	GF_Err e;
3336 	GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
3337 
3338 	e = gf_isom_box_get_size(s);
3339 	if (e) return e;
3340 	if (ptr->InfoHeader) {
3341 		e = gf_isom_box_size((GF_Box *)ptr->InfoHeader);
3342 		if (e) return e;
3343 		ptr->size += ptr->InfoHeader->size;
3344 	}
3345 	if (ptr->dataInformation) {
3346 		e = gf_isom_box_size((GF_Box *)ptr->dataInformation);
3347 		if (e) return e;
3348 		ptr->size += ptr->dataInformation->size;
3349 	}
3350 	if (ptr->sampleTable) {
3351 		e = gf_isom_box_size((GF_Box *)ptr->sampleTable);
3352 		if (e) return e;
3353 		ptr->size += ptr->sampleTable->size;
3354 	}
3355 	return GF_OK;
3356 }
3357 
3358 #endif /*GPAC_DISABLE_ISOM_WRITE*/
3359 
3360 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
3361 
moof_del(GF_Box * s)3362 void moof_del(GF_Box *s)
3363 {
3364 	GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
3365 	if (ptr == NULL) return;
3366 
3367 	if (ptr->mfhd) gf_isom_box_del((GF_Box *)ptr->mfhd);
3368 	gf_isom_box_array_del(ptr->TrackList);
3369 	if (ptr->mdat) gf_free(ptr->mdat);
3370 	gf_free(ptr);
3371 }
3372 
moof_AddBox(GF_Box * s,GF_Box * a)3373 GF_Err moof_AddBox(GF_Box *s, GF_Box *a)
3374 {
3375 	GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
3376 	switch (a->type) {
3377 	case GF_ISOM_BOX_TYPE_MFHD:
3378 		if (ptr->mfhd) ERROR_ON_DUPLICATED_BOX(a, ptr)
3379 
3380 			ptr->mfhd = (GF_MovieFragmentHeaderBox *)a;
3381 		return GF_OK;
3382 	case GF_ISOM_BOX_TYPE_TRAF:
3383 		return gf_list_add(ptr->TrackList, a);
3384 	case GF_ISOM_BOX_TYPE_PSSH:
3385 	default:
3386 		return gf_isom_box_add_default(s, a);
3387 	}
3388 }
3389 
moof_Read(GF_Box * s,GF_BitStream * bs)3390 GF_Err moof_Read(GF_Box *s, GF_BitStream *bs)
3391 {
3392 	return gf_isom_read_box_list(s, bs, moof_AddBox);
3393 }
3394 
moof_New()3395 GF_Box *moof_New()
3396 {
3397 	ISOM_DECL_BOX_ALLOC(GF_MovieFragmentBox, GF_ISOM_BOX_TYPE_MOOF);
3398 	tmp->TrackList = gf_list_new();
3399 	return (GF_Box *)tmp;
3400 }
3401 
3402 
3403 #ifndef GPAC_DISABLE_ISOM_WRITE
3404 
moof_Write(GF_Box * s,GF_BitStream * bs)3405 GF_Err moof_Write(GF_Box *s, GF_BitStream *bs)
3406 {
3407 	GF_Err e;
3408 	GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
3409 	if (!s) return GF_BAD_PARAM;
3410 
3411 	e = gf_isom_box_write_header(s, bs);
3412 	if (e) return e;
3413 	//Header First
3414 	if (ptr->mfhd) {
3415 		e = gf_isom_box_write((GF_Box *)ptr->mfhd, bs);
3416 		if (e) return e;
3417 	}
3418 	//then the track list
3419 	return gf_isom_box_array_write(s, ptr->TrackList, bs);
3420 }
3421 
moof_Size(GF_Box * s)3422 GF_Err moof_Size(GF_Box *s)
3423 {
3424 	GF_Err e;
3425 	GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
3426 	e = gf_isom_box_get_size(s);
3427 	if (e) return e;
3428 
3429 
3430 	if (ptr->mfhd) {
3431 		e = gf_isom_box_size((GF_Box *)ptr->mfhd);
3432 		if (e) return e;
3433 		ptr->size += ptr->mfhd->size;
3434 	}
3435 	return gf_isom_box_array_size(s, ptr->TrackList);
3436 }
3437 
3438 
3439 
3440 #endif /*GPAC_DISABLE_ISOM_WRITE*/
3441 
3442 #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
3443 
moov_del(GF_Box * s)3444 void moov_del(GF_Box *s)
3445 {
3446 	GF_MovieBox *ptr = (GF_MovieBox *)s;
3447 	if (ptr == NULL) return;
3448 
3449 	if (ptr->mvhd) gf_isom_box_del((GF_Box *)ptr->mvhd);
3450 	if (ptr->meta) gf_isom_box_del((GF_Box *)ptr->meta);
3451 	if (ptr->iods) gf_isom_box_del((GF_Box *)ptr->iods);
3452 	if (ptr->udta) gf_isom_box_del((GF_Box *)ptr->udta);
3453 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
3454 	if (ptr->mvex) gf_isom_box_del((GF_Box *)ptr->mvex);
3455 #endif
3456 
3457 	gf_isom_box_array_del(ptr->trackList);
3458 	gf_free(ptr);
3459 }
3460 
3461 
moov_AddBox(GF_Box * s,GF_Box * a)3462 GF_Err moov_AddBox(GF_Box *s, GF_Box *a)
3463 {
3464 	GF_MovieBox *ptr = (GF_MovieBox *)s;
3465 	switch (a->type) {
3466 	case GF_ISOM_BOX_TYPE_IODS:
3467 		if (ptr->iods) ERROR_ON_DUPLICATED_BOX(a, ptr)
3468 			ptr->iods = (GF_ObjectDescriptorBox *)a;
3469 		//if no IOD, delete the box
3470 		if (!ptr->iods->descriptor) {
3471 			ptr->iods = NULL;
3472 			gf_isom_box_del(a);
3473 		}
3474 		return GF_OK;
3475 
3476 	case GF_ISOM_BOX_TYPE_MVHD:
3477 		if (ptr->mvhd) ERROR_ON_DUPLICATED_BOX(a, ptr)
3478 			ptr->mvhd = (GF_MovieHeaderBox *)a;
3479 		return GF_OK;
3480 
3481 	case GF_ISOM_BOX_TYPE_UDTA:
3482 		if (ptr->udta) ERROR_ON_DUPLICATED_BOX(a, ptr)
3483 			ptr->udta = (GF_UserDataBox *)a;
3484 		return GF_OK;
3485 
3486 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
3487 	case GF_ISOM_BOX_TYPE_MVEX:
3488 		if (ptr->mvex) ERROR_ON_DUPLICATED_BOX(a, ptr)
3489 			ptr->mvex = (GF_MovieExtendsBox *)a;
3490 		ptr->mvex->mov = ptr->mov;
3491 		return GF_OK;
3492 #endif
3493 
3494 	case GF_ISOM_BOX_TYPE_META:
3495 		if (ptr->meta) ERROR_ON_DUPLICATED_BOX(a, ptr)
3496 			ptr->meta = (GF_MetaBox *)a;
3497 		return GF_OK;
3498 
3499 	case GF_ISOM_BOX_TYPE_TRAK:
3500 		//set our pointer to this obj
3501 		((GF_TrackBox *)a)->moov = ptr;
3502 		return gf_list_add(ptr->trackList, a);
3503 	case GF_ISOM_BOX_TYPE_PSSH:
3504 	default:
3505 		return gf_isom_box_add_default(s, a);
3506 	}
3507 }
3508 
3509 
moov_Read(GF_Box * s,GF_BitStream * bs)3510 GF_Err moov_Read(GF_Box *s, GF_BitStream *bs)
3511 {
3512 	return gf_isom_read_box_list(s, bs, moov_AddBox);
3513 }
3514 
moov_New()3515 GF_Box *moov_New()
3516 {
3517 	ISOM_DECL_BOX_ALLOC(GF_MovieBox, GF_ISOM_BOX_TYPE_MOOV);
3518 	tmp->trackList = gf_list_new();
3519 	if (!tmp->trackList) {
3520 		gf_free(tmp);
3521 		return NULL;
3522 	}
3523 	return (GF_Box *)tmp;
3524 }
3525 
3526 
3527 
3528 #ifndef GPAC_DISABLE_ISOM_WRITE
3529 
3530 
moov_Write(GF_Box * s,GF_BitStream * bs)3531 GF_Err moov_Write(GF_Box *s, GF_BitStream *bs)
3532 {
3533 	GF_Err e;
3534 	GF_MovieBox *ptr = (GF_MovieBox *)s;
3535 	if (!s) return GF_BAD_PARAM;
3536 	e = gf_isom_box_write_header(s, bs);
3537 	if (e) return e;
3538 
3539 	if (ptr->mvhd) {
3540 		e = gf_isom_box_write((GF_Box *)ptr->mvhd, bs);
3541 		if (e) return e;
3542 	}
3543 	if (ptr->iods) {
3544 		e = gf_isom_box_write((GF_Box *)ptr->iods, bs);
3545 		if (e) return e;
3546 	}
3547 	if (ptr->meta) {
3548 		e = gf_isom_box_write((GF_Box *)ptr->meta, bs);
3549 		if (e) return e;
3550 	}
3551 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
3552 	if (ptr->mvex) {
3553 		e = gf_isom_box_write((GF_Box *)ptr->mvex, bs);
3554 		if (e) return e;
3555 	}
3556 #endif
3557 
3558 	e = gf_isom_box_array_write(s, ptr->trackList, bs);
3559 	if (e) return e;
3560 
3561 	if (ptr->udta) {
3562 		e = gf_isom_box_write((GF_Box *)ptr->udta, bs);
3563 		if (e) return e;
3564 	}
3565 	return GF_OK;
3566 }
3567 
moov_Size(GF_Box * s)3568 GF_Err moov_Size(GF_Box *s)
3569 {
3570 	GF_Err e;
3571 	GF_MovieBox *ptr = (GF_MovieBox *)s;
3572 	e = gf_isom_box_get_size(s);
3573 	if (e) return e;
3574 
3575 	if (ptr->mvhd) {
3576 		e = gf_isom_box_size((GF_Box *)ptr->mvhd);
3577 		if (e) return e;
3578 		ptr->size += ptr->mvhd->size;
3579 	}
3580 	if (ptr->iods) {
3581 		e = gf_isom_box_size((GF_Box *)ptr->iods);
3582 		if (e) return e;
3583 		ptr->size += ptr->iods->size;
3584 	}
3585 	if (ptr->udta) {
3586 		e = gf_isom_box_size((GF_Box *)ptr->udta);
3587 		if (e) return e;
3588 		ptr->size += ptr->udta->size;
3589 	}
3590 	if (ptr->meta) {
3591 		e = gf_isom_box_size((GF_Box *)ptr->meta);
3592 		if (e) return e;
3593 		ptr->size += ptr->meta->size;
3594 	}
3595 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
3596 	if (ptr->mvex) {
3597 		e = gf_isom_box_size((GF_Box *)ptr->mvex);
3598 		if (e) return e;
3599 		ptr->size += ptr->mvex->size;
3600 	}
3601 #endif
3602 
3603 	return gf_isom_box_array_size(s, ptr->trackList);
3604 }
3605 
3606 #endif /*GPAC_DISABLE_ISOM_WRITE*/
3607 
mp4a_del(GF_Box * s)3608 void mp4a_del(GF_Box *s)
3609 {
3610 	GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
3611 	if (ptr == NULL) return;
3612 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
3613 
3614 	if (ptr->esd) gf_isom_box_del((GF_Box *)ptr->esd);
3615 	if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
3616 	gf_free(ptr);
3617 }
3618 
mp4a_AddBox(GF_Box * s,GF_Box * a)3619 GF_Err mp4a_AddBox(GF_Box *s, GF_Box *a)
3620 {
3621 	GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
3622 	switch (a->type) {
3623 	case GF_ISOM_BOX_TYPE_ESDS:
3624 		if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
3625 			ptr->esd = (GF_ESDBox *)a;
3626 		break;
3627 	case GF_ISOM_BOX_TYPE_SINF:
3628 		gf_list_add(ptr->protections, a);
3629 		break;
3630 	case GF_4CC('w', 'a', 'v', 'e'):
3631 		if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
3632 			/*HACK for QT files: get the esds box from the track*/
3633 		{
3634 			GF_UnknownBox *wave = (GF_UnknownBox *)a;
3635 			u32 offset = 0;
3636 			while ((wave->data[offset + 4] != 'e') && (wave->data[offset + 5] != 's')) {
3637 				offset++;
3638 				if (offset == wave->dataSize) break;
3639 			}
3640 			if (offset < wave->dataSize) {
3641 				GF_Box *a;
3642 				GF_Err e;
3643 				GF_BitStream *bs = gf_bs_new(wave->data + offset, wave->dataSize - offset, GF_BITSTREAM_READ);
3644 				e = gf_isom_parse_box(&a, bs);
3645 				gf_bs_del(bs);
3646 				if (e) return e;
3647 				ptr->esd = (GF_ESDBox *)a;
3648 			}
3649 			gf_isom_box_del(a);
3650 		}
3651 		break;
3652 	default:
3653 		return gf_isom_box_add_default(s, a);
3654 	}
3655 	return GF_OK;
3656 }
mp4a_Read(GF_Box * s,GF_BitStream * bs)3657 GF_Err mp4a_Read(GF_Box *s, GF_BitStream *bs)
3658 {
3659 	GF_MPEGAudioSampleEntryBox *ptr;
3660 	char *data;
3661 	u32 i, size;
3662 	GF_Err e;
3663 	u64 pos;
3664 
3665 	e = gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox*)s, bs);
3666 	if (e) return e;
3667 	pos = gf_bs_get_position(bs);
3668 	size = (u32)s->size;
3669 
3670 	e = gf_isom_read_box_list(s, bs, mp4a_AddBox);
3671 	if (!e) return GF_OK;
3672 
3673 	/*hack for some weird files (possibly recorded with live.com tools, needs further investigations)*/
3674 	ptr = (GF_MPEGAudioSampleEntryBox *)s;
3675 	gf_bs_seek(bs, pos);
3676 	data = (char*)gf_malloc(sizeof(char) * size);
3677 	gf_bs_read_data(bs, data, size);
3678 	for (i = 0; i<size - 8; i++) {
3679 		if (GF_4CC(data[i + 4], data[i + 5], data[i + 6], data[i + 7]) == GF_ISOM_BOX_TYPE_ESDS) {
3680 			GF_BitStream *mybs = gf_bs_new(data + i, size - i, GF_BITSTREAM_READ);
3681 			e = gf_isom_parse_box((GF_Box **)&ptr->esd, mybs);
3682 			gf_bs_del(mybs);
3683 			break;
3684 		}
3685 	}
3686 	gf_free(data);
3687 	return e;
3688 }
3689 
mp4a_New()3690 GF_Box *mp4a_New()
3691 {
3692 	ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_MP4A);
3693 	gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
3694 	return (GF_Box *)tmp;
3695 }
3696 
enca_New()3697 GF_Box *enca_New()
3698 {
3699 	ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_ENCA);
3700 	gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
3701 	return (GF_Box *)tmp;
3702 }
3703 
3704 
3705 #ifndef GPAC_DISABLE_ISOM_WRITE
3706 
mp4a_Write(GF_Box * s,GF_BitStream * bs)3707 GF_Err mp4a_Write(GF_Box *s, GF_BitStream *bs)
3708 {
3709 	GF_Err e;
3710 	GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
3711 	e = gf_isom_box_write_header(s, bs);
3712 	if (e) return e;
3713 	gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs);
3714 	e = gf_isom_box_write((GF_Box *)ptr->esd, bs);
3715 	if (e) return e;
3716 
3717 	return gf_isom_box_array_write(s, ptr->protections, bs);
3718 }
3719 
mp4a_Size(GF_Box * s)3720 GF_Err mp4a_Size(GF_Box *s)
3721 {
3722 	GF_Err e;
3723 	GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
3724 	e = gf_isom_box_get_size(s);
3725 	if (e) return e;
3726 
3727 	gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox*)s);
3728 
3729 	e = gf_isom_box_size((GF_Box *)ptr->esd);
3730 	if (e) return e;
3731 	ptr->size += ptr->esd->size;
3732 	return gf_isom_box_array_size(s, ptr->protections);
3733 }
3734 
3735 #endif /*GPAC_DISABLE_ISOM_WRITE*/
3736 
3737 
mp4s_del(GF_Box * s)3738 void mp4s_del(GF_Box *s)
3739 {
3740 	GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
3741 	if (ptr == NULL) return;
3742 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
3743 
3744 	if (ptr->esd) gf_isom_box_del((GF_Box *)ptr->esd);
3745 	if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
3746 	gf_free(ptr);
3747 }
3748 
mp4s_AddBox(GF_Box * s,GF_Box * a)3749 GF_Err mp4s_AddBox(GF_Box *s, GF_Box *a)
3750 {
3751 	GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
3752 	switch (a->type) {
3753 	case GF_ISOM_BOX_TYPE_ESDS:
3754 		if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
3755 			ptr->esd = (GF_ESDBox *)a;
3756 		break;
3757 	case GF_ISOM_BOX_TYPE_SINF:
3758 		gf_list_add(ptr->protections, a);
3759 		break;
3760 	default:
3761 		return gf_isom_box_add_default(s, a);
3762 	}
3763 	return GF_OK;
3764 }
3765 
mp4s_Read(GF_Box * s,GF_BitStream * bs)3766 GF_Err mp4s_Read(GF_Box *s, GF_BitStream *bs)
3767 {
3768 	GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
3769 	gf_bs_read_data(bs, ptr->reserved, 6);
3770 	ptr->dataReferenceIndex = gf_bs_read_u16(bs);
3771 	ptr->size -= 8;
3772 	return gf_isom_read_box_list(s, bs, mp4s_AddBox);
3773 }
3774 
mp4s_New()3775 GF_Box *mp4s_New()
3776 {
3777 	ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_MP4S);
3778 	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
3779 	return (GF_Box *)tmp;
3780 }
3781 
encs_New()3782 GF_Box *encs_New()
3783 {
3784 	ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_ENCS);
3785 	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
3786 	return (GF_Box *)tmp;
3787 }
3788 
3789 
3790 #ifndef GPAC_DISABLE_ISOM_WRITE
3791 
mp4s_Write(GF_Box * s,GF_BitStream * bs)3792 GF_Err mp4s_Write(GF_Box *s, GF_BitStream *bs)
3793 {
3794 	GF_Err e;
3795 	GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
3796 
3797 	e = gf_isom_box_write_header(s, bs);
3798 	if (e) return e;
3799 	gf_bs_write_data(bs, ptr->reserved, 6);
3800 	gf_bs_write_u16(bs, ptr->dataReferenceIndex);
3801 	e = gf_isom_box_write((GF_Box *)ptr->esd, bs);
3802 	if (e) return e;
3803 	return gf_isom_box_array_write(s, ptr->protections, bs);
3804 }
3805 
mp4s_Size(GF_Box * s)3806 GF_Err mp4s_Size(GF_Box *s)
3807 {
3808 	GF_Err e;
3809 	GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
3810 
3811 	e = gf_isom_box_get_size(s);
3812 	if (e) return e;
3813 	ptr->size += 8;
3814 	e = gf_isom_box_size((GF_Box *)ptr->esd);
3815 	if (e) return e;
3816 	ptr->size += ptr->esd->size;
3817 	return gf_isom_box_array_size(s, ptr->protections);
3818 }
3819 
3820 #endif /*GPAC_DISABLE_ISOM_WRITE*/
3821 
mp4v_del(GF_Box * s)3822 void mp4v_del(GF_Box *s)
3823 {
3824 	GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
3825 	if (ptr == NULL) return;
3826 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
3827 
3828 	if (ptr->esd) gf_isom_box_del((GF_Box *)ptr->esd);
3829 	if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
3830 	if (ptr->avc_config) gf_isom_box_del((GF_Box *)ptr->avc_config);
3831 	if (ptr->svc_config) gf_isom_box_del((GF_Box *)ptr->svc_config);
3832 	if (ptr->hevc_config) gf_isom_box_del((GF_Box *)ptr->hevc_config);
3833 	if (ptr->lhvc_config) gf_isom_box_del((GF_Box *)ptr->lhvc_config);
3834 	if (ptr->descr) gf_isom_box_del((GF_Box *)ptr->descr);
3835 	if (ptr->ipod_ext) gf_isom_box_del((GF_Box *)ptr->ipod_ext);
3836 	/*for publishing*/
3837 	if (ptr->emul_esd) gf_odf_desc_del((GF_Descriptor *)ptr->emul_esd);
3838 
3839 	if (ptr->pasp) gf_isom_box_del((GF_Box *)ptr->pasp);
3840 	if (ptr->rvcc) gf_isom_box_del((GF_Box *)ptr->rvcc);
3841 
3842 	gf_free(ptr);
3843 }
3844 
mp4v_AddBox(GF_Box * s,GF_Box * a)3845 GF_Err mp4v_AddBox(GF_Box *s, GF_Box *a)
3846 {
3847 	GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
3848 	switch (a->type) {
3849 	case GF_ISOM_BOX_TYPE_ESDS:
3850 		if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
3851 			ptr->esd = (GF_ESDBox *)a;
3852 		break;
3853 	case GF_ISOM_BOX_TYPE_SINF:
3854 		gf_list_add(ptr->protections, a);
3855 		break;
3856 	case GF_ISOM_BOX_TYPE_AVCC:
3857 		if (ptr->avc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
3858 			ptr->avc_config = (GF_AVCConfigurationBox *)a;
3859 		break;
3860 	case GF_ISOM_BOX_TYPE_HVCC:
3861 		if (ptr->hevc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
3862 			ptr->hevc_config = (GF_HEVCConfigurationBox *)a;
3863 		break;
3864 	case GF_ISOM_BOX_TYPE_SVCC:
3865 		if (ptr->svc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
3866 			ptr->svc_config = (GF_AVCConfigurationBox *)a;
3867 		break;
3868 	case GF_ISOM_BOX_TYPE_LHVC:
3869 		if (ptr->lhvc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
3870 			ptr->lhvc_config = (GF_HEVCConfigurationBox *)a;
3871 		break;
3872 	case GF_ISOM_BOX_TYPE_M4DS:
3873 		if (ptr->descr) ERROR_ON_DUPLICATED_BOX(a, ptr)
3874 			ptr->descr = (GF_MPEG4ExtensionDescriptorsBox *)a;
3875 		break;
3876 	case GF_ISOM_BOX_TYPE_UUID:
3877 		if (ptr->ipod_ext) ERROR_ON_DUPLICATED_BOX(a, ptr)
3878 			ptr->ipod_ext = (GF_UnknownUUIDBox *)a;
3879 		break;
3880 	case GF_ISOM_BOX_TYPE_PASP:
3881 		if (ptr->pasp) ERROR_ON_DUPLICATED_BOX(a, ptr)
3882 			ptr->pasp = (GF_PixelAspectRatioBox *)a;
3883 		break;
3884 	case GF_ISOM_BOX_TYPE_RVCC:
3885 		if (ptr->rvcc) ERROR_ON_DUPLICATED_BOX(a, ptr)
3886 			ptr->rvcc = (GF_RVCConfigurationBox *)a;
3887 		break;
3888 	default:
3889 		return gf_isom_box_add_default(s, a);
3890 	}
3891 	return GF_OK;
3892 }
3893 
mp4v_Read(GF_Box * s,GF_BitStream * bs)3894 GF_Err mp4v_Read(GF_Box *s, GF_BitStream *bs)
3895 {
3896 	GF_MPEGVisualSampleEntryBox *mp4v = (GF_MPEGVisualSampleEntryBox*)s;
3897 	GF_Err e;
3898 	e = gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *)s, bs);
3899 	if (e) return e;
3900 	e = gf_isom_read_box_list(s, bs, mp4v_AddBox);
3901 	if (e) return e;
3902 	/*this is an AVC sample desc*/
3903 	if (mp4v->avc_config || mp4v->svc_config) AVC_RewriteESDescriptor(mp4v);
3904 	/*this is an HEVC sample desc*/
3905 	if (mp4v->hevc_config || mp4v->lhvc_config || (mp4v->type == GF_ISOM_BOX_TYPE_HVT1))
3906 		HEVC_RewriteESDescriptor(mp4v);
3907 	return GF_OK;
3908 }
3909 
mp4v_encv_avc_hevc_new(u32 type)3910 GF_Box *mp4v_encv_avc_hevc_new(u32 type)
3911 {
3912 	GF_MPEGVisualSampleEntryBox *tmp;
3913 	GF_SAFEALLOC(tmp, GF_MPEGVisualSampleEntryBox);
3914 	if (tmp == NULL) return NULL;
3915 
3916 	gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox *)tmp);
3917 	tmp->type = type;
3918 	return (GF_Box *)tmp;
3919 }
3920 
3921 
3922 #ifndef GPAC_DISABLE_ISOM_WRITE
3923 
mp4v_Write(GF_Box * s,GF_BitStream * bs)3924 GF_Err mp4v_Write(GF_Box *s, GF_BitStream *bs)
3925 {
3926 	GF_Err e;
3927 	GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
3928 	e = gf_isom_box_write_header(s, bs);
3929 	if (e) return e;
3930 	gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)s, bs);
3931 
3932 	if (ptr->pasp) {
3933 		e = gf_isom_box_write((GF_Box *)ptr->pasp, bs);
3934 		if (e) return e;
3935 	}
3936 
3937 	/*mp4v*/
3938 	if (ptr->esd) {
3939 		e = gf_isom_box_write((GF_Box *)ptr->esd, bs);
3940 		if (e) return e;
3941 	}
3942 	/*avc or hevc*/
3943 	else {
3944 		if (ptr->avc_config && ptr->avc_config->config) {
3945 			e = gf_isom_box_write((GF_Box *)ptr->avc_config, bs);
3946 			if (e) return e;
3947 		}
3948 		if (ptr->hevc_config && ptr->hevc_config->config) {
3949 			e = gf_isom_box_write((GF_Box *)ptr->hevc_config, bs);
3950 			if (e) return e;
3951 		}
3952 		if (ptr->ipod_ext) {
3953 			e = gf_isom_box_write((GF_Box *)ptr->ipod_ext, bs);
3954 			if (e) return e;
3955 		}
3956 		if (ptr->descr) {
3957 			e = gf_isom_box_write((GF_Box *)ptr->descr, bs);
3958 			if (e) return e;
3959 		}
3960 		if (ptr->svc_config && ptr->svc_config->config) {
3961 			e = gf_isom_box_write((GF_Box *)ptr->svc_config, bs);
3962 			if (e) return e;
3963 		}
3964 		if (ptr->lhvc_config && ptr->lhvc_config->config) {
3965 			e = gf_isom_box_write((GF_Box *)ptr->lhvc_config, bs);
3966 			if (e) return e;
3967 		}
3968 	}
3969 	if (ptr->rvcc) {
3970 		e = gf_isom_box_write((GF_Box *)ptr->rvcc, bs);
3971 		if (e) return e;
3972 	}
3973 	return gf_isom_box_array_write(s, ptr->protections, bs);
3974 }
3975 
mp4v_Size(GF_Box * s)3976 GF_Err mp4v_Size(GF_Box *s)
3977 {
3978 	GF_Err e;
3979 	GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
3980 	e = gf_isom_box_get_size(s);
3981 	if (e) return e;
3982 
3983 	gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);
3984 
3985 	if (ptr->esd) {
3986 		e = gf_isom_box_size((GF_Box *)ptr->esd);
3987 		if (e) return e;
3988 		ptr->size += ptr->esd->size;
3989 	}
3990 	else {
3991 		if (!ptr->avc_config && !ptr->svc_config && !ptr->hevc_config && !ptr->lhvc_config && (ptr->type != GF_ISOM_BOX_TYPE_HVT1)) {
3992 			return GF_ISOM_INVALID_FILE;
3993 		}
3994 
3995 		if (ptr->hevc_config && ptr->hevc_config->config) {
3996 			e = gf_isom_box_size((GF_Box *)ptr->hevc_config);
3997 			if (e) return e;
3998 			ptr->size += ptr->hevc_config->size;
3999 		}
4000 
4001 		if (ptr->avc_config && ptr->avc_config->config) {
4002 			e = gf_isom_box_size((GF_Box *)ptr->avc_config);
4003 			if (e) return e;
4004 			ptr->size += ptr->avc_config->size;
4005 		}
4006 
4007 		if (ptr->svc_config && ptr->svc_config->config) {
4008 			e = gf_isom_box_size((GF_Box *)ptr->svc_config);
4009 			if (e) return e;
4010 			ptr->size += ptr->svc_config->size;
4011 		}
4012 
4013 		if (ptr->lhvc_config && ptr->lhvc_config->config) {
4014 			e = gf_isom_box_size((GF_Box *)ptr->lhvc_config);
4015 			if (e) return e;
4016 			ptr->size += ptr->lhvc_config->size;
4017 		}
4018 
4019 		if (ptr->ipod_ext) {
4020 			e = gf_isom_box_size((GF_Box *)ptr->ipod_ext);
4021 			if (e) return e;
4022 			ptr->size += ptr->ipod_ext->size;
4023 		}
4024 		if (ptr->descr) {
4025 			e = gf_isom_box_size((GF_Box *)ptr->descr);
4026 			if (e) return e;
4027 			ptr->size += ptr->descr->size;
4028 		}
4029 	}
4030 	if (ptr->pasp) {
4031 		e = gf_isom_box_size((GF_Box *)ptr->pasp);
4032 		if (e) return e;
4033 		ptr->size += ptr->pasp->size;
4034 	}
4035 	if (ptr->rvcc) {
4036 		e = gf_isom_box_size((GF_Box *)ptr->rvcc);
4037 		if (e) return e;
4038 		ptr->size += ptr->rvcc->size;
4039 	}
4040 	return gf_isom_box_array_size(s, ptr->protections);
4041 }
4042 
4043 #endif /*GPAC_DISABLE_ISOM_WRITE*/
4044 
4045 
4046 
4047 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
4048 
mvex_del(GF_Box * s)4049 void mvex_del(GF_Box *s)
4050 {
4051 	GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
4052 	if (ptr == NULL) return;
4053 	if (ptr->mehd) gf_isom_box_del((GF_Box*)ptr->mehd);
4054 	gf_isom_box_array_del(ptr->TrackExList);
4055 	gf_isom_box_array_del(ptr->TrackExPropList);
4056 	gf_free(ptr);
4057 }
4058 
4059 
mvex_AddBox(GF_Box * s,GF_Box * a)4060 GF_Err mvex_AddBox(GF_Box *s, GF_Box *a)
4061 {
4062 	GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
4063 
4064 	switch (a->type) {
4065 	case GF_ISOM_BOX_TYPE_TREX:
4066 		return gf_list_add(ptr->TrackExList, a);
4067 	case GF_ISOM_BOX_TYPE_TREP:
4068 		return gf_list_add(ptr->TrackExPropList, a);
4069 	case GF_ISOM_BOX_TYPE_MEHD:
4070 		if (ptr->mehd) break;
4071 		ptr->mehd = (GF_MovieExtendsHeaderBox*)a;
4072 		return GF_OK;
4073 	default:
4074 		return gf_isom_box_add_default(s, a);
4075 	}
4076 	return GF_OK;
4077 }
4078 
4079 
4080 
mvex_Read(GF_Box * s,GF_BitStream * bs)4081 GF_Err mvex_Read(GF_Box *s, GF_BitStream *bs)
4082 {
4083 	return gf_isom_read_box_list(s, bs, mvex_AddBox);
4084 }
4085 
mvex_New()4086 GF_Box *mvex_New()
4087 {
4088 	ISOM_DECL_BOX_ALLOC(GF_MovieExtendsBox, GF_ISOM_BOX_TYPE_MVEX);
4089 	tmp->TrackExList = gf_list_new();
4090 	if (!tmp->TrackExList) {
4091 		gf_free(tmp);
4092 		return NULL;
4093 	}
4094 	tmp->TrackExPropList = gf_list_new();
4095 	if (!tmp->TrackExPropList) {
4096 		gf_list_del(tmp->TrackExList);
4097 		gf_free(tmp);
4098 		return NULL;
4099 	}
4100 	return (GF_Box *)tmp;
4101 }
4102 
4103 
4104 
4105 #ifndef GPAC_DISABLE_ISOM_WRITE
4106 
4107 
mvex_Write(GF_Box * s,GF_BitStream * bs)4108 GF_Err mvex_Write(GF_Box *s, GF_BitStream *bs)
4109 {
4110 	GF_Err e;
4111 	GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
4112 	if (!s) return GF_BAD_PARAM;
4113 	e = gf_isom_box_write_header(s, bs);
4114 	if (e) return e;
4115 	if (ptr->mehd) {
4116 		e = gf_isom_box_write((GF_Box *)ptr->mehd, bs);
4117 		if (e) return e;
4118 	}
4119 	e = gf_isom_box_array_write(s, ptr->TrackExList, bs);
4120 	if (e) return e;
4121 	return gf_isom_box_array_write(s, ptr->TrackExPropList, bs);
4122 }
4123 
mvex_Size(GF_Box * s)4124 GF_Err mvex_Size(GF_Box *s)
4125 {
4126 	GF_Err e;
4127 	GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
4128 	e = gf_isom_box_get_size(s);
4129 	if (e) return e;
4130 	if (ptr->mehd) {
4131 		e = gf_isom_box_size((GF_Box *)ptr->mehd);
4132 		if (e) return e;
4133 		ptr->size += ptr->mehd->size;
4134 	}
4135 	e = gf_isom_box_array_size(s, ptr->TrackExList);
4136 	if (e) return e;
4137 	return gf_isom_box_array_size(s, ptr->TrackExPropList);
4138 }
4139 
4140 
4141 
4142 #endif /*GPAC_DISABLE_ISOM_WRITE*/
4143 
mehd_New()4144 GF_Box *mehd_New()
4145 {
4146 	ISOM_DECL_BOX_ALLOC(GF_MovieExtendsHeaderBox, GF_ISOM_BOX_TYPE_MEHD);
4147 	return (GF_Box *)tmp;
4148 }
mehd_del(GF_Box * s)4149 void mehd_del(GF_Box *s)
4150 {
4151 	gf_free(s);
4152 }
mehd_Read(GF_Box * s,GF_BitStream * bs)4153 GF_Err mehd_Read(GF_Box *s, GF_BitStream *bs)
4154 {
4155 	GF_Err e;
4156 	GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
4157 
4158 	e = gf_isom_full_box_read(s, bs);
4159 	if (e) return e;
4160 	if (ptr->version == 1) {
4161 		ptr->fragment_duration = gf_bs_read_u64(bs);
4162 	}
4163 	else {
4164 		ptr->fragment_duration = (u64)gf_bs_read_u32(bs);
4165 	}
4166 	return GF_OK;
4167 }
4168 #ifndef GPAC_DISABLE_ISOM_WRITE
mehd_Write(GF_Box * s,GF_BitStream * bs)4169 GF_Err mehd_Write(GF_Box *s, GF_BitStream *bs)
4170 {
4171 	GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
4172 	GF_Err e = gf_isom_full_box_write(s, bs);
4173 	if (e) return e;
4174 	if (ptr->version == 1) {
4175 		gf_bs_write_u64(bs, ptr->fragment_duration);
4176 	}
4177 	else {
4178 		gf_bs_write_u32(bs, (u32)ptr->fragment_duration);
4179 	}
4180 	return GF_OK;
4181 }
mehd_Size(GF_Box * s)4182 GF_Err mehd_Size(GF_Box *s)
4183 {
4184 	GF_Err e = gf_isom_full_box_get_size(s);
4185 	GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
4186 	if (e) return e;
4187 	ptr->version = (ptr->fragment_duration>0xFFFFFFFF) ? 1 : 0;
4188 	s->size += (ptr->version == 1) ? 8 : 4;
4189 	return GF_OK;
4190 }
4191 #endif /*GPAC_DISABLE_ISOM_WRITE*/
4192 
4193 #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
4194 
4195 
mvhd_del(GF_Box * s)4196 void mvhd_del(GF_Box *s)
4197 {
4198 	GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
4199 	if (ptr == NULL) return;
4200 	gf_free(ptr);
4201 }
4202 
4203 
mvhd_Read(GF_Box * s,GF_BitStream * bs)4204 GF_Err mvhd_Read(GF_Box *s, GF_BitStream *bs)
4205 {
4206 	GF_Err e;
4207 	GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
4208 	if (ptr == NULL) return GF_BAD_PARAM;
4209 	e = gf_isom_full_box_read(s, bs);
4210 	if (e) return e;
4211 	if (ptr->version == 1) {
4212 		ptr->creationTime = gf_bs_read_u64(bs);
4213 		ptr->modificationTime = gf_bs_read_u64(bs);
4214 		ptr->timeScale = gf_bs_read_u32(bs);
4215 		ptr->duration = gf_bs_read_u64(bs);
4216 	}
4217 	else {
4218 		ptr->creationTime = gf_bs_read_u32(bs);
4219 		ptr->modificationTime = gf_bs_read_u32(bs);
4220 		ptr->timeScale = gf_bs_read_u32(bs);
4221 		ptr->duration = gf_bs_read_u32(bs);
4222 	}
4223 	if (!ptr->timeScale) {
4224 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Movie header timescale is invalid (0) - defaulting to 600\n"));
4225 		ptr->timeScale = 600;
4226 	}
4227 	ptr->preferredRate = gf_bs_read_u32(bs);
4228 	ptr->preferredVolume = gf_bs_read_u16(bs);
4229 	gf_bs_read_data(bs, ptr->reserved, 10);
4230 	ptr->matrixA = gf_bs_read_u32(bs);
4231 	ptr->matrixB = gf_bs_read_u32(bs);
4232 	ptr->matrixU = gf_bs_read_u32(bs);
4233 	ptr->matrixC = gf_bs_read_u32(bs);
4234 	ptr->matrixD = gf_bs_read_u32(bs);
4235 	ptr->matrixV = gf_bs_read_u32(bs);
4236 	ptr->matrixX = gf_bs_read_u32(bs);
4237 	ptr->matrixY = gf_bs_read_u32(bs);
4238 	ptr->matrixW = gf_bs_read_u32(bs);
4239 	ptr->previewTime = gf_bs_read_u32(bs);
4240 	ptr->previewDuration = gf_bs_read_u32(bs);
4241 	ptr->posterTime = gf_bs_read_u32(bs);
4242 	ptr->selectionTime = gf_bs_read_u32(bs);
4243 	ptr->selectionDuration = gf_bs_read_u32(bs);
4244 	ptr->currentTime = gf_bs_read_u32(bs);
4245 	ptr->nextTrackID = gf_bs_read_u32(bs);
4246 	ptr->original_duration = ptr->duration;
4247 	return GF_OK;
4248 }
4249 
mvhd_New()4250 GF_Box *mvhd_New()
4251 {
4252 	ISOM_DECL_BOX_ALLOC(GF_MovieHeaderBox, GF_ISOM_BOX_TYPE_MVHD);
4253 
4254 	gf_isom_full_box_init((GF_Box *)tmp);
4255 
4256 	tmp->preferredRate = (1 << 16);
4257 	tmp->preferredVolume = (1 << 8);
4258 
4259 	tmp->matrixA = (1 << 16);
4260 	tmp->matrixD = (1 << 16);
4261 	tmp->matrixW = (1 << 30);
4262 
4263 	tmp->nextTrackID = 1;
4264 
4265 	return (GF_Box *)tmp;
4266 }
4267 
4268 
4269 #ifndef GPAC_DISABLE_ISOM_WRITE
4270 
mvhd_Write(GF_Box * s,GF_BitStream * bs)4271 GF_Err mvhd_Write(GF_Box *s, GF_BitStream *bs)
4272 {
4273 	GF_Err e;
4274 	GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
4275 	e = gf_isom_full_box_write(s, bs);
4276 	if (e) return e;
4277 	if (ptr->version == 1) {
4278 		gf_bs_write_u64(bs, ptr->creationTime);
4279 		gf_bs_write_u64(bs, ptr->modificationTime);
4280 		gf_bs_write_u32(bs, ptr->timeScale);
4281 		gf_bs_write_u64(bs, ptr->duration);
4282 	}
4283 	else {
4284 		gf_bs_write_u32(bs, (u32)ptr->creationTime);
4285 		gf_bs_write_u32(bs, (u32)ptr->modificationTime);
4286 		gf_bs_write_u32(bs, ptr->timeScale);
4287 		gf_bs_write_u32(bs, (u32)ptr->duration);
4288 	}
4289 	gf_bs_write_u32(bs, ptr->preferredRate);
4290 	gf_bs_write_u16(bs, ptr->preferredVolume);
4291 	gf_bs_write_data(bs, ptr->reserved, 10);
4292 	gf_bs_write_u32(bs, ptr->matrixA);
4293 	gf_bs_write_u32(bs, ptr->matrixB);
4294 	gf_bs_write_u32(bs, ptr->matrixU);
4295 	gf_bs_write_u32(bs, ptr->matrixC);
4296 	gf_bs_write_u32(bs, ptr->matrixD);
4297 	gf_bs_write_u32(bs, ptr->matrixV);
4298 	gf_bs_write_u32(bs, ptr->matrixX);
4299 	gf_bs_write_u32(bs, ptr->matrixY);
4300 	gf_bs_write_u32(bs, ptr->matrixW);
4301 	gf_bs_write_u32(bs, ptr->previewTime);
4302 	gf_bs_write_u32(bs, ptr->previewDuration);
4303 	gf_bs_write_u32(bs, ptr->posterTime);
4304 	gf_bs_write_u32(bs, ptr->selectionTime);
4305 	gf_bs_write_u32(bs, ptr->selectionDuration);
4306 	gf_bs_write_u32(bs, ptr->currentTime);
4307 	gf_bs_write_u32(bs, ptr->nextTrackID);
4308 	return GF_OK;
4309 }
4310 
mvhd_Size(GF_Box * s)4311 GF_Err mvhd_Size(GF_Box *s)
4312 {
4313 	GF_Err e;
4314 	GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
4315 	if (ptr->duration == (u64)-1) ptr->version = 0;
4316 	else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
4317 	e = gf_isom_full_box_get_size(s);
4318 	if (e) return e;
4319 	ptr->size += (ptr->version == 1) ? 28 : 16;
4320 	ptr->size += 80;
4321 	return GF_OK;
4322 }
4323 
4324 #endif /*GPAC_DISABLE_ISOM_WRITE*/
4325 
4326 
nmhd_del(GF_Box * s)4327 void nmhd_del(GF_Box *s)
4328 {
4329 	GF_MPEGMediaHeaderBox *ptr = (GF_MPEGMediaHeaderBox *)s;
4330 	if (ptr == NULL) return;
4331 	gf_free(ptr);
4332 }
4333 
4334 
4335 
nmhd_Read(GF_Box * s,GF_BitStream * bs)4336 GF_Err nmhd_Read(GF_Box *s, GF_BitStream *bs)
4337 {
4338 	GF_Err e = gf_isom_full_box_read(s, bs);
4339 	if (e) return e;
4340 	return GF_OK;
4341 }
4342 
nmhd_New()4343 GF_Box *nmhd_New()
4344 {
4345 	ISOM_DECL_BOX_ALLOC(GF_MPEGMediaHeaderBox, GF_ISOM_BOX_TYPE_NMHD);
4346 	gf_isom_full_box_init((GF_Box *)tmp);
4347 	return (GF_Box *)tmp;
4348 }
4349 
4350 
4351 #ifndef GPAC_DISABLE_ISOM_WRITE
4352 
nmhd_Write(GF_Box * s,GF_BitStream * bs)4353 GF_Err nmhd_Write(GF_Box *s, GF_BitStream *bs)
4354 {
4355 	return gf_isom_full_box_write(s, bs);
4356 }
4357 
nmhd_Size(GF_Box * s)4358 GF_Err nmhd_Size(GF_Box *s)
4359 {
4360 	return gf_isom_full_box_get_size(s);
4361 }
4362 
4363 #endif /*GPAC_DISABLE_ISOM_WRITE*/
4364 
4365 
4366 
padb_del(GF_Box * s)4367 void padb_del(GF_Box *s)
4368 {
4369 	GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;
4370 	if (ptr == NULL) return;
4371 	if (ptr->padbits) gf_free(ptr->padbits);
4372 	gf_free(ptr);
4373 }
4374 
4375 
padb_Read(GF_Box * s,GF_BitStream * bs)4376 GF_Err padb_Read(GF_Box *s, GF_BitStream *bs)
4377 {
4378 	GF_Err e;
4379 	u32 i;
4380 	GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;
4381 
4382 	e = gf_isom_full_box_read(s, bs);
4383 	if (e) return e;
4384 
4385 	ptr->SampleCount = gf_bs_read_u32(bs);
4386 
4387 	ptr->padbits = (u8 *)gf_malloc(sizeof(u8)*ptr->SampleCount);
4388 	for (i = 0; i<ptr->SampleCount; i += 2) {
4389 		gf_bs_read_int(bs, 1);
4390 		if (i + 1 < ptr->SampleCount) {
4391 			ptr->padbits[i + 1] = gf_bs_read_int(bs, 3);
4392 		}
4393 		else {
4394 			gf_bs_read_int(bs, 3);
4395 		}
4396 		gf_bs_read_int(bs, 1);
4397 		ptr->padbits[i] = gf_bs_read_int(bs, 3);
4398 	}
4399 	return GF_OK;
4400 }
4401 
padb_New()4402 GF_Box *padb_New()
4403 {
4404 	ISOM_DECL_BOX_ALLOC(GF_PaddingBitsBox, GF_ISOM_BOX_TYPE_PADB);
4405 	gf_isom_full_box_init((GF_Box *)tmp);
4406 	return (GF_Box *)tmp;
4407 }
4408 
4409 
4410 
4411 #ifndef GPAC_DISABLE_ISOM_WRITE
4412 
padb_Write(GF_Box * s,GF_BitStream * bs)4413 GF_Err padb_Write(GF_Box *s, GF_BitStream *bs)
4414 {
4415 	u32 i;
4416 	GF_Err e;
4417 	GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;
4418 
4419 	e = gf_isom_full_box_write(s, bs);
4420 	if (e) return e;
4421 	gf_bs_write_int(bs, ptr->SampleCount, 32);
4422 
4423 	for (i = 0; i<ptr->SampleCount; i += 2) {
4424 		gf_bs_write_int(bs, 0, 1);
4425 		if (i + 1 < ptr->SampleCount) {
4426 			gf_bs_write_int(bs, ptr->padbits[i + 1], 3);
4427 		}
4428 		else {
4429 			gf_bs_write_int(bs, 0, 3);
4430 		}
4431 		gf_bs_write_int(bs, 0, 1);
4432 		gf_bs_write_int(bs, ptr->padbits[i], 3);
4433 	}
4434 	return GF_OK;
4435 }
4436 
padb_Size(GF_Box * s)4437 GF_Err padb_Size(GF_Box *s)
4438 {
4439 	GF_Err e;
4440 	GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;
4441 	e = gf_isom_full_box_get_size(s);
4442 	if (e) return e;
4443 	ptr->size += 4;
4444 	if (ptr->SampleCount) ptr->size += (ptr->SampleCount + 1) / 2;
4445 
4446 
4447 	return GF_OK;
4448 }
4449 
4450 #endif /*GPAC_DISABLE_ISOM_WRITE*/
4451 
4452 
rely_del(GF_Box * s)4453 void rely_del(GF_Box *s)
4454 {
4455 	GF_RelyHintBox *rely = (GF_RelyHintBox *)s;
4456 	gf_free(rely);
4457 }
4458 
rely_Read(GF_Box * s,GF_BitStream * bs)4459 GF_Err rely_Read(GF_Box *s, GF_BitStream *bs)
4460 {
4461 	GF_RelyHintBox *ptr = (GF_RelyHintBox *)s;
4462 	ptr->reserved = gf_bs_read_int(bs, 6);
4463 	ptr->prefered = gf_bs_read_int(bs, 1);
4464 	ptr->required = gf_bs_read_int(bs, 1);
4465 	return GF_OK;
4466 }
4467 
rely_New()4468 GF_Box *rely_New()
4469 {
4470 	ISOM_DECL_BOX_ALLOC(GF_RelyHintBox, GF_ISOM_BOX_TYPE_RELY);
4471 	return (GF_Box *)tmp;
4472 }
4473 
4474 
4475 #ifndef GPAC_DISABLE_ISOM_WRITE
rely_Write(GF_Box * s,GF_BitStream * bs)4476 GF_Err rely_Write(GF_Box *s, GF_BitStream *bs)
4477 {
4478 	GF_Err e;
4479 	GF_RelyHintBox *ptr = (GF_RelyHintBox *)s;
4480 	if (ptr == NULL) return GF_BAD_PARAM;
4481 	e = gf_isom_box_write_header(s, bs);
4482 	if (e) return e;
4483 	gf_bs_write_int(bs, ptr->reserved, 6);
4484 	gf_bs_write_int(bs, ptr->prefered, 1);
4485 	gf_bs_write_int(bs, ptr->required, 1);
4486 	return GF_OK;
4487 }
4488 
rely_Size(GF_Box * s)4489 GF_Err rely_Size(GF_Box *s)
4490 {
4491 	GF_Err e;
4492 	e = gf_isom_box_get_size(s);
4493 	if (e) return e;
4494 	s->size += 1;
4495 	return GF_OK;
4496 }
4497 #endif /*GPAC_DISABLE_ISOM_WRITE*/
4498 
4499 
rtpo_del(GF_Box * s)4500 void rtpo_del(GF_Box *s)
4501 {
4502 	GF_RTPOBox *rtpo = (GF_RTPOBox *)s;
4503 	gf_free(rtpo);
4504 }
4505 
rtpo_Read(GF_Box * s,GF_BitStream * bs)4506 GF_Err rtpo_Read(GF_Box *s, GF_BitStream *bs)
4507 {
4508 	GF_RTPOBox *ptr = (GF_RTPOBox *)s;
4509 	ptr->timeOffset = gf_bs_read_u32(bs);
4510 	return GF_OK;
4511 }
4512 
rtpo_New()4513 GF_Box *rtpo_New()
4514 {
4515 	ISOM_DECL_BOX_ALLOC(GF_RTPOBox, GF_ISOM_BOX_TYPE_RTPO);
4516 	return (GF_Box *)tmp;
4517 }
4518 #ifndef GPAC_DISABLE_ISOM_WRITE
rtpo_Write(GF_Box * s,GF_BitStream * bs)4519 GF_Err rtpo_Write(GF_Box *s, GF_BitStream *bs)
4520 {
4521 	GF_Err e;
4522 	GF_RTPOBox *ptr = (GF_RTPOBox *)s;
4523 	if (ptr == NULL) return GF_BAD_PARAM;
4524 
4525 	//here we have no pb, just remembed that some entries will have to
4526 	//be 4-bytes aligned ...
4527 	e = gf_isom_box_write_header(s, bs);
4528 	if (e) return e;
4529 	gf_bs_write_u32(bs, ptr->timeOffset);
4530 	return GF_OK;
4531 }
4532 
rtpo_Size(GF_Box * s)4533 GF_Err rtpo_Size(GF_Box *s)
4534 {
4535 	GF_Err e;
4536 	e = gf_isom_box_get_size(s);
4537 	if (e) return e;
4538 	s->size += 4;
4539 	return GF_OK;
4540 }
4541 #endif /*GPAC_DISABLE_ISOM_WRITE*/
4542 
smhd_del(GF_Box * s)4543 void smhd_del(GF_Box *s)
4544 {
4545 	GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
4546 	if (ptr == NULL) return;
4547 	gf_free(ptr);
4548 }
4549 
4550 
smhd_Read(GF_Box * s,GF_BitStream * bs)4551 GF_Err smhd_Read(GF_Box *s, GF_BitStream *bs)
4552 {
4553 	GF_Err e;
4554 	GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
4555 	e = gf_isom_full_box_read(s, bs);
4556 	if (e) return e;
4557 	ptr->balance = gf_bs_read_u16(bs);
4558 	ptr->reserved = gf_bs_read_u16(bs);
4559 	return GF_OK;
4560 }
4561 
smhd_New()4562 GF_Box *smhd_New()
4563 {
4564 	ISOM_DECL_BOX_ALLOC(GF_SoundMediaHeaderBox, GF_ISOM_BOX_TYPE_SMHD);
4565 	gf_isom_full_box_init((GF_Box *)tmp);
4566 	return (GF_Box *)tmp;
4567 }
4568 
4569 
4570 #ifndef GPAC_DISABLE_ISOM_WRITE
4571 
smhd_Write(GF_Box * s,GF_BitStream * bs)4572 GF_Err smhd_Write(GF_Box *s, GF_BitStream *bs)
4573 {
4574 	GF_Err e;
4575 	GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
4576 	e = gf_isom_full_box_write(s, bs);
4577 	if (e) return e;
4578 	gf_bs_write_u16(bs, ptr->balance);
4579 	gf_bs_write_u16(bs, ptr->reserved);
4580 	return GF_OK;
4581 }
4582 
smhd_Size(GF_Box * s)4583 GF_Err smhd_Size(GF_Box *s)
4584 {
4585 	GF_Err e;
4586 	GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
4587 	e = gf_isom_full_box_get_size(s);
4588 	if (e) return e;
4589 	ptr->reserved = 0;
4590 	ptr->size += 4;
4591 	return GF_OK;
4592 }
4593 
4594 #endif /*GPAC_DISABLE_ISOM_WRITE*/
4595 
4596 
4597 
snro_del(GF_Box * s)4598 void snro_del(GF_Box *s)
4599 {
4600 	GF_SeqOffHintEntryBox *snro = (GF_SeqOffHintEntryBox *)s;
4601 	gf_free(snro);
4602 }
4603 
snro_Read(GF_Box * s,GF_BitStream * bs)4604 GF_Err snro_Read(GF_Box *s, GF_BitStream *bs)
4605 {
4606 	GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s;
4607 	ptr->SeqOffset = gf_bs_read_u32(bs);
4608 	return GF_OK;
4609 }
4610 
snro_New()4611 GF_Box *snro_New()
4612 {
4613 	ISOM_DECL_BOX_ALLOC(GF_SeqOffHintEntryBox, GF_ISOM_BOX_TYPE_SNRO);
4614 	return (GF_Box *)tmp;
4615 }
4616 
4617 
4618 #ifndef GPAC_DISABLE_ISOM_WRITE
snro_Write(GF_Box * s,GF_BitStream * bs)4619 GF_Err snro_Write(GF_Box *s, GF_BitStream *bs)
4620 {
4621 	GF_Err e;
4622 	GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s;
4623 	if (ptr == NULL) return GF_BAD_PARAM;
4624 
4625 	e = gf_isom_box_write_header(s, bs);
4626 	if (e) return e;
4627 	gf_bs_write_u32(bs, ptr->SeqOffset);
4628 	return GF_OK;
4629 }
4630 
snro_Size(GF_Box * s)4631 GF_Err snro_Size(GF_Box *s)
4632 {
4633 	GF_Err e;
4634 	e = gf_isom_box_get_size(s);
4635 	if (e) return e;
4636 	s->size += 4;
4637 	return GF_OK;
4638 }
4639 #endif /*GPAC_DISABLE_ISOM_WRITE*/
4640 
4641 
4642 #define WRITE_SAMPLE_FRAGMENTS		1
4643 
stbl_del(GF_Box * s)4644 void stbl_del(GF_Box *s)
4645 {
4646 	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
4647 	if (ptr == NULL) return;
4648 
4649 	if (ptr->ChunkOffset) gf_isom_box_del(ptr->ChunkOffset);
4650 	if (ptr->CompositionOffset) gf_isom_box_del((GF_Box *)ptr->CompositionOffset);
4651 	if (ptr->CompositionToDecode) gf_isom_box_del((GF_Box *)ptr->CompositionToDecode);
4652 	if (ptr->DegradationPriority) gf_isom_box_del((GF_Box *)ptr->DegradationPriority);
4653 	if (ptr->SampleDescription) gf_isom_box_del((GF_Box *)ptr->SampleDescription);
4654 	if (ptr->SampleSize) gf_isom_box_del((GF_Box *)ptr->SampleSize);
4655 	if (ptr->SampleToChunk) gf_isom_box_del((GF_Box *)ptr->SampleToChunk);
4656 	if (ptr->ShadowSync) gf_isom_box_del((GF_Box *)ptr->ShadowSync);
4657 	if (ptr->SyncSample) gf_isom_box_del((GF_Box *)ptr->SyncSample);
4658 	if (ptr->TimeToSample) gf_isom_box_del((GF_Box *)ptr->TimeToSample);
4659 	if (ptr->SampleDep) gf_isom_box_del((GF_Box *)ptr->SampleDep);
4660 	if (ptr->PaddingBits) gf_isom_box_del((GF_Box *)ptr->PaddingBits);
4661 	if (ptr->Fragments) gf_isom_box_del((GF_Box *)ptr->Fragments);
4662 	if (ptr->sub_samples) gf_isom_box_array_del(ptr->sub_samples);
4663 	if (ptr->sampleGroups) gf_isom_box_array_del(ptr->sampleGroups);
4664 	if (ptr->sampleGroupsDescription) gf_isom_box_array_del(ptr->sampleGroupsDescription);
4665 
4666 	if (ptr->sai_sizes) gf_isom_box_array_del(ptr->sai_sizes);
4667 	if (ptr->sai_offsets) gf_isom_box_array_del(ptr->sai_offsets);
4668 
4669 	gf_free(ptr);
4670 }
4671 
stbl_AddBox(GF_SampleTableBox * ptr,GF_Box * a)4672 GF_Err stbl_AddBox(GF_SampleTableBox *ptr, GF_Box *a)
4673 {
4674 	if (!a) return GF_OK;
4675 	switch (a->type) {
4676 	case GF_ISOM_BOX_TYPE_STTS:
4677 		if (ptr->TimeToSample) ERROR_ON_DUPLICATED_BOX(a, ptr)
4678 			ptr->TimeToSample = (GF_TimeToSampleBox *)a;
4679 		break;
4680 	case GF_ISOM_BOX_TYPE_CTTS:
4681 		if (ptr->CompositionOffset) ERROR_ON_DUPLICATED_BOX(a, ptr)
4682 			ptr->CompositionOffset = (GF_CompositionOffsetBox *)a;
4683 		break;
4684 	case GF_ISOM_BOX_TYPE_CSLG:
4685 		if (ptr->CompositionToDecode) ERROR_ON_DUPLICATED_BOX(a, ptr)
4686 			ptr->CompositionToDecode = (GF_CompositionToDecodeBox *)a;
4687 		break;
4688 	case GF_ISOM_BOX_TYPE_STSS:
4689 		if (ptr->SyncSample) ERROR_ON_DUPLICATED_BOX(a, ptr)
4690 			ptr->SyncSample = (GF_SyncSampleBox *)a;
4691 		break;
4692 	case GF_ISOM_BOX_TYPE_STSD:
4693 		if (ptr->SampleDescription) ERROR_ON_DUPLICATED_BOX(a, ptr)
4694 			ptr->SampleDescription = (GF_SampleDescriptionBox *)a;
4695 		break;
4696 	case GF_ISOM_BOX_TYPE_STZ2:
4697 	case GF_ISOM_BOX_TYPE_STSZ:
4698 		if (ptr->SampleSize) ERROR_ON_DUPLICATED_BOX(a, ptr)
4699 			ptr->SampleSize = (GF_SampleSizeBox *)a;
4700 		break;
4701 	case GF_ISOM_BOX_TYPE_STSC:
4702 		if (ptr->SampleToChunk) ERROR_ON_DUPLICATED_BOX(a, ptr)
4703 			ptr->SampleToChunk = (GF_SampleToChunkBox *)a;
4704 		break;
4705 	case GF_ISOM_BOX_TYPE_PADB:
4706 		if (ptr->PaddingBits) ERROR_ON_DUPLICATED_BOX(a, ptr)
4707 			ptr->PaddingBits = (GF_PaddingBitsBox *)a;
4708 		break;
4709 
4710 		//WARNING: AS THIS MAY CHANGE DYNAMICALLY DURING EDIT,
4711 	case GF_ISOM_BOX_TYPE_CO64:
4712 	case GF_ISOM_BOX_TYPE_STCO:
4713 		if (ptr->ChunkOffset) {
4714 			gf_isom_box_del(ptr->ChunkOffset);
4715 		}
4716 		ptr->ChunkOffset = a;
4717 		return GF_OK;
4718 	case GF_ISOM_BOX_TYPE_STSH:
4719 		if (ptr->ShadowSync) ERROR_ON_DUPLICATED_BOX(a, ptr)
4720 			ptr->ShadowSync = (GF_ShadowSyncBox *)a;
4721 		break;
4722 	case GF_ISOM_BOX_TYPE_STDP:
4723 		if (ptr->DegradationPriority) ERROR_ON_DUPLICATED_BOX(a, ptr)
4724 			ptr->DegradationPriority = (GF_DegradationPriorityBox *)a;
4725 		break;
4726 	case GF_ISOM_BOX_TYPE_SDTP:
4727 		if (ptr->SampleDep) ERROR_ON_DUPLICATED_BOX(a, ptr)
4728 			ptr->SampleDep = (GF_SampleDependencyTypeBox *)a;
4729 		break;
4730 
4731 	case GF_ISOM_BOX_TYPE_STSF:
4732 		if (ptr->Fragments) ERROR_ON_DUPLICATED_BOX(a, ptr)
4733 			ptr->Fragments = (GF_SampleFragmentBox *)a;
4734 		break;
4735 
4736 	case GF_ISOM_BOX_TYPE_SUBS:
4737 		if (!ptr->sub_samples) ptr->sub_samples = gf_list_new();
4738 		gf_list_add(ptr->sub_samples, a);
4739 		break;
4740 
4741 	case GF_ISOM_BOX_TYPE_SBGP:
4742 		if (!ptr->sampleGroups) ptr->sampleGroups = gf_list_new();
4743 		gf_list_add(ptr->sampleGroups, a);
4744 		break;
4745 	case GF_ISOM_BOX_TYPE_SGPD:
4746 		if (!ptr->sampleGroupsDescription) ptr->sampleGroupsDescription = gf_list_new();
4747 		gf_list_add(ptr->sampleGroupsDescription, a);
4748 		break;
4749 
4750 	case GF_ISOM_BOX_TYPE_SAIZ:
4751 		if (!ptr->sai_sizes) ptr->sai_sizes = gf_list_new();
4752 		gf_list_add(ptr->sai_sizes, a);
4753 		break;
4754 	case GF_ISOM_BOX_TYPE_SAIO:
4755 		if (!ptr->sai_offsets) ptr->sai_offsets = gf_list_new();
4756 		gf_list_add(ptr->sai_offsets, a);
4757 		break;
4758 
4759 	case GF_ISOM_BOX_TYPE_SENC:
4760 		ptr->senc = a;
4761 		return gf_isom_box_add_default((GF_Box *)ptr, a);
4762 	case GF_ISOM_BOX_UUID_PSEC:
4763 		ptr->piff_psec = a;
4764 		return gf_isom_box_add_default((GF_Box *)ptr, a);
4765 	case GF_ISOM_BOX_TYPE_UUID:
4766 		if (((GF_UnknownUUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC) {
4767 			ptr->piff_psec = a;
4768 			return gf_isom_box_add_default((GF_Box *)ptr, a);
4769 		}
4770 
4771 	default:
4772 		return gf_isom_box_add_default((GF_Box *)ptr, a);
4773 	}
4774 	return GF_OK;
4775 }
4776 
4777 
4778 
4779 
stbl_Read(GF_Box * s,GF_BitStream * bs)4780 GF_Err stbl_Read(GF_Box *s, GF_BitStream *bs)
4781 {
4782 	GF_Err e;
4783 	GF_Box *a;
4784 	//we need to parse DegPrior in a special way
4785 	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
4786 
4787 	while (ptr->size) {
4788 		e = gf_isom_parse_box(&a, bs);
4789 		if (e) return e;
4790 		//we need to read the DegPriority in a different way...
4791 		if ((a->type == GF_ISOM_BOX_TYPE_STDP) || (a->type == GF_ISOM_BOX_TYPE_SDTP)) {
4792 			u64 s = a->size;
4793 			/*
4794 			if (!ptr->SampleSize) {
4795 			gf_isom_box_del(a);
4796 			return GF_ISOM_INVALID_FILE;
4797 			}
4798 			*/
4799 			if (a->type == GF_ISOM_BOX_TYPE_STDP) {
4800 				if (ptr->SampleSize) ((GF_DegradationPriorityBox *)a)->nb_entries = ptr->SampleSize->sampleCount;
4801 				e = stdp_Read(a, bs);
4802 			}
4803 			else {
4804 				if (ptr->SampleSize) ((GF_SampleDependencyTypeBox *)a)->sampleCount = ptr->SampleSize->sampleCount;
4805 				e = sdtp_Read(a, bs);
4806 			}
4807 			if (e) {
4808 				gf_isom_box_del(a);
4809 				return e;
4810 			}
4811 
4812 			if (a->size>8) {
4813 				GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Box \"%s\" has %d extra bytes\n", gf_4cc_to_str(a->type), a->size));
4814 				gf_bs_skip_bytes(bs, a->size - 8);
4815 			}
4816 			a->size = s;
4817 		}
4818 
4819 		if (ptr->size<a->size) {
4820 			gf_isom_box_del(a);
4821 			return GF_ISOM_INVALID_FILE;
4822 		}
4823 		ptr->size -= a->size;
4824 		e = stbl_AddBox(ptr, a);
4825 		if (e) return e;
4826 	}
4827 	if (!ptr->SyncSample)
4828 		ptr->no_sync_found = 1;
4829 
4830 	ptr->nb_sgpd_in_stbl = gf_list_count(ptr->sampleGroupsDescription);
4831 	ptr->nb_other_boxes_in_stbl = gf_list_count(ptr->other_boxes);
4832 
4833 	return GF_OK;
4834 }
4835 
stbl_New()4836 GF_Box *stbl_New()
4837 {
4838 	ISOM_DECL_BOX_ALLOC(GF_SampleTableBox, GF_ISOM_BOX_TYPE_STBL);
4839 	//maxSamplePer chunk is 10 by default
4840 	tmp->MaxSamplePerChunk = 10;
4841 	tmp->groupID = 1;
4842 	return (GF_Box *)tmp;
4843 }
4844 
4845 
4846 
4847 #ifndef GPAC_DISABLE_ISOM_WRITE
4848 
stbl_Write(GF_Box * s,GF_BitStream * bs)4849 GF_Err stbl_Write(GF_Box *s, GF_BitStream *bs)
4850 {
4851 	GF_Err e;
4852 	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
4853 	if (!s) return GF_BAD_PARAM;
4854 	e = gf_isom_box_write_header(s, bs);
4855 	if (e) return e;
4856 
4857 	if (ptr->SampleDescription) {
4858 		e = gf_isom_box_write((GF_Box *)ptr->SampleDescription, bs);
4859 		if (e) return e;
4860 	}
4861 	if (ptr->TimeToSample) {
4862 		e = gf_isom_box_write((GF_Box *)ptr->TimeToSample, bs);
4863 		if (e) return e;
4864 	}
4865 	if (ptr->CompositionOffset) {
4866 		e = gf_isom_box_write((GF_Box *)ptr->CompositionOffset, bs);
4867 		if (e) return e;
4868 	}
4869 	if (ptr->CompositionToDecode) {
4870 		e = gf_isom_box_write((GF_Box *)ptr->CompositionToDecode, bs);
4871 		if (e) return e;
4872 	}
4873 	if (ptr->SyncSample) {
4874 		e = gf_isom_box_write((GF_Box *)ptr->SyncSample, bs);
4875 		if (e) return e;
4876 	}
4877 	if (ptr->ShadowSync) {
4878 		e = gf_isom_box_write((GF_Box *)ptr->ShadowSync, bs);
4879 		if (e) return e;
4880 	}
4881 	if (ptr->SampleToChunk) {
4882 		e = gf_isom_box_write((GF_Box *)ptr->SampleToChunk, bs);
4883 		if (e) return e;
4884 	}
4885 	if (ptr->SampleSize) {
4886 		e = gf_isom_box_write((GF_Box *)ptr->SampleSize, bs);
4887 		if (e) return e;
4888 	}
4889 	if (ptr->ChunkOffset) {
4890 		e = gf_isom_box_write(ptr->ChunkOffset, bs);
4891 		if (e) return e;
4892 	}
4893 	if (ptr->DegradationPriority) {
4894 		e = gf_isom_box_write((GF_Box *)ptr->DegradationPriority, bs);
4895 		if (e) return e;
4896 	}
4897 	if (ptr->SampleDep && ptr->SampleDep->sampleCount) {
4898 		e = gf_isom_box_write((GF_Box *)ptr->SampleDep, bs);
4899 		if (e) return e;
4900 	}
4901 	if (ptr->PaddingBits) {
4902 		e = gf_isom_box_write((GF_Box *)ptr->PaddingBits, bs);
4903 		if (e) return e;
4904 	}
4905 	if (ptr->sub_samples) {
4906 		e = gf_isom_box_array_write(s, ptr->sub_samples, bs);
4907 		if (e) return e;
4908 	}
4909 	if (ptr->sampleGroupsDescription) {
4910 		e = gf_isom_box_array_write(s, ptr->sampleGroupsDescription, bs);
4911 		if (e) return e;
4912 	}
4913 	if (ptr->sampleGroups) {
4914 		e = gf_isom_box_array_write(s, ptr->sampleGroups, bs);
4915 		if (e) return e;
4916 	}
4917 	if (ptr->sai_sizes) {
4918 		e = gf_isom_box_array_write(s, ptr->sai_sizes, bs);
4919 		if (e) return e;
4920 	}
4921 	if (ptr->sai_offsets) {
4922 		e = gf_isom_box_array_write(s, ptr->sai_offsets, bs);
4923 		if (e) return e;
4924 	}
4925 
4926 #if WRITE_SAMPLE_FRAGMENTS
4927 	//sampleFragments
4928 	if (ptr->Fragments) {
4929 		e = gf_isom_box_write((GF_Box *)ptr->Fragments, bs);
4930 		if (e) return e;
4931 	}
4932 #endif
4933 	return GF_OK;
4934 }
4935 
stbl_Size(GF_Box * s)4936 GF_Err stbl_Size(GF_Box *s)
4937 {
4938 	GF_Err e;
4939 	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
4940 	e = gf_isom_box_get_size(s);
4941 	if (e) return e;
4942 
4943 	//Mandatory boxs (but not internally :)
4944 	if (ptr->SampleDescription) {
4945 		e = gf_isom_box_size((GF_Box *)ptr->SampleDescription);
4946 		if (e) return e;
4947 		ptr->size += ptr->SampleDescription->size;
4948 	}
4949 	if (ptr->SampleSize) {
4950 		e = gf_isom_box_size((GF_Box *)ptr->SampleSize);
4951 		if (e) return e;
4952 		ptr->size += ptr->SampleSize->size;
4953 	}
4954 	if (ptr->SampleToChunk) {
4955 		e = gf_isom_box_size((GF_Box *)ptr->SampleToChunk);
4956 		if (e) return e;
4957 		ptr->size += ptr->SampleToChunk->size;
4958 	}
4959 	if (ptr->TimeToSample) {
4960 		e = gf_isom_box_size((GF_Box *)ptr->TimeToSample);
4961 		if (e) return e;
4962 		ptr->size += ptr->TimeToSample->size;
4963 	}
4964 	if (ptr->ChunkOffset) {
4965 		e = gf_isom_box_size(ptr->ChunkOffset);
4966 		if (e) return e;
4967 		ptr->size += ptr->ChunkOffset->size;
4968 	}
4969 
4970 	//optional boxs
4971 	if (ptr->CompositionOffset) {
4972 		e = gf_isom_box_size((GF_Box *)ptr->CompositionOffset);
4973 		if (e) return e;
4974 		ptr->size += ptr->CompositionOffset->size;
4975 	}
4976 	if (ptr->CompositionToDecode) {
4977 		e = gf_isom_box_size((GF_Box *)ptr->CompositionToDecode);
4978 		if (e) return e;
4979 		ptr->size += ptr->CompositionToDecode->size;
4980 	}
4981 	if (ptr->DegradationPriority) {
4982 		e = gf_isom_box_size((GF_Box *)ptr->DegradationPriority);
4983 		if (e) return e;
4984 		ptr->size += ptr->DegradationPriority->size;
4985 	}
4986 	if (ptr->ShadowSync) {
4987 		e = gf_isom_box_size((GF_Box *)ptr->ShadowSync);
4988 		if (e) return e;
4989 		ptr->size += ptr->ShadowSync->size;
4990 	}
4991 	if (ptr->SyncSample) {
4992 		e = gf_isom_box_size((GF_Box *)ptr->SyncSample);
4993 		if (e) return e;
4994 		ptr->size += ptr->SyncSample->size;
4995 	}
4996 	if (ptr->SampleDep && ptr->SampleDep->sampleCount) {
4997 		e = gf_isom_box_size((GF_Box *)ptr->SampleDep);
4998 		if (e) return e;
4999 		ptr->size += ptr->SampleDep->size;
5000 	}
5001 	//padb
5002 	if (ptr->PaddingBits) {
5003 		e = gf_isom_box_size((GF_Box *)ptr->PaddingBits);
5004 		if (e) return e;
5005 		ptr->size += ptr->PaddingBits->size;
5006 	}
5007 #if WRITE_SAMPLE_FRAGMENTS
5008 	//sample fragments
5009 	if (ptr->Fragments) {
5010 		e = gf_isom_box_size((GF_Box *)ptr->Fragments);
5011 		if (e) return e;
5012 		ptr->size += ptr->Fragments->size;
5013 	}
5014 #endif
5015 
5016 	if (ptr->sub_samples) {
5017 		e = gf_isom_box_array_size(s, ptr->sub_samples);
5018 		if (e) return e;
5019 	}
5020 	if (ptr->sampleGroups) {
5021 		e = gf_isom_box_array_size(s, ptr->sampleGroups);
5022 		if (e) return e;
5023 	}
5024 	if (ptr->sampleGroupsDescription) {
5025 		e = gf_isom_box_array_size(s, ptr->sampleGroupsDescription);
5026 		if (e) return e;
5027 	}
5028 	if (ptr->sai_sizes) {
5029 		e = gf_isom_box_array_size(s, ptr->sai_sizes);
5030 		if (e) return e;
5031 	}
5032 	if (ptr->sai_offsets) {
5033 		e = gf_isom_box_array_size(s, ptr->sai_offsets);
5034 		if (e) return e;
5035 	}
5036 	return GF_OK;
5037 }
5038 
5039 #endif /*GPAC_DISABLE_ISOM_WRITE*/
5040 
5041 
stco_del(GF_Box * s)5042 void stco_del(GF_Box *s)
5043 {
5044 	GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
5045 	if (ptr == NULL) return;
5046 	if (ptr->offsets) gf_free(ptr->offsets);
5047 	gf_free(ptr);
5048 }
5049 
5050 
stco_Read(GF_Box * s,GF_BitStream * bs)5051 GF_Err stco_Read(GF_Box *s, GF_BitStream *bs)
5052 {
5053 	GF_Err e;
5054 	u32 entries;
5055 	GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
5056 
5057 	e = gf_isom_full_box_read(s, bs);
5058 	if (e) return e;
5059 	ptr->nb_entries = gf_bs_read_u32(bs);
5060 
5061 	if (ptr->nb_entries) {
5062 		ptr->offsets = (u32 *)gf_malloc(ptr->nb_entries * sizeof(u32));
5063 		if (ptr->offsets == NULL) return GF_OUT_OF_MEM;
5064 		ptr->alloc_size = ptr->nb_entries;
5065 
5066 		for (entries = 0; entries < ptr->nb_entries; entries++) {
5067 			ptr->offsets[entries] = gf_bs_read_u32(bs);
5068 		}
5069 	}
5070 	return GF_OK;
5071 }
5072 
stco_New()5073 GF_Box *stco_New()
5074 {
5075 	ISOM_DECL_BOX_ALLOC(GF_ChunkOffsetBox, GF_ISOM_BOX_TYPE_STCO);
5076 	gf_isom_full_box_init((GF_Box *)tmp);
5077 	return (GF_Box *)tmp;
5078 }
5079 
5080 
5081 
5082 #ifndef GPAC_DISABLE_ISOM_WRITE
5083 
stco_Write(GF_Box * s,GF_BitStream * bs)5084 GF_Err stco_Write(GF_Box *s, GF_BitStream *bs)
5085 {
5086 	GF_Err e;
5087 	u32 i;
5088 	GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
5089 	e = gf_isom_full_box_write(s, bs);
5090 	if (e) return e;
5091 	gf_bs_write_u32(bs, ptr->nb_entries);
5092 	for (i = 0; i < ptr->nb_entries; i++) {
5093 		gf_bs_write_u32(bs, ptr->offsets[i]);
5094 	}
5095 	return GF_OK;
5096 }
5097 
5098 
stco_Size(GF_Box * s)5099 GF_Err stco_Size(GF_Box *s)
5100 {
5101 	GF_Err e;
5102 	GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
5103 	e = gf_isom_full_box_get_size(s);
5104 	if (e) return e;
5105 	ptr->size += 4 + (4 * ptr->nb_entries);
5106 	return GF_OK;
5107 }
5108 
5109 #endif /*GPAC_DISABLE_ISOM_WRITE*/
5110 
5111 
5112 
stdp_del(GF_Box * s)5113 void stdp_del(GF_Box *s)
5114 {
5115 	GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
5116 	if (ptr == NULL) return;
5117 	if (ptr->priorities) gf_free(ptr->priorities);
5118 	gf_free(ptr);
5119 }
5120 
5121 //this is called through stbl_read...
stdp_Read(GF_Box * s,GF_BitStream * bs)5122 GF_Err stdp_Read(GF_Box *s, GF_BitStream *bs)
5123 {
5124 	GF_Err e;
5125 	u32 entry;
5126 	GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
5127 
5128 	e = gf_isom_full_box_read(s, bs);
5129 	if (e) return e;
5130 	/*out-of-order stdp, assume no padding at the end and take the entire remaining data for entries*/
5131 	if (!ptr->nb_entries) ptr->nb_entries = (u32)ptr->size / 2;
5132 
5133 	ptr->priorities = (u16 *)gf_malloc(ptr->nb_entries * sizeof(u16));
5134 	if (ptr->priorities == NULL) return GF_OUT_OF_MEM;
5135 	for (entry = 0; entry < ptr->nb_entries; entry++) {
5136 		ptr->priorities[entry] = gf_bs_read_u16(bs);
5137 	}
5138 	ptr->size -= 2 * ptr->nb_entries;
5139 	return GF_OK;
5140 }
5141 
stdp_New()5142 GF_Box *stdp_New()
5143 {
5144 	ISOM_DECL_BOX_ALLOC(GF_DegradationPriorityBox, GF_ISOM_BOX_TYPE_STDP);
5145 	gf_isom_full_box_init((GF_Box *)tmp);
5146 	return (GF_Box *)tmp;
5147 }
5148 
5149 
5150 #ifndef GPAC_DISABLE_ISOM_WRITE
5151 
stdp_Write(GF_Box * s,GF_BitStream * bs)5152 GF_Err stdp_Write(GF_Box *s, GF_BitStream *bs)
5153 {
5154 	GF_Err e;
5155 	u32 i;
5156 	GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
5157 	e = gf_isom_full_box_write(s, bs);
5158 	if (e) return e;
5159 
5160 	for (i = 0; i < ptr->nb_entries; i++) {
5161 		gf_bs_write_u16(bs, ptr->priorities[i]);
5162 	}
5163 	return GF_OK;
5164 }
5165 
stdp_Size(GF_Box * s)5166 GF_Err stdp_Size(GF_Box *s)
5167 {
5168 	GF_Err e;
5169 	GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
5170 	e = gf_isom_full_box_get_size(s);
5171 	if (e) return e;
5172 	ptr->size += (2 * ptr->nb_entries);
5173 	return GF_OK;
5174 }
5175 
5176 #endif /*GPAC_DISABLE_ISOM_WRITE*/
5177 
5178 
stsc_del(GF_Box * s)5179 void stsc_del(GF_Box *s)
5180 {
5181 	GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
5182 	if (ptr == NULL) return;
5183 	if (ptr->entries) gf_free(ptr->entries);
5184 	gf_free(ptr);
5185 }
5186 
5187 
stsc_Read(GF_Box * s,GF_BitStream * bs)5188 GF_Err stsc_Read(GF_Box *s, GF_BitStream *bs)
5189 {
5190 	GF_Err e;
5191 	u32 i;
5192 	GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
5193 
5194 	e = gf_isom_full_box_read(s, bs);
5195 	if (e) return e;
5196 	ptr->nb_entries = gf_bs_read_u32(bs);
5197 	ptr->alloc_size = ptr->nb_entries;
5198 	ptr->entries = gf_malloc(sizeof(GF_StscEntry)*ptr->alloc_size);
5199 	if (!ptr->entries) return GF_OUT_OF_MEM;
5200 
5201 	for (i = 0; i < ptr->nb_entries; i++) {
5202 		ptr->entries[i].firstChunk = gf_bs_read_u32(bs);
5203 		ptr->entries[i].samplesPerChunk = gf_bs_read_u32(bs);
5204 		ptr->entries[i].sampleDescriptionIndex = gf_bs_read_u32(bs);
5205 		ptr->entries[i].isEdited = 0;
5206 		ptr->entries[i].nextChunk = 0;
5207 
5208 		//update the next chunk in the previous entry
5209 		if (i) ptr->entries[i - 1].nextChunk = ptr->entries[i].firstChunk;
5210 	}
5211 	ptr->currentIndex = 0;
5212 	ptr->firstSampleInCurrentChunk = 0;
5213 	ptr->currentChunk = 0;
5214 	ptr->ghostNumber = 0;
5215 	return GF_OK;
5216 }
5217 
stsc_New()5218 GF_Box *stsc_New()
5219 {
5220 	ISOM_DECL_BOX_ALLOC(GF_SampleToChunkBox, GF_ISOM_BOX_TYPE_STSC);
5221 	gf_isom_full_box_init((GF_Box *)tmp);
5222 	return (GF_Box *)tmp;
5223 }
5224 
5225 
5226 #ifndef GPAC_DISABLE_ISOM_WRITE
5227 
stsc_Write(GF_Box * s,GF_BitStream * bs)5228 GF_Err stsc_Write(GF_Box *s, GF_BitStream *bs)
5229 {
5230 	GF_Err e;
5231 	u32 i;
5232 	GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
5233 
5234 	e = gf_isom_full_box_write(s, bs);
5235 	if (e) return e;
5236 	gf_bs_write_u32(bs, ptr->nb_entries);
5237 	for (i = 0; i<ptr->nb_entries; i++) {
5238 		gf_bs_write_u32(bs, ptr->entries[i].firstChunk);
5239 		gf_bs_write_u32(bs, ptr->entries[i].samplesPerChunk);
5240 		gf_bs_write_u32(bs, ptr->entries[i].sampleDescriptionIndex);
5241 	}
5242 	return GF_OK;
5243 }
5244 
stsc_Size(GF_Box * s)5245 GF_Err stsc_Size(GF_Box *s)
5246 {
5247 	GF_Err e;
5248 	GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
5249 	e = gf_isom_full_box_get_size(s);
5250 	if (e) return e;
5251 	ptr->size += 4 + (12 * ptr->nb_entries);
5252 	return GF_OK;
5253 }
5254 
5255 #endif /*GPAC_DISABLE_ISOM_WRITE*/
5256 
stsd_del(GF_Box * s)5257 void stsd_del(GF_Box *s)
5258 {
5259 	GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
5260 	if (ptr == NULL) return;
5261 	gf_free(ptr);
5262 }
5263 
stsd_AddBox(GF_SampleDescriptionBox * ptr,GF_Box * a)5264 GF_Err stsd_AddBox(GF_SampleDescriptionBox *ptr, GF_Box *a)
5265 {
5266 	GF_UnknownBox *def;
5267 	if (!a) return GF_OK;
5268 
5269 	switch (a->type) {
5270 	case GF_ISOM_BOX_TYPE_MP4S:
5271 	case GF_ISOM_BOX_TYPE_ENCS:
5272 	case GF_ISOM_BOX_TYPE_MP4A:
5273 	case GF_ISOM_BOX_TYPE_ENCA:
5274 	case GF_ISOM_BOX_TYPE_MP4V:
5275 	case GF_ISOM_BOX_TYPE_ENCV:
5276 	case GF_ISOM_BOX_TYPE_GHNT:
5277 	case GF_ISOM_BOX_TYPE_RTP_STSD:
5278 	case GF_ISOM_BOX_TYPE_AVC1:
5279 	case GF_ISOM_BOX_TYPE_AVC2:
5280 	case GF_ISOM_BOX_TYPE_AVC3:
5281 	case GF_ISOM_BOX_TYPE_AVC4:
5282 	case GF_ISOM_BOX_TYPE_SVC1:
5283 	case GF_ISOM_BOX_TYPE_HVC1:
5284 	case GF_ISOM_BOX_TYPE_HEV1:
5285 	case GF_ISOM_BOX_TYPE_HVC2:
5286 	case GF_ISOM_BOX_TYPE_HEV2:
5287 	case GF_ISOM_BOX_TYPE_HVT1:
5288 	case GF_ISOM_BOX_TYPE_LHV1:
5289 	case GF_ISOM_BOX_TYPE_LHE1:
5290 	case GF_ISOM_BOX_TYPE_TX3G:
5291 	case GF_ISOM_BOX_TYPE_TEXT:
5292 	case GF_ISOM_BOX_TYPE_ENCT:
5293 	case GF_ISOM_BOX_TYPE_METX:
5294 	case GF_ISOM_BOX_TYPE_METT:
5295 	case GF_ISOM_BOX_TYPE_STXT:
5296 	case GF_ISOM_BOX_TYPE_DIMS:
5297 	case GF_ISOM_BOX_TYPE_AC3:
5298 	case GF_ISOM_BOX_TYPE_LSR1:
5299 	case GF_ISOM_BOX_TYPE_WVTT:
5300 	case GF_ISOM_BOX_TYPE_STPP:
5301 	case GF_ISOM_BOX_TYPE_SBTT:
5302 	case GF_ISOM_BOX_TYPE_ELNG:
5303 	case GF_ISOM_BOX_TYPE_MP3:
5304 		return gf_isom_box_add_default((GF_Box*)ptr, a);
5305 		/*for 3GP config, we must set the type*/
5306 	case GF_ISOM_SUBTYPE_3GP_AMR:
5307 	case GF_ISOM_SUBTYPE_3GP_AMR_WB:
5308 	case GF_ISOM_SUBTYPE_3GP_EVRC:
5309 	case GF_ISOM_SUBTYPE_3GP_QCELP:
5310 	case GF_ISOM_SUBTYPE_3GP_SMV:
5311 	{
5312 		((GF_3GPPAudioSampleEntryBox *)a)->info->cfg.type = a->type;
5313 		return gf_isom_box_add_default((GF_Box*)ptr, a);
5314 	}
5315 	case GF_ISOM_SUBTYPE_3GP_H263:
5316 	{
5317 		((GF_3GPPVisualSampleEntryBox *)a)->info->cfg.type = a->type;
5318 		return gf_isom_box_add_default((GF_Box*)ptr, a);
5319 	}
5320 
5321 	//unknown sample description: we need a specific box to handle the data ref index
5322 	//rather than a default box ...
5323 	default:
5324 		def = (GF_UnknownBox *)a;
5325 		/*we need at least 8 bytes for unknown sample entries*/
5326 		if (def->dataSize < 8) {
5327 			gf_isom_box_del(a);
5328 			return GF_OK;
5329 		}
5330 		return gf_isom_box_add_default((GF_Box*)ptr, a);
5331 	}
5332 }
5333 
5334 
stsd_Read(GF_Box * s,GF_BitStream * bs)5335 GF_Err stsd_Read(GF_Box *s, GF_BitStream *bs)
5336 {
5337 	GF_Err e;
5338 	u32 nb_entries;
5339 	u32 i;
5340 	GF_Box *a;
5341 	GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
5342 
5343 	e = gf_isom_full_box_read(s, bs);
5344 	if (e) return e;
5345 	nb_entries = gf_bs_read_u32(bs);
5346 	for (i = 0; i < nb_entries; i++) {
5347 		e = gf_isom_parse_box(&a, bs);
5348 		if (e) return e;
5349 		e = stsd_AddBox(ptr, a);
5350 		if (e) return e;
5351 	}
5352 	return GF_OK;
5353 }
5354 
stsd_New()5355 GF_Box *stsd_New()
5356 {
5357 	ISOM_DECL_BOX_ALLOC(GF_SampleDescriptionBox, GF_ISOM_BOX_TYPE_STSD);
5358 	gf_isom_full_box_init((GF_Box *)tmp);
5359 	tmp->other_boxes = gf_list_new();
5360 	return (GF_Box *)tmp;
5361 }
5362 
5363 
5364 #ifndef GPAC_DISABLE_ISOM_WRITE
5365 
stsd_Write(GF_Box * s,GF_BitStream * bs)5366 GF_Err stsd_Write(GF_Box *s, GF_BitStream *bs)
5367 {
5368 	GF_Err e;
5369 	u32 nb_entries;
5370 	GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
5371 
5372 	e = gf_isom_full_box_write(s, bs);
5373 	if (e) return e;
5374 	nb_entries = gf_list_count(ptr->other_boxes);
5375 	gf_bs_write_u32(bs, nb_entries);
5376 	return GF_OK;
5377 }
5378 
stsd_Size(GF_Box * s)5379 GF_Err stsd_Size(GF_Box *s)
5380 {
5381 	GF_Err e;
5382 	GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
5383 	e = gf_isom_full_box_get_size(s);
5384 	if (e) return e;
5385 	ptr->size += 4;
5386 	return GF_OK;
5387 }
5388 
5389 #endif /*GPAC_DISABLE_ISOM_WRITE*/
5390 
stsf_del(GF_Box * s)5391 void stsf_del(GF_Box *s)
5392 {
5393 	u32 nb_entries;
5394 	u32 i;
5395 	GF_StsfEntry *pe;
5396 	GF_SampleFragmentBox *ptr = (GF_SampleFragmentBox *)s;
5397 	if (ptr == NULL) return;
5398 
5399 	if (ptr->entryList) {
5400 		nb_entries = gf_list_count(ptr->entryList);
5401 		for (i = 0; i < nb_entries; i++) {
5402 			pe = (GF_StsfEntry*)gf_list_get(ptr->entryList, i);
5403 			if (pe->fragmentSizes) gf_free(pe->fragmentSizes);
5404 			gf_free(pe);
5405 		}
5406 		gf_list_del(ptr->entryList);
5407 	}
5408 	gf_free(ptr);
5409 }
5410 
5411 
5412 
stsf_Read(GF_Box * s,GF_BitStream * bs)5413 GF_Err stsf_Read(GF_Box *s, GF_BitStream *bs)
5414 {
5415 	GF_Err e;
5416 	u32 entries, i;
5417 	u32 nb_entries;
5418 	GF_StsfEntry *p;
5419 	GF_SampleFragmentBox *ptr = (GF_SampleFragmentBox *)s;
5420 
5421 	p = NULL;
5422 	if (!ptr) return GF_BAD_PARAM;
5423 	e = gf_isom_full_box_read(s, bs);
5424 	if (e) return e;
5425 	nb_entries = gf_bs_read_u32(bs);
5426 
5427 	p = NULL;
5428 	for (entries = 0; entries < nb_entries; entries++) {
5429 		p = (GF_StsfEntry *)gf_malloc(sizeof(GF_StsfEntry));
5430 		if (!p) return GF_OUT_OF_MEM;
5431 		p->SampleNumber = gf_bs_read_u32(bs);
5432 		p->fragmentCount = gf_bs_read_u32(bs);
5433 		p->fragmentSizes = (u16*)gf_malloc(sizeof(GF_StsfEntry) * p->fragmentCount);
5434 		for (i = 0; i<p->fragmentCount; i++) {
5435 			p->fragmentSizes[i] = gf_bs_read_u16(bs);
5436 		}
5437 		gf_list_add(ptr->entryList, p);
5438 	}
5439 #ifndef GPAC_DISABLE_ISOM_WRITE
5440 	ptr->w_currentEntry = p;
5441 	ptr->w_currentEntryIndex = nb_entries - 1;
5442 #endif
5443 	return GF_OK;
5444 }
5445 
stsf_New()5446 GF_Box *stsf_New()
5447 {
5448 	ISOM_DECL_BOX_ALLOC(GF_SampleFragmentBox, GF_ISOM_BOX_TYPE_STSF);
5449 
5450 	gf_isom_full_box_init((GF_Box *)tmp);
5451 	tmp->entryList = gf_list_new();
5452 	if (!tmp->entryList) {
5453 		gf_free(tmp);
5454 		return NULL;
5455 	}
5456 	return (GF_Box *)tmp;
5457 }
5458 
5459 
5460 
5461 
5462 #ifndef GPAC_DISABLE_ISOM_WRITE
5463 
stsf_Write(GF_Box * s,GF_BitStream * bs)5464 GF_Err stsf_Write(GF_Box *s, GF_BitStream *bs)
5465 {
5466 	GF_Err e;
5467 	u32 i, j;
5468 	u32 nb_entries;
5469 	GF_StsfEntry *p;
5470 	GF_SampleFragmentBox *ptr = (GF_SampleFragmentBox *)s;
5471 
5472 	e = gf_isom_full_box_write(s, bs);
5473 	if (e) return e;
5474 	nb_entries = gf_list_count(ptr->entryList);
5475 	gf_bs_write_u32(bs, nb_entries);
5476 	for (i = 0; i < nb_entries; i++) {
5477 		p = (GF_StsfEntry*)gf_list_get(ptr->entryList, i);
5478 		gf_bs_write_u32(bs, p->SampleNumber);
5479 		gf_bs_write_u32(bs, p->fragmentCount);
5480 		for (j = 0; j<p->fragmentCount; j++) {
5481 			gf_bs_write_u16(bs, p->fragmentSizes[j]);
5482 		}
5483 	}
5484 	return GF_OK;
5485 }
5486 
stsf_Size(GF_Box * s)5487 GF_Err stsf_Size(GF_Box *s)
5488 {
5489 	GF_Err e;
5490 	GF_StsfEntry *p;
5491 	u32 nb_entries, i;
5492 	GF_SampleFragmentBox *ptr = (GF_SampleFragmentBox *)s;
5493 
5494 	e = gf_isom_full_box_get_size(s);
5495 	if (e) return e;
5496 	nb_entries = gf_list_count(ptr->entryList);
5497 	ptr->size += 4;
5498 	for (i = 0; i<nb_entries; i++) {
5499 		p = (GF_StsfEntry *)gf_list_get(ptr->entryList, i);
5500 		ptr->size += 8 + 2 * p->fragmentCount;
5501 	}
5502 	return GF_OK;
5503 }
5504 
5505 #endif /*GPAC_DISABLE_ISOM_WRITE*/
5506 
stsh_del(GF_Box * s)5507 void stsh_del(GF_Box *s)
5508 {
5509 	u32 i = 0;
5510 	GF_StshEntry *ent;
5511 	GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
5512 	if (ptr == NULL) return;
5513 	while ((ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i))) {
5514 		gf_free(ent);
5515 	}
5516 	gf_list_del(ptr->entries);
5517 	gf_free(ptr);
5518 }
5519 
5520 
5521 
stsh_Read(GF_Box * s,GF_BitStream * bs)5522 GF_Err stsh_Read(GF_Box *s, GF_BitStream *bs)
5523 {
5524 	GF_Err e;
5525 	u32 count, i;
5526 	GF_StshEntry *ent;
5527 	GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
5528 
5529 	e = gf_isom_full_box_read(s, bs);
5530 	if (e) return e;
5531 	count = gf_bs_read_u32(bs);
5532 
5533 	for (i = 0; i < count; i++) {
5534 		ent = (GF_StshEntry *)gf_malloc(sizeof(GF_StshEntry));
5535 		if (!ent) return GF_OUT_OF_MEM;
5536 		ent->shadowedSampleNumber = gf_bs_read_u32(bs);
5537 		ent->syncSampleNumber = gf_bs_read_u32(bs);
5538 		e = gf_list_add(ptr->entries, ent);
5539 		if (e) return e;
5540 	}
5541 	return GF_OK;
5542 }
5543 
stsh_New()5544 GF_Box *stsh_New()
5545 {
5546 	ISOM_DECL_BOX_ALLOC(GF_ShadowSyncBox, GF_ISOM_BOX_TYPE_STSH);
5547 	gf_isom_full_box_init((GF_Box *)tmp);
5548 	tmp->entries = gf_list_new();
5549 	if (!tmp->entries) {
5550 		gf_free(tmp);
5551 		return NULL;
5552 	}
5553 	return (GF_Box *)tmp;
5554 }
5555 
5556 
5557 #ifndef GPAC_DISABLE_ISOM_WRITE
5558 
stsh_Write(GF_Box * s,GF_BitStream * bs)5559 GF_Err stsh_Write(GF_Box *s, GF_BitStream *bs)
5560 {
5561 	GF_Err e;
5562 	u32 i;
5563 	GF_StshEntry *ent;
5564 	GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
5565 
5566 	e = gf_isom_full_box_write(s, bs);
5567 	if (e) return e;
5568 	gf_bs_write_u32(bs, gf_list_count(ptr->entries));
5569 	i = 0;
5570 	while ((ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i))) {
5571 		gf_bs_write_u32(bs, ent->shadowedSampleNumber);
5572 		gf_bs_write_u32(bs, ent->syncSampleNumber);
5573 	}
5574 	return GF_OK;
5575 }
5576 
stsh_Size(GF_Box * s)5577 GF_Err stsh_Size(GF_Box *s)
5578 {
5579 	GF_Err e;
5580 	GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
5581 	e = gf_isom_full_box_get_size(s);
5582 	if (e) return e;
5583 	ptr->size += 4 + (8 * gf_list_count(ptr->entries));
5584 	return GF_OK;
5585 }
5586 
5587 #endif /*GPAC_DISABLE_ISOM_WRITE*/
5588 
5589 
5590 
stss_del(GF_Box * s)5591 void stss_del(GF_Box *s)
5592 {
5593 	GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
5594 	if (ptr == NULL) return;
5595 	if (ptr->sampleNumbers) gf_free(ptr->sampleNumbers);
5596 	gf_free(ptr);
5597 }
5598 
stss_Read(GF_Box * s,GF_BitStream * bs)5599 GF_Err stss_Read(GF_Box *s, GF_BitStream *bs)
5600 {
5601 	GF_Err e;
5602 	u32 i;
5603 	GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
5604 
5605 	e = gf_isom_full_box_read(s, bs);
5606 	if (e) return e;
5607 	ptr->nb_entries = gf_bs_read_u32(bs);
5608 	ptr->alloc_size = ptr->nb_entries;
5609 	ptr->sampleNumbers = (u32 *)gf_malloc(ptr->alloc_size * sizeof(u32));
5610 	if (ptr->sampleNumbers == NULL) return GF_OUT_OF_MEM;
5611 
5612 	for (i = 0; i < ptr->nb_entries; i++) {
5613 		ptr->sampleNumbers[i] = gf_bs_read_u32(bs);
5614 	}
5615 	return GF_OK;
5616 }
5617 
stss_New()5618 GF_Box *stss_New()
5619 {
5620 	ISOM_DECL_BOX_ALLOC(GF_SyncSampleBox, GF_ISOM_BOX_TYPE_STSS);
5621 	gf_isom_full_box_init((GF_Box *)tmp);
5622 	return (GF_Box*)tmp;
5623 }
5624 
5625 
5626 #ifndef GPAC_DISABLE_ISOM_WRITE
5627 
stss_Write(GF_Box * s,GF_BitStream * bs)5628 GF_Err stss_Write(GF_Box *s, GF_BitStream *bs)
5629 {
5630 	GF_Err e;
5631 	u32 i;
5632 	GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
5633 
5634 	e = gf_isom_full_box_write(s, bs);
5635 	if (e) return e;
5636 	gf_bs_write_u32(bs, ptr->nb_entries);
5637 	for (i = 0; i < ptr->nb_entries; i++) {
5638 		gf_bs_write_u32(bs, ptr->sampleNumbers[i]);
5639 	}
5640 	return GF_OK;
5641 }
5642 
stss_Size(GF_Box * s)5643 GF_Err stss_Size(GF_Box *s)
5644 {
5645 	GF_Err e;
5646 	GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
5647 	e = gf_isom_full_box_get_size(s);
5648 	if (e) return e;
5649 	ptr->size += 4 + (4 * ptr->nb_entries);
5650 	return GF_OK;
5651 }
5652 
5653 #endif /*GPAC_DISABLE_ISOM_WRITE*/
5654 
5655 
stsz_del(GF_Box * s)5656 void stsz_del(GF_Box *s)
5657 {
5658 	GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
5659 	if (ptr == NULL) return;
5660 	if (ptr->sizes) gf_free(ptr->sizes);
5661 	gf_free(ptr);
5662 }
5663 
5664 
stsz_Read(GF_Box * s,GF_BitStream * bs)5665 GF_Err stsz_Read(GF_Box *s, GF_BitStream *bs)
5666 {
5667 	GF_Err e;
5668 	u32 i, estSize;
5669 	GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
5670 	if (ptr == NULL) return GF_BAD_PARAM;
5671 
5672 	e = gf_isom_full_box_read(s, bs);
5673 	if (e) return e;
5674 	//support for CompactSizes
5675 	if (s->type == GF_ISOM_BOX_TYPE_STSZ) {
5676 		ptr->sampleSize = gf_bs_read_u32(bs);
5677 		ptr->sampleCount = gf_bs_read_u32(bs);
5678 		ptr->size -= 8;
5679 	}
5680 	else {
5681 		//24-reserved
5682 		gf_bs_read_int(bs, 24);
5683 		i = gf_bs_read_u8(bs);
5684 		ptr->sampleCount = gf_bs_read_u32(bs);
5685 		ptr->size -= 8;
5686 		switch (i) {
5687 		case 4:
5688 		case 8:
5689 		case 16:
5690 			ptr->sampleSize = i;
5691 			break;
5692 		default:
5693 			//try to fix the file
5694 			//no samples, no parsing pb
5695 			if (!ptr->sampleCount) {
5696 				ptr->sampleSize = 16;
5697 				return GF_OK;
5698 			}
5699 			estSize = (u32)(ptr->size) / ptr->sampleCount;
5700 			if (!estSize && ((ptr->sampleCount + 1) / 2 == (ptr->size))) {
5701 				ptr->sampleSize = 4;
5702 				break;
5703 			}
5704 			else if (estSize == 1 || estSize == 2) {
5705 				ptr->sampleSize = 8 * estSize;
5706 			}
5707 			else {
5708 				return GF_ISOM_INVALID_FILE;
5709 			}
5710 		}
5711 	}
5712 	if (s->type == GF_ISOM_BOX_TYPE_STSZ) {
5713 		if (!ptr->sampleSize && ptr->sampleCount) {
5714 			ptr->sizes = (u32 *)gf_malloc(ptr->sampleCount * sizeof(u32));
5715 			ptr->alloc_size = ptr->sampleCount;
5716 			if (!ptr->sizes) return GF_OUT_OF_MEM;
5717 			for (i = 0; i < ptr->sampleCount; i++) {
5718 				ptr->sizes[i] = gf_bs_read_u32(bs);
5719 			}
5720 		}
5721 	}
5722 	else {
5723 		//note we could optimize the mem usage by keeping the table compact
5724 		//in memory. But that would complicate both caching and editing
5725 		//we therefore keep all sizes as u32 and uncompress the table
5726 		ptr->sizes = (u32 *)gf_malloc(ptr->sampleCount * sizeof(u32));
5727 		if (!ptr->sizes) return GF_OUT_OF_MEM;
5728 		ptr->alloc_size = ptr->sampleCount;
5729 
5730 		for (i = 0; i < ptr->sampleCount; ) {
5731 			switch (ptr->sampleSize) {
5732 			case 4:
5733 				ptr->sizes[i] = gf_bs_read_int(bs, 4);
5734 				if (i + 1 < ptr->sampleCount) {
5735 					ptr->sizes[i + 1] = gf_bs_read_int(bs, 4);
5736 				}
5737 				else {
5738 					//0 padding in odd sample count
5739 					gf_bs_read_int(bs, 4);
5740 				}
5741 				i += 2;
5742 				break;
5743 			default:
5744 				ptr->sizes[i] = gf_bs_read_int(bs, ptr->sampleSize);
5745 				i += 1;
5746 				break;
5747 			}
5748 		}
5749 	}
5750 	return GF_OK;
5751 }
5752 
stsz_New()5753 GF_Box *stsz_New()
5754 {
5755 	ISOM_DECL_BOX_ALLOC(GF_SampleSizeBox, 0);
5756 
5757 	gf_isom_full_box_init((GF_Box *)tmp);
5758 	//type is unknown here, can be regular or compact table
5759 	return (GF_Box *)tmp;
5760 }
5761 
5762 
5763 #ifndef GPAC_DISABLE_ISOM_WRITE
5764 
stsz_Write(GF_Box * s,GF_BitStream * bs)5765 GF_Err stsz_Write(GF_Box *s, GF_BitStream *bs)
5766 {
5767 	GF_Err e;
5768 	u32 i;
5769 	GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
5770 
5771 	e = gf_isom_full_box_write(s, bs);
5772 	if (e) return e;
5773 	//in both versions this is still valid
5774 	if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
5775 		gf_bs_write_u32(bs, ptr->sampleSize);
5776 	}
5777 	else {
5778 		gf_bs_write_u24(bs, 0);
5779 		gf_bs_write_u8(bs, ptr->sampleSize);
5780 	}
5781 	gf_bs_write_u32(bs, ptr->sampleCount);
5782 
5783 	if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
5784 		if (!ptr->sampleSize) {
5785 			for (i = 0; i < ptr->sampleCount; i++) {
5786 				gf_bs_write_u32(bs, ptr->sizes ? ptr->sizes[i] : 0);
5787 			}
5788 		}
5789 	}
5790 	else {
5791 		for (i = 0; i < ptr->sampleCount; ) {
5792 			switch (ptr->sampleSize) {
5793 			case 4:
5794 				gf_bs_write_int(bs, ptr->sizes[i], 4);
5795 				if (i + 1 < ptr->sampleCount) {
5796 					gf_bs_write_int(bs, ptr->sizes[i + 1], 4);
5797 				}
5798 				else {
5799 					//0 padding in odd sample count
5800 					gf_bs_write_int(bs, 0, 4);
5801 				}
5802 				i += 2;
5803 				break;
5804 			default:
5805 				gf_bs_write_int(bs, ptr->sizes[i], ptr->sampleSize);
5806 				i += 1;
5807 				break;
5808 			}
5809 		}
5810 	}
5811 	return GF_OK;
5812 }
5813 
stsz_Size(GF_Box * s)5814 GF_Err stsz_Size(GF_Box *s)
5815 {
5816 	GF_Err e;
5817 	u32 i, fieldSize, size;
5818 	GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
5819 	e = gf_isom_full_box_get_size(s);
5820 	if (e) return e;
5821 
5822 	ptr->size += 8;
5823 	if (!ptr->sampleCount) return GF_OK;
5824 
5825 	//regular table
5826 	if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
5827 		if (ptr->sampleSize) return GF_OK;
5828 		ptr->size += (4 * ptr->sampleCount);
5829 		return GF_OK;
5830 	}
5831 
5832 	fieldSize = 4;
5833 	size = ptr->sizes[0];
5834 
5835 	for (i = 0; i < ptr->sampleCount; i++) {
5836 		if (ptr->sizes[i] <= 0xF) continue;
5837 		//switch to 8-bit table
5838 		else if (ptr->sizes[i] <= 0xFF) {
5839 			fieldSize = 8;
5840 		}
5841 		//switch to 16-bit table
5842 		else if (ptr->sizes[i] <= 0xFFFF) {
5843 			fieldSize = 16;
5844 		}
5845 		//switch to 32-bit table
5846 		else {
5847 			fieldSize = 32;
5848 		}
5849 
5850 		//check the size
5851 		if (size != ptr->sizes[i]) size = 0;
5852 	}
5853 	//if all samples are of the same size, switch to regular (more compact)
5854 	if (size) {
5855 		ptr->type = GF_ISOM_BOX_TYPE_STSZ;
5856 		ptr->sampleSize = size;
5857 		gf_free(ptr->sizes);
5858 		ptr->sizes = NULL;
5859 	}
5860 
5861 	if (fieldSize == 32) {
5862 		//oops, doesn't fit in a compact table
5863 		ptr->type = GF_ISOM_BOX_TYPE_STSZ;
5864 		ptr->size += (4 * ptr->sampleCount);
5865 		return GF_OK;
5866 	}
5867 
5868 	//make sure we are a compact table (no need to change the mem representation)
5869 	ptr->type = GF_ISOM_BOX_TYPE_STZ2;
5870 	ptr->sampleSize = fieldSize;
5871 	if (fieldSize == 4) {
5872 		//do not forget the 0 padding field for odd count
5873 		ptr->size += (ptr->sampleCount + 1) / 2;
5874 	}
5875 	else {
5876 		ptr->size += (ptr->sampleCount) * (fieldSize / 8);
5877 	}
5878 	return GF_OK;
5879 }
5880 
5881 #endif /*GPAC_DISABLE_ISOM_WRITE*/
5882 
5883 
stts_del(GF_Box * s)5884 void stts_del(GF_Box *s)
5885 {
5886 	GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
5887 	if (ptr->entries) gf_free(ptr->entries);
5888 	gf_free(ptr);
5889 }
5890 
5891 
stts_Read(GF_Box * s,GF_BitStream * bs)5892 GF_Err stts_Read(GF_Box *s, GF_BitStream *bs)
5893 {
5894 	GF_Err e;
5895 	u32 i;
5896 	GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
5897 
5898 	e = gf_isom_full_box_read(s, bs);
5899 	if (e) return e;
5900 
5901 #ifndef GPAC_DISABLE_ISOM_WRITE
5902 	ptr->w_LastDTS = 0;
5903 #endif
5904 	ptr->nb_entries = gf_bs_read_u32(bs);
5905 	ptr->alloc_size = ptr->nb_entries;
5906 	ptr->entries = gf_malloc(sizeof(GF_SttsEntry)*ptr->alloc_size);
5907 	if (!ptr->entries) return GF_OUT_OF_MEM;
5908 	for (i = 0; i<ptr->nb_entries; i++) {
5909 		ptr->entries[i].sampleCount = gf_bs_read_u32(bs);
5910 		ptr->entries[i].sampleDelta = gf_bs_read_u32(bs);
5911 #ifndef GPAC_DISABLE_ISOM_WRITE
5912 		ptr->w_currentSampleNum += ptr->entries[i].sampleCount;
5913 		ptr->w_LastDTS += ptr->entries[i].sampleCount * ptr->entries[i].sampleDelta;
5914 #endif
5915 
5916 		if (!ptr->entries[i].sampleDelta) {
5917 			if ((i + 1<ptr->nb_entries)) {
5918 				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Found stss entry with sample_delta=0 - forbidden ! Fixing to 1\n"));
5919 				ptr->entries[i].sampleDelta = 1;
5920 			}
5921 			else if (ptr->entries[i].sampleCount>1) {
5922 				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] more than one sample at the end of the track with sample_delta=0 - forbidden ! Fixing to 1\n"));
5923 				ptr->entries[i].sampleDelta = 1;
5924 			}
5925 		}
5926 		else if ((s32)ptr->entries[i].sampleDelta < 0) {
5927 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] stts entry %d has negative duration %d - forbidden ! Fixing to 1, sync may get lost (consider reimport raw media)\n", i, (s32)ptr->entries[i].sampleDelta));
5928 			ptr->entries[i].sampleDelta = 1;
5929 		}
5930 	}
5931 	//remove the last sample delta.
5932 #ifndef GPAC_DISABLE_ISOM_WRITE
5933 	if (ptr->nb_entries) ptr->w_LastDTS -= ptr->entries[ptr->nb_entries - 1].sampleDelta;
5934 #endif
5935 	return GF_OK;
5936 }
5937 
stts_New()5938 GF_Box *stts_New()
5939 {
5940 	ISOM_DECL_BOX_ALLOC(GF_TimeToSampleBox, GF_ISOM_BOX_TYPE_STTS);
5941 	gf_isom_full_box_init((GF_Box *)tmp);
5942 	return (GF_Box *)tmp;
5943 }
5944 
5945 
5946 #ifndef GPAC_DISABLE_ISOM_WRITE
5947 
stts_Write(GF_Box * s,GF_BitStream * bs)5948 GF_Err stts_Write(GF_Box *s, GF_BitStream *bs)
5949 {
5950 	GF_Err e;
5951 	u32 i;
5952 	GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
5953 
5954 	e = gf_isom_full_box_write(s, bs);
5955 	if (e) return e;
5956 	gf_bs_write_u32(bs, ptr->nb_entries);
5957 	for (i = 0; i<ptr->nb_entries; i++) {
5958 		gf_bs_write_u32(bs, ptr->entries[i].sampleCount);
5959 		gf_bs_write_u32(bs, ptr->entries[i].sampleDelta);
5960 	}
5961 	return GF_OK;
5962 }
5963 
stts_Size(GF_Box * s)5964 GF_Err stts_Size(GF_Box *s)
5965 {
5966 	GF_Err e;
5967 	GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
5968 	e = gf_isom_full_box_get_size(s);
5969 	if (e) return e;
5970 	ptr->size += 4 + (8 * ptr->nb_entries);
5971 	return GF_OK;
5972 }
5973 
5974 
5975 #endif /*GPAC_DISABLE_ISOM_WRITE*/
5976 
5977 
5978 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
5979 
tfhd_del(GF_Box * s)5980 void tfhd_del(GF_Box *s)
5981 {
5982 	GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
5983 	if (ptr == NULL) return;
5984 	gf_free(ptr);
5985 }
5986 
tfhd_Read(GF_Box * s,GF_BitStream * bs)5987 GF_Err tfhd_Read(GF_Box *s, GF_BitStream *bs)
5988 {
5989 	GF_Err e;
5990 	GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
5991 
5992 	e = gf_isom_full_box_read(s, bs);
5993 	if (e) return e;
5994 
5995 	ptr->trackID = gf_bs_read_u32(bs);
5996 
5997 	//The rest depends on the flags
5998 	if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) {
5999 		ptr->base_data_offset = gf_bs_read_u64(bs);
6000 	}
6001 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) {
6002 		ptr->sample_desc_index = gf_bs_read_u32(bs);
6003 	}
6004 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) {
6005 		ptr->def_sample_duration = gf_bs_read_u32(bs);
6006 	}
6007 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) {
6008 		ptr->def_sample_size = gf_bs_read_u32(bs);
6009 	}
6010 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) {
6011 		ptr->def_sample_flags = gf_bs_read_u32(bs);
6012 	}
6013 	return GF_OK;
6014 }
6015 
tfhd_New()6016 GF_Box *tfhd_New()
6017 {
6018 	ISOM_DECL_BOX_ALLOC(GF_TrackFragmentHeaderBox, GF_ISOM_BOX_TYPE_TFHD);
6019 	//NO FLAGS SET BY DEFAULT
6020 	return (GF_Box *)tmp;
6021 }
6022 
6023 
6024 
6025 #ifndef GPAC_DISABLE_ISOM_WRITE
6026 
6027 
tfhd_Write(GF_Box * s,GF_BitStream * bs)6028 GF_Err tfhd_Write(GF_Box *s, GF_BitStream *bs)
6029 {
6030 	GF_Err e;
6031 	GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
6032 	if (!s) return GF_BAD_PARAM;
6033 
6034 	e = gf_isom_full_box_write(s, bs);
6035 	if (e) return e;
6036 	gf_bs_write_u32(bs, ptr->trackID);
6037 
6038 	//The rest depends on the flags
6039 	if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) {
6040 		gf_bs_write_u64(bs, ptr->base_data_offset);
6041 	}
6042 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) {
6043 		gf_bs_write_u32(bs, ptr->sample_desc_index);
6044 	}
6045 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) {
6046 		gf_bs_write_u32(bs, ptr->def_sample_duration);
6047 	}
6048 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) {
6049 		gf_bs_write_u32(bs, ptr->def_sample_size);
6050 	}
6051 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) {
6052 		gf_bs_write_u32(bs, ptr->def_sample_flags);
6053 	}
6054 	return GF_OK;
6055 }
6056 
tfhd_Size(GF_Box * s)6057 GF_Err tfhd_Size(GF_Box *s)
6058 {
6059 	GF_Err e;
6060 	GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
6061 	e = gf_isom_full_box_get_size(s);
6062 	if (e) return e;
6063 	ptr->size += 4;
6064 
6065 	//The rest depends on the flags
6066 	if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) ptr->size += 8;
6067 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) ptr->size += 4;
6068 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) ptr->size += 4;
6069 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) ptr->size += 4;
6070 	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) ptr->size += 4;
6071 	return GF_OK;
6072 }
6073 
6074 #endif /*GPAC_DISABLE_ISOM_WRITE*/
6075 
6076 #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
6077 
6078 
tims_del(GF_Box * s)6079 void tims_del(GF_Box *s)
6080 {
6081 	GF_TSHintEntryBox *tims = (GF_TSHintEntryBox *)s;
6082 	gf_free(tims);
6083 }
6084 
tims_Read(GF_Box * s,GF_BitStream * bs)6085 GF_Err tims_Read(GF_Box *s, GF_BitStream *bs)
6086 {
6087 	GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s;
6088 	ptr->timeScale = gf_bs_read_u32(bs);
6089 	return GF_OK;
6090 }
6091 
tims_New()6092 GF_Box *tims_New()
6093 {
6094 	ISOM_DECL_BOX_ALLOC(GF_TSHintEntryBox, GF_ISOM_BOX_TYPE_TIMS);
6095 	return (GF_Box *)tmp;
6096 }
6097 
6098 #ifndef GPAC_DISABLE_ISOM_WRITE
6099 
tims_Write(GF_Box * s,GF_BitStream * bs)6100 GF_Err tims_Write(GF_Box *s, GF_BitStream *bs)
6101 {
6102 	GF_Err e;
6103 	GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s;
6104 	if (ptr == NULL) return GF_BAD_PARAM;
6105 	e = gf_isom_box_write_header(s, bs);
6106 	if (e) return e;
6107 	gf_bs_write_u32(bs, ptr->timeScale);
6108 	return GF_OK;
6109 }
6110 
tims_Size(GF_Box * s)6111 GF_Err tims_Size(GF_Box *s)
6112 {
6113 	GF_Err e;
6114 	e = gf_isom_box_get_size(s);
6115 	if (e) return e;
6116 	s->size += 4;
6117 	return GF_OK;
6118 }
6119 
6120 #endif /*GPAC_DISABLE_ISOM_WRITE*/
6121 
6122 
tkhd_del(GF_Box * s)6123 void tkhd_del(GF_Box *s)
6124 {
6125 	GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
6126 	if (ptr == NULL) return;
6127 	gf_free(ptr);
6128 	return;
6129 }
6130 
6131 
tkhd_Read(GF_Box * s,GF_BitStream * bs)6132 GF_Err tkhd_Read(GF_Box *s, GF_BitStream *bs)
6133 {
6134 	GF_Err e;
6135 	GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
6136 	e = gf_isom_full_box_read(s, bs);
6137 	if (e) return e;
6138 	if (ptr->version == 1) {
6139 		ptr->creationTime = gf_bs_read_u64(bs);
6140 		ptr->modificationTime = gf_bs_read_u64(bs);
6141 		ptr->trackID = gf_bs_read_u32(bs);
6142 		ptr->reserved1 = gf_bs_read_u32(bs);
6143 		ptr->duration = gf_bs_read_u64(bs);
6144 	}
6145 	else {
6146 		ptr->creationTime = gf_bs_read_u32(bs);
6147 		ptr->modificationTime = gf_bs_read_u32(bs);
6148 		ptr->trackID = gf_bs_read_u32(bs);
6149 		ptr->reserved1 = gf_bs_read_u32(bs);
6150 		ptr->duration = gf_bs_read_u32(bs);
6151 	}
6152 	ptr->reserved2[0] = gf_bs_read_u32(bs);
6153 	ptr->reserved2[1] = gf_bs_read_u32(bs);
6154 	ptr->layer = gf_bs_read_u16(bs);
6155 	ptr->alternate_group = gf_bs_read_u16(bs);
6156 	ptr->volume = gf_bs_read_u16(bs);
6157 	ptr->reserved3 = gf_bs_read_u16(bs);
6158 	ptr->matrix[0] = gf_bs_read_u32(bs);
6159 	ptr->matrix[1] = gf_bs_read_u32(bs);
6160 	ptr->matrix[2] = gf_bs_read_u32(bs);
6161 	ptr->matrix[3] = gf_bs_read_u32(bs);
6162 	ptr->matrix[4] = gf_bs_read_u32(bs);
6163 	ptr->matrix[5] = gf_bs_read_u32(bs);
6164 	ptr->matrix[6] = gf_bs_read_u32(bs);
6165 	ptr->matrix[7] = gf_bs_read_u32(bs);
6166 	ptr->matrix[8] = gf_bs_read_u32(bs);
6167 	ptr->width = gf_bs_read_u32(bs);
6168 	ptr->height = gf_bs_read_u32(bs);
6169 	return GF_OK;
6170 }
6171 
tkhd_New()6172 GF_Box *tkhd_New()
6173 {
6174 	ISOM_DECL_BOX_ALLOC(GF_TrackHeaderBox, GF_ISOM_BOX_TYPE_TKHD);
6175 	gf_isom_full_box_init((GF_Box *)tmp);
6176 	tmp->matrix[0] = 0x00010000;
6177 	tmp->matrix[4] = 0x00010000;
6178 	tmp->matrix[8] = 0x40000000;
6179 	return (GF_Box *)tmp;
6180 }
6181 
6182 
6183 
6184 #ifndef GPAC_DISABLE_ISOM_WRITE
6185 
tkhd_Write(GF_Box * s,GF_BitStream * bs)6186 GF_Err tkhd_Write(GF_Box *s, GF_BitStream *bs)
6187 {
6188 	GF_Err e;
6189 	GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
6190 
6191 	e = gf_isom_full_box_write(s, bs);
6192 	if (e) return e;
6193 	if (ptr->version == 1) {
6194 		gf_bs_write_u64(bs, ptr->creationTime);
6195 		gf_bs_write_u64(bs, ptr->modificationTime);
6196 		gf_bs_write_u32(bs, ptr->trackID);
6197 		gf_bs_write_u32(bs, ptr->reserved1);
6198 		gf_bs_write_u64(bs, ptr->duration);
6199 	}
6200 	else {
6201 		gf_bs_write_u32(bs, (u32)ptr->creationTime);
6202 		gf_bs_write_u32(bs, (u32)ptr->modificationTime);
6203 		gf_bs_write_u32(bs, ptr->trackID);
6204 		gf_bs_write_u32(bs, ptr->reserved1);
6205 		gf_bs_write_u32(bs, (u32)ptr->duration);
6206 	}
6207 	gf_bs_write_u32(bs, ptr->reserved2[0]);
6208 	gf_bs_write_u32(bs, ptr->reserved2[1]);
6209 	gf_bs_write_u16(bs, ptr->layer);
6210 	gf_bs_write_u16(bs, ptr->alternate_group);
6211 	gf_bs_write_u16(bs, ptr->volume);
6212 	gf_bs_write_u16(bs, ptr->reserved3);
6213 	gf_bs_write_u32(bs, ptr->matrix[0]);
6214 	gf_bs_write_u32(bs, ptr->matrix[1]);
6215 	gf_bs_write_u32(bs, ptr->matrix[2]);
6216 	gf_bs_write_u32(bs, ptr->matrix[3]);
6217 	gf_bs_write_u32(bs, ptr->matrix[4]);
6218 	gf_bs_write_u32(bs, ptr->matrix[5]);
6219 	gf_bs_write_u32(bs, ptr->matrix[6]);
6220 	gf_bs_write_u32(bs, ptr->matrix[7]);
6221 	gf_bs_write_u32(bs, ptr->matrix[8]);
6222 	gf_bs_write_u32(bs, ptr->width);
6223 	gf_bs_write_u32(bs, ptr->height);
6224 	return GF_OK;
6225 }
6226 
tkhd_Size(GF_Box * s)6227 GF_Err tkhd_Size(GF_Box *s)
6228 {
6229 	GF_Err e;
6230 	GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
6231 	e = gf_isom_full_box_get_size(s);
6232 	if (e) return e;
6233 	if (ptr->duration == (u64)-1) ptr->version = 0;
6234 	else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
6235 	ptr->size += (ptr->version == 1) ? 32 : 20;
6236 	ptr->size += 60;
6237 	return GF_OK;
6238 }
6239 
6240 #endif /*GPAC_DISABLE_ISOM_WRITE*/
6241 
6242 
6243 
6244 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
6245 
traf_del(GF_Box * s)6246 void traf_del(GF_Box *s)
6247 {
6248 	GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
6249 	if (ptr == NULL) return;
6250 	if (ptr->tfhd) gf_isom_box_del((GF_Box *)ptr->tfhd);
6251 	if (ptr->sdtp) gf_isom_box_del((GF_Box *)ptr->sdtp);
6252 	if (ptr->sub_samples) gf_isom_box_array_del(ptr->sub_samples);
6253 	if (ptr->tfdt) gf_isom_box_del((GF_Box *)ptr->tfdt);
6254 	if (ptr->piff_sample_encryption) gf_isom_box_del((GF_Box *)ptr->piff_sample_encryption);
6255 	if (ptr->sample_encryption) gf_isom_box_del((GF_Box *)ptr->sample_encryption);
6256 	gf_isom_box_array_del(ptr->TrackRuns);
6257 	if (ptr->sampleGroups) gf_isom_box_array_del(ptr->sampleGroups);
6258 	if (ptr->sampleGroupsDescription) gf_isom_box_array_del(ptr->sampleGroupsDescription);
6259 	if (ptr->sai_sizes) gf_isom_box_array_del(ptr->sai_sizes);
6260 	if (ptr->sai_offsets) gf_isom_box_array_del(ptr->sai_offsets);
6261 	gf_free(ptr);
6262 }
6263 
traf_AddBox(GF_Box * s,GF_Box * a)6264 GF_Err traf_AddBox(GF_Box *s, GF_Box *a)
6265 {
6266 	GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
6267 
6268 	switch (a->type) {
6269 	case GF_ISOM_BOX_TYPE_TFHD:
6270 		if (ptr->tfhd) ERROR_ON_DUPLICATED_BOX(a, ptr)
6271 			ptr->tfhd = (GF_TrackFragmentHeaderBox *)a;
6272 		return GF_OK;
6273 	case GF_ISOM_BOX_TYPE_TRUN:
6274 		return gf_list_add(ptr->TrackRuns, a);
6275 	case GF_ISOM_BOX_TYPE_SDTP:
6276 		if (ptr->sdtp) ERROR_ON_DUPLICATED_BOX(a, ptr)
6277 			ptr->sdtp = (GF_SampleDependencyTypeBox *)a;
6278 		return GF_OK;
6279 	case GF_ISOM_BOX_TYPE_TFDT:
6280 		if (ptr->tfdt) ERROR_ON_DUPLICATED_BOX(a, ptr)
6281 			ptr->tfdt = (GF_TFBaseMediaDecodeTimeBox*)a;
6282 		return GF_OK;
6283 	case GF_ISOM_BOX_TYPE_SUBS:
6284 		if (!ptr->sub_samples) ptr->sub_samples = gf_list_new();
6285 		return gf_list_add(ptr->sub_samples, a);
6286 	case GF_ISOM_BOX_TYPE_SBGP:
6287 		if (!ptr->sampleGroups) ptr->sampleGroups = gf_list_new();
6288 		gf_list_add(ptr->sampleGroups, a);
6289 		return GF_OK;
6290 	case GF_ISOM_BOX_TYPE_SGPD:
6291 		if (!ptr->sampleGroupsDescription) ptr->sampleGroupsDescription = gf_list_new();
6292 		gf_list_add(ptr->sampleGroupsDescription, a);
6293 		return GF_OK;
6294 	case GF_ISOM_BOX_TYPE_SAIZ:
6295 		if (!ptr->sai_sizes) ptr->sai_sizes = gf_list_new();
6296 		gf_list_add(ptr->sai_sizes, a);
6297 		return GF_OK;
6298 	case GF_ISOM_BOX_TYPE_SAIO:
6299 		if (!ptr->sai_offsets) ptr->sai_offsets = gf_list_new();
6300 		gf_list_add(ptr->sai_offsets, a);
6301 		return GF_OK;
6302 	case GF_ISOM_BOX_TYPE_UUID:
6303 		if (((GF_UUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC) {
6304 			if (ptr->piff_sample_encryption) ERROR_ON_DUPLICATED_BOX(a, ptr)
6305 				ptr->piff_sample_encryption = (GF_PIFFSampleEncryptionBox *)a;
6306 			ptr->piff_sample_encryption->traf = ptr;
6307 			return GF_OK;
6308 		}
6309 		else {
6310 			return gf_isom_box_add_default(s, a);
6311 		}
6312 	case GF_ISOM_BOX_TYPE_SENC:
6313 		if (ptr->sample_encryption) ERROR_ON_DUPLICATED_BOX(a, ptr)
6314 			ptr->sample_encryption = (GF_SampleEncryptionBox *)a;
6315 		ptr->sample_encryption->traf = ptr;
6316 		return GF_OK;
6317 	default:
6318 		return gf_isom_box_add_default(s, a);
6319 	}
6320 	return GF_OK;
6321 }
6322 
6323 
traf_Read(GF_Box * s,GF_BitStream * bs)6324 GF_Err traf_Read(GF_Box *s, GF_BitStream *bs)
6325 {
6326 	GF_Box *a;
6327 
6328 	GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
6329 
6330 	while (ptr->size) {
6331 		GF_Err e = gf_isom_parse_box(&a, bs);
6332 		if (e) return e;
6333 
6334 
6335 		//we need to read the DegPriority in a different way...
6336 		if ((a->type == GF_ISOM_BOX_TYPE_STDP) || (a->type == GF_ISOM_BOX_TYPE_SDTP)) {
6337 			u32 nb_samples = 0, i = 0;
6338 			u64 s = a->size;
6339 			for (i = 0; i<gf_list_count(ptr->TrackRuns); i++) {
6340 				GF_TrackFragmentRunBox *trun = gf_list_get(ptr->TrackRuns, i);
6341 				nb_samples += trun->sample_count;
6342 			}
6343 			if (a->type == GF_ISOM_BOX_TYPE_STDP) {
6344 				if (nb_samples) ((GF_DegradationPriorityBox *)a)->nb_entries = nb_samples;
6345 				e = stdp_Read(a, bs);
6346 			}
6347 			else {
6348 				if (nb_samples) ((GF_SampleDependencyTypeBox *)a)->sampleCount = nb_samples;
6349 				e = sdtp_Read(a, bs);
6350 			}
6351 			if (e) {
6352 				gf_isom_box_del(a);
6353 				return e;
6354 			}
6355 			a->size = s;
6356 		}
6357 		if (ptr->size<a->size) {
6358 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Box \"%s\" is larger than container box\n", gf_4cc_to_str(a->type)));
6359 			ptr->size = 0;
6360 		}
6361 		else {
6362 			ptr->size -= a->size;
6363 		}
6364 		e = traf_AddBox((GF_Box*)ptr, a);
6365 		if (e) return e;
6366 	}
6367 	return GF_OK;
6368 }
6369 
traf_New()6370 GF_Box *traf_New()
6371 {
6372 	ISOM_DECL_BOX_ALLOC(GF_TrackFragmentBox, GF_ISOM_BOX_TYPE_TRAF);
6373 	tmp->TrackRuns = gf_list_new();
6374 	return (GF_Box *)tmp;
6375 }
6376 
6377 
6378 #ifndef GPAC_DISABLE_ISOM_WRITE
6379 
6380 
tfxd_New()6381 GF_Box *tfxd_New()
6382 {
6383 	ISOM_DECL_BOX_ALLOC(GF_MSSTimeExtBox, GF_ISOM_BOX_TYPE_UUID);
6384 	tmp->internal_4cc = GF_ISOM_BOX_UUID_TFXD;
6385 	return (GF_Box *)tmp;
6386 }
6387 
tfxd_del(GF_Box * s)6388 void tfxd_del(GF_Box *s)
6389 {
6390 	gf_free(s);
6391 }
6392 
6393 
tfxd_Read(GF_Box * s,GF_BitStream * bs)6394 GF_Err tfxd_Read(GF_Box *s, GF_BitStream *bs)
6395 {
6396 	GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox *)s;
6397 	if (ptr->size<4) return GF_ISOM_INVALID_FILE;
6398 	ptr->version = gf_bs_read_u8(bs);
6399 	ptr->flags = gf_bs_read_u24(bs);
6400 	ptr->size -= 4;
6401 
6402 	if (ptr->version == 0x01) {
6403 		ptr->absolute_time_in_track_timescale = gf_bs_read_u64(bs);
6404 		ptr->fragment_duration_in_track_timescale = gf_bs_read_u64(bs);
6405 	}
6406 	else {
6407 		ptr->absolute_time_in_track_timescale = gf_bs_read_u32(bs);
6408 		ptr->fragment_duration_in_track_timescale = gf_bs_read_u32(bs);
6409 	}
6410 
6411 	return GF_OK;
6412 }
6413 
tfxd_Write(GF_Box * s,GF_BitStream * bs)6414 GF_Err tfxd_Write(GF_Box *s, GF_BitStream *bs)
6415 {
6416 	GF_Err e = GF_OK;
6417 	GF_MSSTimeExtBox *uuid = (GF_MSSTimeExtBox*)s;
6418 	e = gf_isom_box_write_header(s, bs);
6419 	if (e) return e;
6420 
6421 	gf_bs_write_u8(bs, 1);
6422 	gf_bs_write_u24(bs, 0);
6423 	gf_bs_write_u64(bs, uuid->absolute_time_in_track_timescale);
6424 	gf_bs_write_u64(bs, uuid->fragment_duration_in_track_timescale);
6425 
6426 	return GF_OK;
6427 }
6428 
tfxd_Size(GF_Box * s)6429 GF_Err tfxd_Size(GF_Box *s)
6430 {
6431 	GF_Err e = gf_isom_box_get_size(s);
6432 	if (e) return e;
6433 	s->size += 20;
6434 	return GF_OK;
6435 }
6436 
traf_Write(GF_Box * s,GF_BitStream * bs)6437 GF_Err traf_Write(GF_Box *s, GF_BitStream *bs)
6438 {
6439 	GF_Err e;
6440 	GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
6441 	if (!s) return GF_BAD_PARAM;
6442 
6443 	e = gf_isom_box_write_header(s, bs);
6444 	if (e) return e;
6445 
6446 	//Header first
6447 	if (ptr->tfhd) {
6448 		e = gf_isom_box_write((GF_Box *)ptr->tfhd, bs);
6449 		if (e) return e;
6450 	}
6451 	if (ptr->sub_samples) {
6452 		e = gf_isom_box_array_write(s, ptr->sub_samples, bs);
6453 		if (e) return e;
6454 	}
6455 	if (ptr->tfdt) {
6456 		e = gf_isom_box_write((GF_Box *)ptr->tfdt, bs);
6457 		if (e) return e;
6458 	}
6459 	if (ptr->sdtp) {
6460 		e = gf_isom_box_write((GF_Box *)ptr->sdtp, bs);
6461 		if (e) return e;
6462 	}
6463 	if (ptr->sampleGroupsDescription) {
6464 		e = gf_isom_box_array_write(s, ptr->sampleGroupsDescription, bs);
6465 		if (e) return e;
6466 	}
6467 	if (ptr->sampleGroups) {
6468 		e = gf_isom_box_array_write(s, ptr->sampleGroups, bs);
6469 		if (e) return e;
6470 	}
6471 	if (ptr->sai_sizes) {
6472 		e = gf_isom_box_array_write(s, ptr->sai_sizes, bs);
6473 		if (e) return e;
6474 	}
6475 	if (ptr->sai_offsets) {
6476 		e = gf_isom_box_array_write(s, ptr->sai_offsets, bs);
6477 		if (e) return e;
6478 	}
6479 	e = gf_isom_box_array_write(s, ptr->TrackRuns, bs);
6480 	if (e) return e;
6481 
6482 	if (ptr->piff_sample_encryption) {
6483 		e = gf_isom_box_write((GF_Box *)ptr->piff_sample_encryption, bs);
6484 		if (e) return e;
6485 	}
6486 	if (ptr->tfxd) {
6487 		e = gf_isom_box_write((GF_Box *)ptr->tfxd, bs);
6488 		if (e) return e;
6489 	}
6490 
6491 	if (ptr->sample_encryption) {
6492 		e = gf_isom_box_write((GF_Box *)ptr->sample_encryption, bs);
6493 		if (e) return e;
6494 	}
6495 	return GF_OK;
6496 }
6497 
traf_Size(GF_Box * s)6498 GF_Err traf_Size(GF_Box *s)
6499 {
6500 	GF_Err e;
6501 	GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
6502 
6503 	e = gf_isom_box_get_size(s);
6504 	if (e) return e;
6505 	if (ptr->tfhd) {
6506 		e = gf_isom_box_size((GF_Box *)ptr->tfhd);
6507 		if (e) return e;
6508 		ptr->size += ptr->tfhd->size;
6509 	}
6510 	if (ptr->piff_sample_encryption) {
6511 		e = gf_isom_box_size((GF_Box *)ptr->piff_sample_encryption);
6512 		if (e) return e;
6513 		ptr->size += ptr->piff_sample_encryption->size;
6514 	}
6515 	if (ptr->sub_samples) {
6516 		e = gf_isom_box_array_size(s, ptr->sub_samples);
6517 		if (e) return e;
6518 	}
6519 	if (ptr->sdtp) {
6520 		e = gf_isom_box_size((GF_Box *)ptr->sdtp);
6521 		if (e) return e;
6522 		ptr->size += ptr->sdtp->size;
6523 	}
6524 	if (ptr->tfdt) {
6525 		e = gf_isom_box_size((GF_Box *)ptr->tfdt);
6526 		if (e) return e;
6527 		ptr->size += ptr->tfdt->size;
6528 	}
6529 
6530 	if (ptr->sampleGroups) {
6531 		e = gf_isom_box_array_size(s, ptr->sampleGroups);
6532 		if (e) return e;
6533 	}
6534 	if (ptr->sampleGroupsDescription) {
6535 		e = gf_isom_box_array_size(s, ptr->sampleGroupsDescription);
6536 		if (e) return e;
6537 	}
6538 	if (ptr->sai_sizes) {
6539 		e = gf_isom_box_array_size(s, ptr->sai_sizes);
6540 		if (e) return e;
6541 	}
6542 	if (ptr->sai_offsets) {
6543 		e = gf_isom_box_array_size(s, ptr->sai_offsets);
6544 		if (e) return e;
6545 	}
6546 	if (ptr->sample_encryption) {
6547 		e = gf_isom_box_size((GF_Box *)ptr->sample_encryption);
6548 		if (e) return e;
6549 		ptr->size += ptr->sample_encryption->size;
6550 	}
6551 	if (ptr->tfxd) {
6552 		e = gf_isom_box_size((GF_Box *)ptr->tfxd);
6553 		if (e) return e;
6554 		s->size += ptr->tfxd->size;
6555 	}
6556 	return gf_isom_box_array_size(s, ptr->TrackRuns);
6557 }
6558 
6559 #endif /*GPAC_DISABLE_ISOM_WRITE*/
6560 
6561 #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
6562 
6563 
trak_del(GF_Box * s)6564 void trak_del(GF_Box *s)
6565 {
6566 	GF_TrackBox *ptr = (GF_TrackBox *)s;
6567 	if (ptr == NULL) return;
6568 
6569 	if (ptr->Header) gf_isom_box_del((GF_Box *)ptr->Header);
6570 	if (ptr->udta) gf_isom_box_del((GF_Box *)ptr->udta);
6571 	if (ptr->Media) gf_isom_box_del((GF_Box *)ptr->Media);
6572 	if (ptr->References) gf_isom_box_del((GF_Box *)ptr->References);
6573 	if (ptr->editBox) gf_isom_box_del((GF_Box *)ptr->editBox);
6574 	if (ptr->meta) gf_isom_box_del((GF_Box *)ptr->meta);
6575 	if (ptr->name) gf_free(ptr->name);
6576 	if (ptr->groups) gf_isom_box_del((GF_Box *)ptr->groups);
6577 	gf_free(ptr);
6578 }
6579 
gf_isom_check_sample_desc(GF_TrackBox * trak)6580 static void gf_isom_check_sample_desc(GF_TrackBox *trak)
6581 {
6582 	GF_BitStream *bs;
6583 	GF_UnknownBox *a;
6584 	u32 i;
6585 
6586 	if (!trak->Media || !trak->Media->information) {
6587 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no media box !\n"));
6588 		return;
6589 	}
6590 	if (!trak->Media->information->sampleTable) {
6591 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample table !\n"));
6592 		trak->Media->information->sampleTable = (GF_SampleTableBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_STBL);
6593 	}
6594 
6595 	if (!trak->Media->information->sampleTable->SampleDescription) {
6596 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample description box !\n"));
6597 		trak->Media->information->sampleTable->SampleDescription = (GF_SampleDescriptionBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_STSD);
6598 		return;
6599 	}
6600 
6601 	i = 0;
6602 	while ((a = (GF_UnknownBox*)gf_list_enum(trak->Media->information->sampleTable->SampleDescription->other_boxes, &i))) {
6603 		switch (a->type) {
6604 		case GF_ISOM_BOX_TYPE_MP4S:
6605 		case GF_ISOM_BOX_TYPE_ENCS:
6606 		case GF_ISOM_BOX_TYPE_MP4A:
6607 		case GF_ISOM_BOX_TYPE_ENCA:
6608 		case GF_ISOM_BOX_TYPE_MP4V:
6609 		case GF_ISOM_BOX_TYPE_ENCV:
6610 		case GF_ISOM_SUBTYPE_3GP_AMR:
6611 		case GF_ISOM_SUBTYPE_3GP_AMR_WB:
6612 		case GF_ISOM_SUBTYPE_3GP_EVRC:
6613 		case GF_ISOM_SUBTYPE_3GP_QCELP:
6614 		case GF_ISOM_SUBTYPE_3GP_SMV:
6615 		case GF_ISOM_SUBTYPE_3GP_H263:
6616 		case GF_ISOM_BOX_TYPE_GHNT:
6617 		case GF_ISOM_BOX_TYPE_RTP_STSD:
6618 		case GF_ISOM_BOX_TYPE_METX:
6619 		case GF_ISOM_BOX_TYPE_METT:
6620 		case GF_ISOM_BOX_TYPE_STXT:
6621 		case GF_ISOM_BOX_TYPE_AVC1:
6622 		case GF_ISOM_BOX_TYPE_AVC2:
6623 		case GF_ISOM_BOX_TYPE_AVC3:
6624 		case GF_ISOM_BOX_TYPE_AVC4:
6625 		case GF_ISOM_BOX_TYPE_SVC1:
6626 		case GF_ISOM_BOX_TYPE_HVC1:
6627 		case GF_ISOM_BOX_TYPE_HEV1:
6628 		case GF_ISOM_BOX_TYPE_HVC2:
6629 		case GF_ISOM_BOX_TYPE_HEV2:
6630 		case GF_ISOM_BOX_TYPE_HVT1:
6631 		case GF_ISOM_BOX_TYPE_LHV1:
6632 		case GF_ISOM_BOX_TYPE_LHE1:
6633 		case GF_ISOM_BOX_TYPE_TX3G:
6634 		case GF_ISOM_BOX_TYPE_TEXT:
6635 		case GF_ISOM_BOX_TYPE_ENCT:
6636 		case GF_ISOM_BOX_TYPE_DIMS:
6637 		case GF_ISOM_BOX_TYPE_AC3:
6638 		case GF_ISOM_BOX_TYPE_LSR1:
6639 		case GF_ISOM_BOX_TYPE_WVTT:
6640 		case GF_ISOM_BOX_TYPE_STPP:
6641 		case GF_ISOM_BOX_TYPE_SBTT:
6642 			continue;
6643 		default:
6644 			break;
6645 		}
6646 		if (!a->data || (a->dataSize<8)) {
6647 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Sample description %s does not have at least 8 bytes!\n", gf_4cc_to_str(a->type)));
6648 			continue;
6649 		}
6650 
6651 		/*only process visual or audio*/
6652 		switch (trak->Media->handler->handlerType) {
6653 		case GF_ISOM_MEDIA_VISUAL:
6654 		{
6655 			GF_GenericVisualSampleEntryBox *genv;
6656 			/*remove entry*/
6657 			gf_list_rem(trak->Media->information->sampleTable->SampleDescription->other_boxes, i - 1);
6658 			genv = (GF_GenericVisualSampleEntryBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRV);
6659 			bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
6660 			genv->size = a->size - 8;
6661 			gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *)genv, bs);
6662 
6663 			if (gf_bs_available(bs)) {
6664 				u64 pos = gf_bs_get_position(bs);
6665 				//try to parse as boxes
6666 				GF_Err e = gf_isom_read_box_list((GF_Box *)genv, bs, mp4v_AddBox);
6667 				if (e) {
6668 					gf_bs_seek(bs, pos);
6669 					genv->data_size = (u32)gf_bs_available(bs);
6670 					if (genv->data_size) {
6671 						genv->data = a->data;
6672 						a->data = NULL;
6673 						memmove(genv->data, genv->data + pos, genv->data_size);
6674 					}
6675 				}
6676 				else {
6677 					genv->data_size = 0;
6678 				}
6679 			}
6680 			gf_bs_del(bs);
6681 			if (!genv->data_size && genv->data) {
6682 				gf_free(genv->data);
6683 				genv->data = NULL;
6684 			}
6685 
6686 			genv->size = 0;
6687 			genv->EntryType = a->type;
6688 			gf_isom_box_del((GF_Box *)a);
6689 			gf_list_insert(trak->Media->information->sampleTable->SampleDescription->other_boxes, genv, i - 1);
6690 		}
6691 		break;
6692 		case GF_ISOM_MEDIA_AUDIO:
6693 		{
6694 			GF_GenericAudioSampleEntryBox *gena;
6695 			/*remove entry*/
6696 			gf_list_rem(trak->Media->information->sampleTable->SampleDescription->other_boxes, i - 1);
6697 			gena = (GF_GenericAudioSampleEntryBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRA);
6698 			gena->size = a->size - 8;
6699 			bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
6700 			gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox *)gena, bs);
6701 
6702 			if (gf_bs_available(bs)) {
6703 				u64 pos = gf_bs_get_position(bs);
6704 				//try to parse as boxes
6705 				GF_Err e = gf_isom_read_box_list((GF_Box *)gena, bs, mp4a_AddBox);
6706 				if (e) {
6707 					gf_bs_seek(bs, pos);
6708 					gena->data_size = (u32)gf_bs_available(bs);
6709 					if (gena->data_size) {
6710 						gena->data = a->data;
6711 						a->data = NULL;
6712 						memmove(gena->data, gena->data + pos, gena->data_size);
6713 					}
6714 				}
6715 				else {
6716 					gena->data_size = 0;
6717 				}
6718 			}
6719 			gf_bs_del(bs);
6720 			if (!gena->data_size && gena->data) {
6721 				gf_free(gena->data);
6722 				gena->data = NULL;
6723 			}
6724 			gena->size = 0;
6725 			gena->EntryType = a->type;
6726 			gf_isom_box_del((GF_Box *)a);
6727 			gf_list_insert(trak->Media->information->sampleTable->SampleDescription->other_boxes, gena, i - 1);
6728 		}
6729 		break;
6730 
6731 		default:
6732 		{
6733 			GF_GenericSampleEntryBox *genm;
6734 			/*remove entry*/
6735 			gf_list_rem(trak->Media->information->sampleTable->SampleDescription->other_boxes, i - 1);
6736 			genm = (GF_GenericSampleEntryBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRM);
6737 			genm->size = a->size - 8;
6738 			bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
6739 			gf_bs_read_data(bs, genm->reserved, 6);
6740 			genm->dataReferenceIndex = gf_bs_read_u16(bs);
6741 			genm->size -= 8;
6742 
6743 			if (gf_bs_available(bs)) {
6744 				u64 pos = gf_bs_get_position(bs);
6745 				//try to parse as boxes
6746 				GF_Err e = gf_isom_read_box_list((GF_Box *)genm, bs, mp4s_AddBox);
6747 				if (e) {
6748 					gf_bs_seek(bs, pos);
6749 					genm->data_size = (u32)gf_bs_available(bs);
6750 					if (genm->data_size) {
6751 						genm->data = a->data;
6752 						a->data = NULL;
6753 						memmove(genm->data, genm->data + pos, genm->data_size);
6754 					}
6755 				}
6756 				else {
6757 					genm->data_size = 0;
6758 				}
6759 			}
6760 			gf_bs_del(bs);
6761 			if (!genm->data_size && genm->data) {
6762 				gf_free(genm->data);
6763 				genm->data = NULL;
6764 			}
6765 			genm->size = 0;
6766 
6767 			genm->EntryType = a->type;
6768 			gf_isom_box_del((GF_Box *)a);
6769 			gf_list_insert(trak->Media->information->sampleTable->SampleDescription->other_boxes, genm, i - 1);
6770 		}
6771 		break;
6772 		}
6773 
6774 	}
6775 }
6776 
6777 
trak_AddBox(GF_Box * s,GF_Box * a)6778 GF_Err trak_AddBox(GF_Box *s, GF_Box *a)
6779 {
6780 	GF_TrackBox *ptr = (GF_TrackBox *)s;
6781 	if (!a) return GF_OK;
6782 	switch (a->type) {
6783 	case GF_ISOM_BOX_TYPE_TKHD:
6784 		if (ptr->Header) ERROR_ON_DUPLICATED_BOX(a, ptr)
6785 			ptr->Header = (GF_TrackHeaderBox *)a;
6786 		return GF_OK;
6787 	case GF_ISOM_BOX_TYPE_EDTS:
6788 		if (ptr->editBox) ERROR_ON_DUPLICATED_BOX(a, ptr)
6789 			ptr->editBox = (GF_EditBox *)a;
6790 		return GF_OK;
6791 	case GF_ISOM_BOX_TYPE_UDTA:
6792 		if (ptr->udta) ERROR_ON_DUPLICATED_BOX(a, ptr)
6793 			ptr->udta = (GF_UserDataBox *)a;
6794 		return GF_OK;
6795 	case GF_ISOM_BOX_TYPE_META:
6796 		if (ptr->meta) ERROR_ON_DUPLICATED_BOX(a, ptr)
6797 			ptr->meta = (GF_MetaBox *)a;
6798 		return GF_OK;
6799 	case GF_ISOM_BOX_TYPE_TREF:
6800 		if (ptr->References) ERROR_ON_DUPLICATED_BOX(a, ptr)
6801 			ptr->References = (GF_TrackReferenceBox *)a;
6802 		return GF_OK;
6803 	case GF_ISOM_BOX_TYPE_MDIA:
6804 		if (ptr->Media) ERROR_ON_DUPLICATED_BOX(a, ptr)
6805 			ptr->Media = (GF_MediaBox *)a;
6806 		((GF_MediaBox *)a)->mediaTrack = ptr;
6807 		return GF_OK;
6808 	case GF_ISOM_BOX_TYPE_TRGR:
6809 		if (ptr->groups) ERROR_ON_DUPLICATED_BOX(a, ptr)
6810 			ptr->groups = (GF_TrackGroupBox *)a;
6811 		return GF_OK;
6812 	default:
6813 		return gf_isom_box_add_default(s, a);
6814 	}
6815 	return GF_OK;
6816 }
6817 
6818 
trak_Read(GF_Box * s,GF_BitStream * bs)6819 GF_Err trak_Read(GF_Box *s, GF_BitStream *bs)
6820 {
6821 	GF_Err e;
6822 	GF_TrackBox *ptr = (GF_TrackBox *)s;
6823 	e = gf_isom_read_box_list(s, bs, trak_AddBox);
6824 	if (e) return e;
6825 	gf_isom_check_sample_desc(ptr);
6826 
6827 	//we should only parse senc/psec when no saiz/saio is present, otherwise we fetch the info directly
6828 	if (ptr->Media && ptr->Media->information && ptr->Media->information->sampleTable /*&& !ptr->Media->information->sampleTable->sai_sizes*/) {
6829 		if (ptr->Media->information->sampleTable->senc) {
6830 			e = senc_Parse(bs, ptr, NULL, (GF_SampleEncryptionBox *)ptr->Media->information->sampleTable->senc);
6831 		}
6832 		else if (ptr->Media->information->sampleTable->piff_psec) {
6833 			e = senc_Parse(bs, ptr, NULL, (GF_SampleEncryptionBox *)ptr->Media->information->sampleTable->piff_psec);
6834 		}
6835 	}
6836 	return e;
6837 }
6838 
trak_New()6839 GF_Box *trak_New()
6840 {
6841 	ISOM_DECL_BOX_ALLOC(GF_TrackBox, GF_ISOM_BOX_TYPE_TRAK);
6842 	return (GF_Box *)tmp;
6843 }
6844 
6845 
6846 #ifndef GPAC_DISABLE_ISOM_WRITE
6847 
trak_Write(GF_Box * s,GF_BitStream * bs)6848 GF_Err trak_Write(GF_Box *s, GF_BitStream *bs)
6849 {
6850 	GF_Err e;
6851 	GF_TrackBox *ptr = (GF_TrackBox *)s;
6852 	e = gf_isom_box_write_header(s, bs);
6853 	if (e) return e;
6854 
6855 	if (ptr->Header) {
6856 		e = gf_isom_box_write((GF_Box *)ptr->Header, bs);
6857 		if (e) return e;
6858 	}
6859 	if (ptr->References) {
6860 		e = gf_isom_box_write((GF_Box *)ptr->References, bs);
6861 		if (e) return e;
6862 	}
6863 	if (ptr->editBox) {
6864 		e = gf_isom_box_write((GF_Box *)ptr->editBox, bs);
6865 		if (e) return e;
6866 	}
6867 	if (ptr->Media) {
6868 		e = gf_isom_box_write((GF_Box *)ptr->Media, bs);
6869 		if (e) return e;
6870 	}
6871 	if (ptr->meta) {
6872 		e = gf_isom_box_write((GF_Box *)ptr->meta, bs);
6873 		if (e) return e;
6874 	}
6875 	if (ptr->groups) {
6876 		e = gf_isom_box_write((GF_Box *)ptr->groups, bs);
6877 		if (e) return e;
6878 	}
6879 	if (ptr->udta) {
6880 		e = gf_isom_box_write((GF_Box *)ptr->udta, bs);
6881 		if (e) return e;
6882 	}
6883 	return GF_OK;
6884 }
6885 
trak_Size(GF_Box * s)6886 GF_Err trak_Size(GF_Box *s)
6887 {
6888 	GF_Err e;
6889 	GF_TrackBox *ptr = (GF_TrackBox *)s;
6890 
6891 	e = gf_isom_box_get_size(s);
6892 	if (e) return e;
6893 
6894 	if (ptr->Header) {
6895 		e = gf_isom_box_size((GF_Box *)ptr->Header);
6896 		if (e) return e;
6897 		ptr->size += ptr->Header->size;
6898 	}
6899 	if (ptr->udta) {
6900 		e = gf_isom_box_size((GF_Box *)ptr->udta);
6901 		if (e) return e;
6902 		ptr->size += ptr->udta->size;
6903 	}
6904 	if (ptr->References) {
6905 		e = gf_isom_box_size((GF_Box *)ptr->References);
6906 		if (e) return e;
6907 		ptr->size += ptr->References->size;
6908 	}
6909 	if (ptr->editBox) {
6910 		e = gf_isom_box_size((GF_Box *)ptr->editBox);
6911 		if (e) return e;
6912 		ptr->size += ptr->editBox->size;
6913 	}
6914 	if (ptr->Media) {
6915 		e = gf_isom_box_size((GF_Box *)ptr->Media);
6916 		if (e) return e;
6917 		ptr->size += ptr->Media->size;
6918 	}
6919 	if (ptr->meta) {
6920 		e = gf_isom_box_size((GF_Box *)ptr->meta);
6921 		if (e) return e;
6922 		ptr->size += ptr->meta->size;
6923 	}
6924 	if (ptr->groups) {
6925 		e = gf_isom_box_size((GF_Box *)ptr->groups);
6926 		if (e) return e;
6927 		ptr->size += ptr->groups->size;
6928 	}
6929 	return GF_OK;
6930 }
6931 
6932 #endif /*GPAC_DISABLE_ISOM_WRITE*/
6933 
6934 
tref_AddBox(GF_Box * ptr,GF_Box * a)6935 GF_Err tref_AddBox(GF_Box *ptr, GF_Box *a)
6936 {
6937 	return gf_isom_box_add_default(ptr, a);
6938 }
6939 
tref_del(GF_Box * s)6940 void tref_del(GF_Box *s)
6941 {
6942 	GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
6943 	if (ptr == NULL) return;
6944 	gf_free(ptr);
6945 }
6946 
6947 
tref_Read(GF_Box * s,GF_BitStream * bs)6948 GF_Err tref_Read(GF_Box *s, GF_BitStream *bs)
6949 {
6950 	return gf_isom_read_box_list_ex(s, bs, gf_isom_box_add_default, s->type);
6951 }
6952 
tref_New()6953 GF_Box *tref_New()
6954 {
6955 	ISOM_DECL_BOX_ALLOC(GF_TrackReferenceBox, GF_ISOM_BOX_TYPE_TREF);
6956 	return (GF_Box *)tmp;
6957 }
6958 
6959 
6960 
6961 #ifndef GPAC_DISABLE_ISOM_WRITE
6962 
tref_Write(GF_Box * s,GF_BitStream * bs)6963 GF_Err tref_Write(GF_Box *s, GF_BitStream *bs)
6964 {
6965 	//	GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
6966 	return gf_isom_box_write_header(s, bs);
6967 }
6968 
tref_Size(GF_Box * s)6969 GF_Err tref_Size(GF_Box *s)
6970 {
6971 	//	GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
6972 	return gf_isom_box_get_size(s);
6973 }
6974 
6975 #endif /*GPAC_DISABLE_ISOM_WRITE*/
6976 
reftype_del(GF_Box * s)6977 void reftype_del(GF_Box *s)
6978 {
6979 	GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
6980 	if (!ptr) return;
6981 	if (ptr->trackIDs) gf_free(ptr->trackIDs);
6982 	gf_free(ptr);
6983 }
6984 
6985 
reftype_Read(GF_Box * s,GF_BitStream * bs)6986 GF_Err reftype_Read(GF_Box *s, GF_BitStream *bs)
6987 {
6988 	u32 bytesToRead;
6989 	u32 i;
6990 	GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
6991 
6992 	bytesToRead = (u32)(ptr->size);
6993 	if (!bytesToRead) return GF_OK;
6994 
6995 	ptr->trackIDCount = (u32)(bytesToRead) / sizeof(u32);
6996 	ptr->trackIDs = (u32 *)gf_malloc(ptr->trackIDCount * sizeof(u32));
6997 	if (!ptr->trackIDs) return GF_OUT_OF_MEM;
6998 
6999 	for (i = 0; i < ptr->trackIDCount; i++) {
7000 		ptr->trackIDs[i] = gf_bs_read_u32(bs);
7001 	}
7002 	return GF_OK;
7003 }
7004 
reftype_New()7005 GF_Box *reftype_New()
7006 {
7007 	ISOM_DECL_BOX_ALLOC(GF_TrackReferenceTypeBox, GF_ISOM_BOX_TYPE_REFT);
7008 	return (GF_Box *)tmp;
7009 }
7010 
7011 
reftype_AddRefTrack(GF_TrackReferenceTypeBox * ref,u32 trackID,u16 * outRefIndex)7012 GF_Err reftype_AddRefTrack(GF_TrackReferenceTypeBox *ref, u32 trackID, u16 *outRefIndex)
7013 {
7014 	u32 i;
7015 	if (!ref || !trackID) return GF_BAD_PARAM;
7016 
7017 	if (outRefIndex) *outRefIndex = 0;
7018 	//don't add a dep if already here !!
7019 	for (i = 0; i < ref->trackIDCount; i++) {
7020 		if (ref->trackIDs[i] == trackID) {
7021 			if (outRefIndex) *outRefIndex = i + 1;
7022 			return GF_OK;
7023 		}
7024 	}
7025 
7026 	ref->trackIDs = (u32 *)gf_realloc(ref->trackIDs, (ref->trackIDCount + 1) * sizeof(u32));
7027 	if (!ref->trackIDs) return GF_OUT_OF_MEM;
7028 	ref->trackIDs[ref->trackIDCount] = trackID;
7029 	ref->trackIDCount++;
7030 	if (outRefIndex) *outRefIndex = ref->trackIDCount;
7031 	return GF_OK;
7032 }
7033 
7034 
7035 
7036 #ifndef GPAC_DISABLE_ISOM_WRITE
7037 
reftype_Write(GF_Box * s,GF_BitStream * bs)7038 GF_Err reftype_Write(GF_Box *s, GF_BitStream *bs)
7039 {
7040 	GF_Err e;
7041 	u32 i;
7042 	GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
7043 	ptr->type = ptr->reference_type;
7044 	e = gf_isom_box_write_header(s, bs);
7045 	ptr->type = GF_ISOM_BOX_TYPE_REFT;
7046 	if (e) return e;
7047 	for (i = 0; i < ptr->trackIDCount; i++) {
7048 		gf_bs_write_u32(bs, ptr->trackIDs[i]);
7049 	}
7050 	return GF_OK;
7051 }
7052 
7053 
reftype_Size(GF_Box * s)7054 GF_Err reftype_Size(GF_Box *s)
7055 {
7056 	GF_Err e;
7057 	GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
7058 	e = gf_isom_box_get_size(s);
7059 	if (e) return e;
7060 	ptr->size += (ptr->trackIDCount * sizeof(u32));
7061 	return GF_OK;
7062 }
7063 
7064 #endif /*GPAC_DISABLE_ISOM_WRITE*/
7065 
7066 
7067 
7068 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
7069 
trex_del(GF_Box * s)7070 void trex_del(GF_Box *s)
7071 {
7072 	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
7073 	if (ptr == NULL) return;
7074 	gf_free(ptr);
7075 }
7076 
7077 
trex_Read(GF_Box * s,GF_BitStream * bs)7078 GF_Err trex_Read(GF_Box *s, GF_BitStream *bs)
7079 {
7080 	GF_Err e;
7081 	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
7082 
7083 	e = gf_isom_full_box_read(s, bs);
7084 	if (e) return e;
7085 
7086 	ptr->trackID = gf_bs_read_u32(bs);
7087 	ptr->def_sample_desc_index = gf_bs_read_u32(bs);
7088 	ptr->def_sample_duration = gf_bs_read_u32(bs);
7089 	ptr->def_sample_size = gf_bs_read_u32(bs);
7090 	ptr->def_sample_flags = gf_bs_read_u32(bs);
7091 
7092 	if (!ptr->def_sample_desc_index) {
7093 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] TREX with default sample description set to 0, likely broken ! Fixing to 1\n"));
7094 		ptr->def_sample_desc_index = 1;
7095 	}
7096 	return GF_OK;
7097 }
7098 
trex_New()7099 GF_Box *trex_New()
7100 {
7101 	ISOM_DECL_BOX_ALLOC(GF_TrackExtendsBox, GF_ISOM_BOX_TYPE_TREX);
7102 	return (GF_Box *)tmp;
7103 }
7104 
7105 
7106 
7107 #ifndef GPAC_DISABLE_ISOM_WRITE
7108 
7109 
trex_Write(GF_Box * s,GF_BitStream * bs)7110 GF_Err trex_Write(GF_Box *s, GF_BitStream *bs)
7111 {
7112 	GF_Err e;
7113 	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
7114 	if (!s) return GF_BAD_PARAM;
7115 	e = gf_isom_full_box_write(s, bs);
7116 	if (e) return e;
7117 
7118 	gf_bs_write_u32(bs, ptr->trackID);
7119 	gf_bs_write_u32(bs, ptr->def_sample_desc_index);
7120 	gf_bs_write_u32(bs, ptr->def_sample_duration);
7121 	gf_bs_write_u32(bs, ptr->def_sample_size);
7122 	gf_bs_write_u32(bs, ptr->def_sample_flags);
7123 	return GF_OK;
7124 }
7125 
trex_Size(GF_Box * s)7126 GF_Err trex_Size(GF_Box *s)
7127 {
7128 	GF_Err e;
7129 	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
7130 	e = gf_isom_full_box_get_size(s);
7131 	if (e) return e;
7132 	ptr->size += 20;
7133 	return GF_OK;
7134 }
7135 
7136 
7137 
7138 #endif /*GPAC_DISABLE_ISOM_WRITE*/
7139 
7140 
7141 
trep_del(GF_Box * s)7142 void trep_del(GF_Box *s)
7143 {
7144 	GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
7145 	if (ptr == NULL) return;
7146 	gf_free(ptr);
7147 }
7148 
7149 
trep_Read(GF_Box * s,GF_BitStream * bs)7150 GF_Err trep_Read(GF_Box *s, GF_BitStream *bs)
7151 {
7152 	GF_Err e;
7153 	GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
7154 
7155 	e = gf_isom_full_box_read(s, bs);
7156 	if (e) return e;
7157 
7158 	ptr->trackID = gf_bs_read_u32(bs);
7159 	ptr->size -= 4;
7160 
7161 	return gf_isom_read_box_list(s, bs, gf_isom_box_add_default);
7162 }
7163 
trep_New()7164 GF_Box *trep_New()
7165 {
7166 	ISOM_DECL_BOX_ALLOC(GF_TrackExtensionPropertiesBox, GF_ISOM_BOX_TYPE_TREP);
7167 	tmp->other_boxes = gf_list_new();
7168 	return (GF_Box *)tmp;
7169 }
7170 
7171 
7172 
7173 #ifndef GPAC_DISABLE_ISOM_WRITE
7174 
7175 
trep_Write(GF_Box * s,GF_BitStream * bs)7176 GF_Err trep_Write(GF_Box *s, GF_BitStream *bs)
7177 {
7178 	GF_Err e;
7179 	GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
7180 	if (!s) return GF_BAD_PARAM;
7181 	e = gf_isom_full_box_write(s, bs);
7182 	if (e) return e;
7183 
7184 	gf_bs_write_u32(bs, ptr->trackID);
7185 	return GF_OK;
7186 }
7187 
trep_Size(GF_Box * s)7188 GF_Err trep_Size(GF_Box *s)
7189 {
7190 	GF_Err e;
7191 	GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
7192 	e = gf_isom_full_box_get_size(s);
7193 	if (e) return e;
7194 	ptr->size += 4;
7195 	return GF_OK;
7196 }
7197 
7198 
7199 
7200 #endif /*GPAC_DISABLE_ISOM_WRITE*/
7201 
7202 #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
7203 
7204 
7205 
7206 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
7207 
trun_del(GF_Box * s)7208 void trun_del(GF_Box *s)
7209 {
7210 	GF_TrunEntry *p;
7211 	GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
7212 	if (ptr == NULL) return;
7213 
7214 	while (gf_list_count(ptr->entries)) {
7215 		p = (GF_TrunEntry*)gf_list_get(ptr->entries, 0);
7216 		gf_list_rem(ptr->entries, 0);
7217 		gf_free(p);
7218 	}
7219 	gf_list_del(ptr->entries);
7220 	if (ptr->cache) gf_bs_del(ptr->cache);
7221 	gf_free(ptr);
7222 }
7223 
trun_Read(GF_Box * s,GF_BitStream * bs)7224 GF_Err trun_Read(GF_Box *s, GF_BitStream *bs)
7225 {
7226 	GF_Err e;
7227 	u32 i;
7228 	GF_TrunEntry *p;
7229 	GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
7230 
7231 	e = gf_isom_full_box_read(s, bs);
7232 	if (e) return e;
7233 
7234 	//check this is a good file
7235 	if ((ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) && (ptr->flags & GF_ISOM_TRUN_FLAGS))
7236 		return GF_ISOM_INVALID_FILE;
7237 
7238 	ptr->sample_count = gf_bs_read_u32(bs);
7239 
7240 	//The rest depends on the flags
7241 	if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) {
7242 		ptr->data_offset = gf_bs_read_u32(bs);
7243 		ptr->size -= 4;
7244 	}
7245 	if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) {
7246 		ptr->first_sample_flags = gf_bs_read_u32(bs);
7247 		ptr->size -= 4;
7248 	}
7249 
7250 	//read each entry (even though nothing may be written)
7251 	for (i = 0; i<ptr->sample_count; i++) {
7252 		u32 trun_size = 0;
7253 		p = (GF_TrunEntry *)gf_malloc(sizeof(GF_TrunEntry));
7254 		if (!p) return GF_OUT_OF_MEM;
7255 		memset(p, 0, sizeof(GF_TrunEntry));
7256 
7257 		if (ptr->flags & GF_ISOM_TRUN_DURATION) {
7258 			p->Duration = gf_bs_read_u32(bs);
7259 			trun_size += 4;
7260 		}
7261 		if (ptr->flags & GF_ISOM_TRUN_SIZE) {
7262 			p->size = gf_bs_read_u32(bs);
7263 			trun_size += 4;
7264 		}
7265 		//SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
7266 		if (ptr->flags & GF_ISOM_TRUN_FLAGS) {
7267 			p->flags = gf_bs_read_u32(bs);
7268 			trun_size += 4;
7269 		}
7270 		if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) {
7271 			if (ptr->version == 0) {
7272 				p->CTS_Offset = (u32)gf_bs_read_u32(bs);
7273 			}
7274 			else {
7275 				p->CTS_Offset = (s32)gf_bs_read_u32(bs);
7276 			}
7277 		}
7278 		gf_list_add(ptr->entries, p);
7279 		if (ptr->size<trun_size) return GF_ISOM_INVALID_FILE;
7280 		ptr->size -= trun_size;
7281 	}
7282 	return GF_OK;
7283 }
7284 
trun_New()7285 GF_Box *trun_New()
7286 {
7287 	ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRunBox, GF_ISOM_BOX_TYPE_TRUN);
7288 	tmp->entries = gf_list_new();
7289 	//NO FLAGS SET BY DEFAULT
7290 	return (GF_Box *)tmp;
7291 }
7292 
7293 
7294 
7295 #ifndef GPAC_DISABLE_ISOM_WRITE
7296 
7297 
trun_Write(GF_Box * s,GF_BitStream * bs)7298 GF_Err trun_Write(GF_Box *s, GF_BitStream *bs)
7299 {
7300 	GF_TrunEntry *p;
7301 	GF_Err e;
7302 	u32 i, count;
7303 	GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
7304 	if (!s) return GF_BAD_PARAM;
7305 
7306 	e = gf_isom_full_box_write(s, bs);
7307 	if (e) return e;
7308 
7309 	gf_bs_write_u32(bs, ptr->sample_count);
7310 
7311 	//The rest depends on the flags
7312 	if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) {
7313 		gf_bs_write_u32(bs, ptr->data_offset);
7314 	}
7315 	if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) {
7316 		gf_bs_write_u32(bs, ptr->first_sample_flags);
7317 	}
7318 
7319 	//if nothing to do, this will be skipped automatically
7320 	count = gf_list_count(ptr->entries);
7321 	for (i = 0; i<count; i++) {
7322 		p = (GF_TrunEntry*)gf_list_get(ptr->entries, i);
7323 
7324 		if (ptr->flags & GF_ISOM_TRUN_DURATION) {
7325 			gf_bs_write_u32(bs, p->Duration);
7326 		}
7327 		if (ptr->flags & GF_ISOM_TRUN_SIZE) {
7328 			gf_bs_write_u32(bs, p->size);
7329 		}
7330 		//SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
7331 		if (ptr->flags & GF_ISOM_TRUN_FLAGS) {
7332 			gf_bs_write_u32(bs, p->flags);
7333 		}
7334 		if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) {
7335 			if (ptr->version == 0) {
7336 				gf_bs_write_u32(bs, p->CTS_Offset);
7337 			}
7338 			else {
7339 				gf_bs_write_u32(bs, (u32)p->CTS_Offset);
7340 			}
7341 		}
7342 	}
7343 	return GF_OK;
7344 }
7345 
trun_Size(GF_Box * s)7346 GF_Err trun_Size(GF_Box *s)
7347 {
7348 	GF_Err e;
7349 	u32 i, count;
7350 	GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
7351 
7352 	e = gf_isom_full_box_get_size(s);
7353 	if (e) return e;
7354 
7355 	ptr->size += 4;
7356 	//The rest depends on the flags
7357 	if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) ptr->size += 4;
7358 	if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) ptr->size += 4;
7359 
7360 	//if nothing to do, this will be skipped automatically
7361 	count = gf_list_count(ptr->entries);
7362 	for (i = 0; i<count; i++) {
7363 		if (ptr->flags & GF_ISOM_TRUN_DURATION) ptr->size += 4;
7364 		if (ptr->flags & GF_ISOM_TRUN_SIZE) ptr->size += 4;
7365 		//SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
7366 		if (ptr->flags & GF_ISOM_TRUN_FLAGS) ptr->size += 4;
7367 		if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) ptr->size += 4;
7368 	}
7369 
7370 	return GF_OK;
7371 }
7372 
7373 
7374 
7375 #endif /*GPAC_DISABLE_ISOM_WRITE*/
7376 
7377 #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
7378 
7379 
tsro_del(GF_Box * s)7380 void tsro_del(GF_Box *s)
7381 {
7382 	GF_TimeOffHintEntryBox *tsro = (GF_TimeOffHintEntryBox *)s;
7383 	gf_free(tsro);
7384 }
7385 
tsro_Read(GF_Box * s,GF_BitStream * bs)7386 GF_Err tsro_Read(GF_Box *s, GF_BitStream *bs)
7387 {
7388 	GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s;
7389 	ptr->TimeOffset = gf_bs_read_u32(bs);
7390 	return GF_OK;
7391 }
7392 
tsro_New()7393 GF_Box *tsro_New()
7394 {
7395 	ISOM_DECL_BOX_ALLOC(GF_TimeOffHintEntryBox, GF_ISOM_BOX_TYPE_TSRO);
7396 	return (GF_Box *)tmp;
7397 }
7398 
7399 
7400 #ifndef GPAC_DISABLE_ISOM_WRITE
tsro_Write(GF_Box * s,GF_BitStream * bs)7401 GF_Err tsro_Write(GF_Box *s, GF_BitStream *bs)
7402 {
7403 	GF_Err e;
7404 	GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s;
7405 	if (ptr == NULL) return GF_BAD_PARAM;
7406 
7407 	e = gf_isom_box_write_header(s, bs);
7408 	if (e) return e;
7409 	gf_bs_write_u32(bs, ptr->TimeOffset);
7410 	return GF_OK;
7411 }
7412 
tsro_Size(GF_Box * s)7413 GF_Err tsro_Size(GF_Box *s)
7414 {
7415 	GF_Err e;
7416 	e = gf_isom_box_get_size(s);
7417 	if (e) return e;
7418 	s->size += 4;
7419 	return GF_OK;
7420 }
7421 #endif /*GPAC_DISABLE_ISOM_WRITE*/
7422 
7423 
udta_del(GF_Box * s)7424 void udta_del(GF_Box *s)
7425 {
7426 	u32 i;
7427 	GF_UserDataMap *map;
7428 	GF_UserDataBox *ptr = (GF_UserDataBox *)s;
7429 	if (ptr == NULL) return;
7430 	i = 0;
7431 	while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
7432 		gf_isom_box_array_del(map->other_boxes);
7433 		gf_free(map);
7434 	}
7435 	gf_list_del(ptr->recordList);
7436 	gf_free(ptr);
7437 }
7438 
udta_getEntry(GF_UserDataBox * ptr,u32 box_type,bin128 * uuid)7439 GF_UserDataMap *udta_getEntry(GF_UserDataBox *ptr, u32 box_type, bin128 *uuid)
7440 {
7441 	u32 i;
7442 	GF_UserDataMap *map;
7443 	if (ptr == NULL) return NULL;
7444 	i = 0;
7445 	while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
7446 		if (map->boxType == box_type) {
7447 			if ((box_type != GF_ISOM_BOX_TYPE_UUID) || !uuid) return map;
7448 			if (!memcmp(map->uuid, *uuid, 16)) return map;
7449 		}
7450 	}
7451 	return NULL;
7452 }
7453 
udta_AddBox(GF_UserDataBox * ptr,GF_Box * a)7454 GF_Err udta_AddBox(GF_UserDataBox *ptr, GF_Box *a)
7455 {
7456 	GF_Err e;
7457 	GF_UserDataMap *map;
7458 	if (!ptr) return GF_BAD_PARAM;
7459 	if (!a) return GF_OK;
7460 
7461 	map = udta_getEntry(ptr, a->type, (a->type == GF_ISOM_BOX_TYPE_UUID) ? &((GF_UUIDBox *)a)->uuid : NULL);
7462 	if (map == NULL) {
7463 		map = (GF_UserDataMap *)gf_malloc(sizeof(GF_UserDataMap));
7464 		if (map == NULL) return GF_OUT_OF_MEM;
7465 		memset(map, 0, sizeof(GF_UserDataMap));
7466 
7467 		map->boxType = a->type;
7468 		if (a->type == GF_ISOM_BOX_TYPE_UUID)
7469 			memcpy(map->uuid, ((GF_UUIDBox *)a)->uuid, 16);
7470 		map->other_boxes = gf_list_new();
7471 		if (!map->other_boxes) {
7472 			gf_free(map);
7473 			return GF_OUT_OF_MEM;
7474 		}
7475 		e = gf_list_add(ptr->recordList, map);
7476 		if (e) return e;
7477 	}
7478 	return gf_list_add(map->other_boxes, a);
7479 }
7480 
7481 
udta_Read(GF_Box * s,GF_BitStream * bs)7482 GF_Err udta_Read(GF_Box *s, GF_BitStream *bs)
7483 {
7484 	GF_Err e;
7485 	u32 sub_type;
7486 	GF_Box *a;
7487 	GF_UserDataBox *ptr = (GF_UserDataBox *)s;
7488 	while (ptr->size) {
7489 		/*if no udta type coded, break*/
7490 		sub_type = gf_bs_peek_bits(bs, 32, 0);
7491 		if (sub_type) {
7492 			e = gf_isom_parse_box(&a, bs);
7493 			if (e) return e;
7494 			e = udta_AddBox(ptr, a);
7495 			if (e) return e;
7496 			if (ptr->size<a->size) return GF_ISOM_INVALID_FILE;
7497 			ptr->size -= a->size;
7498 		}
7499 		else {
7500 			gf_bs_read_u32(bs);
7501 			ptr->size -= 4;
7502 		}
7503 	}
7504 	return GF_OK;
7505 }
7506 
udta_New()7507 GF_Box *udta_New()
7508 {
7509 	ISOM_DECL_BOX_ALLOC(GF_UserDataBox, GF_ISOM_BOX_TYPE_UDTA);
7510 	tmp->recordList = gf_list_new();
7511 	if (!tmp->recordList) {
7512 		gf_free(tmp);
7513 		return NULL;
7514 	}
7515 	return (GF_Box *)tmp;
7516 }
7517 
7518 
7519 #ifndef GPAC_DISABLE_ISOM_WRITE
7520 
udta_Write(GF_Box * s,GF_BitStream * bs)7521 GF_Err udta_Write(GF_Box *s, GF_BitStream *bs)
7522 {
7523 	GF_Err e;
7524 	u32 i;
7525 	GF_UserDataMap *map;
7526 	GF_UserDataBox *ptr = (GF_UserDataBox *)s;
7527 
7528 	e = gf_isom_box_write_header(s, bs);
7529 	if (e) return e;
7530 	i = 0;
7531 	while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
7532 		//warning: here we are not passing the actual "parent" of the list
7533 		//but the UDTA box. The parent itself is not an box, we don't care about it
7534 		e = gf_isom_box_array_write(s, map->other_boxes, bs);
7535 		if (e) return e;
7536 	}
7537 	return GF_OK;
7538 }
7539 
udta_Size(GF_Box * s)7540 GF_Err udta_Size(GF_Box *s)
7541 {
7542 	GF_Err e;
7543 	u32 i;
7544 	GF_UserDataMap *map;
7545 	GF_UserDataBox *ptr = (GF_UserDataBox *)s;
7546 
7547 	e = gf_isom_box_get_size(s);
7548 	if (e) return e;
7549 	i = 0;
7550 	while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
7551 		//warning: here we are not passing the actual "parent" of the list
7552 		//but the UDTA box. The parent itself is not an box, we don't care about it
7553 		e = gf_isom_box_array_size(s, map->other_boxes);
7554 		if (e) return e;
7555 	}
7556 	return GF_OK;
7557 }
7558 
7559 #endif /*GPAC_DISABLE_ISOM_WRITE*/
7560 
7561 
vmhd_del(GF_Box * s)7562 void vmhd_del(GF_Box *s)
7563 {
7564 	GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
7565 	if (ptr == NULL) return;
7566 	gf_free(ptr);
7567 }
7568 
7569 
vmhd_Read(GF_Box * s,GF_BitStream * bs)7570 GF_Err vmhd_Read(GF_Box *s, GF_BitStream *bs)
7571 {
7572 	GF_Err e;
7573 	GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
7574 	e = gf_isom_full_box_read(s, bs);
7575 	if (e) return e;
7576 	ptr->reserved = gf_bs_read_u64(bs);
7577 	return GF_OK;
7578 }
7579 
vmhd_New()7580 GF_Box *vmhd_New()
7581 {
7582 	ISOM_DECL_BOX_ALLOC(GF_VideoMediaHeaderBox, GF_ISOM_BOX_TYPE_VMHD);
7583 	gf_isom_full_box_init((GF_Box *)tmp);
7584 	tmp->flags = 1;
7585 	return (GF_Box *)tmp;
7586 }
7587 
7588 
7589 
7590 #ifndef GPAC_DISABLE_ISOM_WRITE
7591 
vmhd_Write(GF_Box * s,GF_BitStream * bs)7592 GF_Err vmhd_Write(GF_Box *s, GF_BitStream *bs)
7593 {
7594 	GF_Err e;
7595 	GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
7596 
7597 	e = gf_isom_full_box_write(s, bs);
7598 	if (e) return e;
7599 	gf_bs_write_u64(bs, ptr->reserved);
7600 	return GF_OK;
7601 }
7602 
vmhd_Size(GF_Box * s)7603 GF_Err vmhd_Size(GF_Box *s)
7604 {
7605 	GF_Err e;
7606 	GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
7607 	e = gf_isom_full_box_get_size(s);
7608 	if (e) return e;
7609 	ptr->size += 8;
7610 	return GF_OK;
7611 }
7612 
7613 #endif /*GPAC_DISABLE_ISOM_WRITE*/
7614 
7615 
void_del(GF_Box * s)7616 void void_del(GF_Box *s)
7617 {
7618 	gf_free(s);
7619 }
7620 
7621 
void_Read(GF_Box * s,GF_BitStream * bs)7622 GF_Err void_Read(GF_Box *s, GF_BitStream *bs)
7623 {
7624 	if (s->size) return GF_ISOM_INVALID_FILE;
7625 	return GF_OK;
7626 }
7627 
void_New()7628 GF_Box *void_New()
7629 {
7630 	ISOM_DECL_BOX_ALLOC(GF_Box, GF_ISOM_BOX_TYPE_VOID);
7631 	return tmp;
7632 }
7633 
7634 
7635 #ifndef GPAC_DISABLE_ISOM_WRITE
7636 
void_Write(GF_Box * s,GF_BitStream * bs)7637 GF_Err void_Write(GF_Box *s, GF_BitStream *bs)
7638 {
7639 	gf_bs_write_u32(bs, 0);
7640 	return GF_OK;
7641 }
7642 
void_Size(GF_Box * s)7643 GF_Err void_Size(GF_Box *s)
7644 {
7645 	s->size = 4;
7646 	return GF_OK;
7647 }
7648 
7649 #endif /*GPAC_DISABLE_ISOM_WRITE*/
7650 
7651 
7652 
pdin_New()7653 GF_Box *pdin_New()
7654 {
7655 	ISOM_DECL_BOX_ALLOC(GF_ProgressiveDownloadBox, GF_ISOM_BOX_TYPE_PDIN);
7656 	gf_isom_full_box_init((GF_Box *)tmp);
7657 	tmp->flags = 1;
7658 	return (GF_Box *)tmp;
7659 }
7660 
7661 
pdin_del(GF_Box * s)7662 void pdin_del(GF_Box *s)
7663 {
7664 	GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s;
7665 	if (ptr == NULL) return;
7666 	if (ptr->rates) gf_free(ptr->rates);
7667 	if (ptr->times) gf_free(ptr->times);
7668 	gf_free(ptr);
7669 }
7670 
7671 
pdin_Read(GF_Box * s,GF_BitStream * bs)7672 GF_Err pdin_Read(GF_Box *s, GF_BitStream *bs)
7673 {
7674 	u32 i;
7675 	GF_Err e;
7676 	GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s;
7677 
7678 	e = gf_isom_full_box_read(s, bs);
7679 	if (e) return e;
7680 
7681 	ptr->count = (u32)(ptr->size) / 8;
7682 	ptr->rates = (u32*)gf_malloc(sizeof(u32)*ptr->count);
7683 	ptr->times = (u32*)gf_malloc(sizeof(u32)*ptr->count);
7684 	for (i = 0; i<ptr->count; i++) {
7685 		ptr->rates[i] = gf_bs_read_u32(bs);
7686 		ptr->times[i] = gf_bs_read_u32(bs);
7687 	}
7688 	return GF_OK;
7689 }
7690 
7691 
7692 #ifndef GPAC_DISABLE_ISOM_WRITE
7693 
pdin_Write(GF_Box * s,GF_BitStream * bs)7694 GF_Err pdin_Write(GF_Box *s, GF_BitStream *bs)
7695 {
7696 	GF_Err e;
7697 	u32 i;
7698 	GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s;
7699 	e = gf_isom_full_box_write(s, bs);
7700 	if (e) return e;
7701 	for (i = 0; i<ptr->count; i++) {
7702 		gf_bs_write_u32(bs, ptr->rates[i]);
7703 		gf_bs_write_u32(bs, ptr->times[i]);
7704 	}
7705 	return GF_OK;
7706 }
7707 
pdin_Size(GF_Box * s)7708 GF_Err pdin_Size(GF_Box *s)
7709 {
7710 	GF_Err e;
7711 	GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s;
7712 	e = gf_isom_full_box_get_size(s);
7713 	if (e) return e;
7714 	ptr->size += 8 * ptr->count;
7715 	return GF_OK;
7716 }
7717 
7718 #endif /*GPAC_DISABLE_ISOM_WRITE*/
7719 
7720 
7721 
7722 
sdtp_New()7723 GF_Box *sdtp_New()
7724 {
7725 	ISOM_DECL_BOX_ALLOC(GF_SampleDependencyTypeBox, GF_ISOM_BOX_TYPE_SDTP);
7726 	gf_isom_full_box_init((GF_Box *)tmp);
7727 	tmp->flags = 1;
7728 	return (GF_Box *)tmp;
7729 }
7730 
7731 
sdtp_del(GF_Box * s)7732 void sdtp_del(GF_Box *s)
7733 {
7734 	GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s;
7735 	if (ptr == NULL) return;
7736 	if (ptr->sample_info) gf_free(ptr->sample_info);
7737 	gf_free(ptr);
7738 }
7739 
7740 
sdtp_Read(GF_Box * s,GF_BitStream * bs)7741 GF_Err sdtp_Read(GF_Box *s, GF_BitStream *bs)
7742 {
7743 	GF_Err e;
7744 	GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s;
7745 
7746 	e = gf_isom_full_box_read(s, bs);
7747 	if (e) return e;
7748 	/*out-of-order sdtp, assume no padding at the end*/
7749 	if (!ptr->sampleCount) ptr->sampleCount = (u32)(ptr->size - 8);
7750 	ptr->sample_info = (u8 *)gf_malloc(sizeof(u8)*ptr->sampleCount);
7751 	gf_bs_read_data(bs, (char*)ptr->sample_info, ptr->sampleCount);
7752 	ptr->size -= ptr->sampleCount;
7753 	return GF_OK;
7754 }
7755 
7756 
7757 #ifndef GPAC_DISABLE_ISOM_WRITE
7758 
sdtp_Write(GF_Box * s,GF_BitStream * bs)7759 GF_Err sdtp_Write(GF_Box *s, GF_BitStream *bs)
7760 {
7761 	GF_Err e;
7762 	GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s;
7763 	e = gf_isom_full_box_write(s, bs);
7764 	if (e) return e;
7765 	gf_bs_write_data(bs, (char*)ptr->sample_info, ptr->sampleCount);
7766 	return GF_OK;
7767 }
7768 
sdtp_Size(GF_Box * s)7769 GF_Err sdtp_Size(GF_Box *s)
7770 {
7771 	GF_Err e;
7772 	GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s;
7773 	e = gf_isom_full_box_get_size(s);
7774 	if (e) return e;
7775 	ptr->size += ptr->sampleCount;
7776 	return GF_OK;
7777 }
7778 
7779 #endif /*GPAC_DISABLE_ISOM_WRITE*/
7780 
7781 
pasp_New()7782 GF_Box *pasp_New()
7783 {
7784 	ISOM_DECL_BOX_ALLOC(GF_PixelAspectRatioBox, GF_ISOM_BOX_TYPE_PASP);
7785 	return (GF_Box *)tmp;
7786 }
7787 
7788 
pasp_del(GF_Box * s)7789 void pasp_del(GF_Box *s)
7790 {
7791 	GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s;
7792 	if (ptr == NULL) return;
7793 	gf_free(ptr);
7794 }
7795 
7796 
pasp_Read(GF_Box * s,GF_BitStream * bs)7797 GF_Err pasp_Read(GF_Box *s, GF_BitStream *bs)
7798 {
7799 	GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s;
7800 	ptr->hSpacing = gf_bs_read_u32(bs);
7801 	ptr->vSpacing = gf_bs_read_u32(bs);
7802 	ptr->size -= 8;
7803 	return GF_OK;
7804 }
7805 
7806 
7807 #ifndef GPAC_DISABLE_ISOM_WRITE
7808 
pasp_Write(GF_Box * s,GF_BitStream * bs)7809 GF_Err pasp_Write(GF_Box *s, GF_BitStream *bs)
7810 {
7811 	GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox *)s;
7812 	GF_Err e = gf_isom_box_write_header(s, bs);
7813 	if (e) return e;
7814 	gf_bs_write_u32(bs, ptr->hSpacing);
7815 	gf_bs_write_u32(bs, ptr->vSpacing);
7816 	return GF_OK;
7817 }
7818 
pasp_Size(GF_Box * s)7819 GF_Err pasp_Size(GF_Box *s)
7820 {
7821 	GF_Err e = gf_isom_box_get_size(s);
7822 	if (e) return e;
7823 	s->size += 8;
7824 	return GF_OK;
7825 }
7826 
7827 #endif /*GPAC_DISABLE_ISOM_WRITE*/
7828 
7829 
7830 
7831 
metx_New(u32 type)7832 GF_Box *metx_New(u32 type)
7833 {
7834 	ISOM_DECL_BOX_ALLOC(GF_MetaDataSampleEntryBox, type);
7835 	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
7836 	return (GF_Box *)tmp;
7837 }
7838 
7839 
metx_del(GF_Box * s)7840 void metx_del(GF_Box *s)
7841 {
7842 	GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s;
7843 	if (ptr == NULL) return;
7844 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
7845 
7846 	if (ptr->content_encoding) gf_free(ptr->content_encoding);
7847 	if (ptr->xml_namespace) gf_free(ptr->xml_namespace);
7848 	if (ptr->xml_schema_loc) gf_free(ptr->xml_schema_loc);
7849 	if (ptr->mime_type) gf_free(ptr->mime_type);
7850 	if (ptr->config) gf_isom_box_del((GF_Box *)ptr->config);
7851 	gf_free(ptr);
7852 }
7853 
7854 
metx_AddBox(GF_Box * s,GF_Box * a)7855 GF_Err metx_AddBox(GF_Box *s, GF_Box *a)
7856 {
7857 	GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
7858 	switch (a->type) {
7859 	case GF_ISOM_BOX_TYPE_SINF:
7860 		gf_list_add(ptr->protections, a);
7861 		break;
7862 	case GF_ISOM_BOX_TYPE_TXTC:
7863 		//we allow the config box on metx
7864 		if (ptr->config) ERROR_ON_DUPLICATED_BOX(a, ptr)
7865 			ptr->config = (GF_TextConfigBox *)a;
7866 		break;
7867 	default:
7868 		return gf_isom_box_add_default(s, a);
7869 	}
7870 	return GF_OK;
7871 }
7872 
metx_Read(GF_Box * s,GF_BitStream * bs)7873 GF_Err metx_Read(GF_Box *s, GF_BitStream *bs)
7874 {
7875 	u32 size, i;
7876 	char *str;
7877 	GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s;
7878 
7879 	gf_bs_read_data(bs, ptr->reserved, 6);
7880 	ptr->dataReferenceIndex = gf_bs_read_u16(bs);
7881 
7882 	size = (u32)ptr->size - 8;
7883 	str = gf_malloc(sizeof(char)*size);
7884 
7885 	i = 0;
7886 
7887 	while (size) {
7888 		str[i] = gf_bs_read_u8(bs);
7889 		size--;
7890 		if (!str[i])
7891 			break;
7892 		i++;
7893 	}
7894 	if (i) {
7895 		if (ptr->type == GF_ISOM_BOX_TYPE_STPP) {
7896 			ptr->xml_namespace = gf_strdup(str);
7897 		}
7898 		else {
7899 			ptr->content_encoding = gf_strdup(str);
7900 		}
7901 	}
7902 
7903 	i = 0;
7904 	while (size) {
7905 		str[i] = gf_bs_read_u8(bs);
7906 		size--;
7907 		if (!str[i])
7908 			break;
7909 		i++;
7910 	}
7911 	if ((ptr->type == GF_ISOM_BOX_TYPE_METX) || (ptr->type == GF_ISOM_BOX_TYPE_STPP)) {
7912 		if (i) {
7913 			if (ptr->type == GF_ISOM_BOX_TYPE_STPP) {
7914 				ptr->xml_schema_loc = gf_strdup(str);
7915 			}
7916 			else {
7917 				ptr->xml_namespace = gf_strdup(str);
7918 			}
7919 		}
7920 
7921 		i = 0;
7922 		while (size) {
7923 			str[i] = gf_bs_read_u8(bs);
7924 			size--;
7925 			if (!str[i])
7926 				break;
7927 			i++;
7928 		}
7929 		if (i) {
7930 			if (ptr->type == GF_ISOM_BOX_TYPE_STPP) {
7931 				ptr->mime_type = gf_strdup(str);
7932 			}
7933 			else {
7934 				ptr->xml_schema_loc = gf_strdup(str);
7935 			}
7936 		}
7937 	}
7938 	//mett, sbtt, stxt, stpp
7939 	else {
7940 		if (i) ptr->mime_type = gf_strdup(str);
7941 	}
7942 	ptr->size = size;
7943 	gf_free(str);
7944 	return gf_isom_read_box_list(s, bs, metx_AddBox);
7945 }
7946 
7947 
7948 #ifndef GPAC_DISABLE_ISOM_WRITE
7949 
metx_Write(GF_Box * s,GF_BitStream * bs)7950 GF_Err metx_Write(GF_Box *s, GF_BitStream *bs)
7951 {
7952 	GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
7953 	GF_Err e = gf_isom_box_write_header(s, bs);
7954 	if (e) return e;
7955 
7956 	gf_bs_write_data(bs, ptr->reserved, 6);
7957 	gf_bs_write_u16(bs, ptr->dataReferenceIndex);
7958 
7959 	if (ptr->type != GF_ISOM_BOX_TYPE_STPP) {
7960 		if (ptr->content_encoding)
7961 			gf_bs_write_data(bs, ptr->content_encoding, (u32)strlen(ptr->content_encoding));
7962 		gf_bs_write_u8(bs, 0);
7963 	}
7964 
7965 	if ((ptr->type == GF_ISOM_BOX_TYPE_METX) || (ptr->type == GF_ISOM_BOX_TYPE_STPP)) {
7966 		if (ptr->xml_namespace)
7967 			gf_bs_write_data(bs, ptr->xml_namespace, (u32)strlen(ptr->xml_namespace));
7968 
7969 		gf_bs_write_u8(bs, 0);
7970 
7971 		if (ptr->xml_schema_loc)
7972 			gf_bs_write_data(bs, ptr->xml_schema_loc, (u32)strlen(ptr->xml_schema_loc));
7973 		gf_bs_write_u8(bs, 0);
7974 
7975 		if (ptr->type == GF_ISOM_BOX_TYPE_STPP) {
7976 			if (ptr->mime_type)
7977 				gf_bs_write_data(bs, ptr->mime_type, (u32)strlen(ptr->mime_type));
7978 
7979 			gf_bs_write_u8(bs, 0);
7980 		}
7981 	}
7982 	//mett, sbtt, stxt
7983 	else {
7984 		if (ptr->mime_type)
7985 			gf_bs_write_data(bs, ptr->mime_type, (u32)strlen(ptr->mime_type));
7986 
7987 		gf_bs_write_u8(bs, 0);
7988 
7989 		if (ptr->config) {
7990 			gf_isom_box_write((GF_Box *)ptr->config, bs);
7991 		}
7992 	}
7993 
7994 	return gf_isom_box_array_write(s, ptr->protections, bs);
7995 }
7996 
metx_Size(GF_Box * s)7997 GF_Err metx_Size(GF_Box *s)
7998 {
7999 	GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
8000 	GF_Err e = gf_isom_box_get_size(s);
8001 	if (e) return e;
8002 	ptr->size += 8;
8003 
8004 	if (ptr->type != GF_ISOM_BOX_TYPE_STPP) {
8005 		if (ptr->content_encoding)
8006 			ptr->size += strlen(ptr->content_encoding);
8007 		ptr->size++;
8008 	}
8009 
8010 	if ((ptr->type == GF_ISOM_BOX_TYPE_METX) || (ptr->type == GF_ISOM_BOX_TYPE_STPP)) {
8011 
8012 		if (ptr->xml_namespace)
8013 			ptr->size += strlen(ptr->xml_namespace);
8014 		ptr->size++;
8015 
8016 		if (ptr->xml_schema_loc)
8017 			ptr->size += strlen(ptr->xml_schema_loc);
8018 		ptr->size++;
8019 
8020 		if (ptr->type == GF_ISOM_BOX_TYPE_STPP) {
8021 			if (ptr->mime_type)
8022 				ptr->size += strlen(ptr->mime_type);
8023 			ptr->size++;
8024 		}
8025 
8026 	}
8027 	//mett, sbtt, stxt
8028 	else {
8029 		if (ptr->mime_type)
8030 			ptr->size += strlen(ptr->mime_type);
8031 		ptr->size++;
8032 
8033 		if (ptr->config) {
8034 			e = gf_isom_box_size((GF_Box *)ptr->config);
8035 			if (e) return e;
8036 			ptr->size += ptr->config->size;
8037 		}
8038 	}
8039 
8040 	return gf_isom_box_array_size(s, ptr->protections);
8041 }
8042 
8043 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8044 
8045 
8046 /* SimpleTextSampleEntry */
txtc_New()8047 GF_Box *txtc_New()
8048 {
8049 	ISOM_DECL_BOX_ALLOC(GF_TextConfigBox, GF_ISOM_BOX_TYPE_TXTC);
8050 	gf_isom_full_box_init((GF_Box *)tmp);
8051 	return (GF_Box *)tmp;
8052 }
8053 
8054 
txtc_del(GF_Box * s)8055 void txtc_del(GF_Box *s)
8056 {
8057 	GF_TextConfigBox *ptr = (GF_TextConfigBox*)s;
8058 	if (ptr == NULL) return;
8059 
8060 	if (ptr->config) gf_free(ptr->config);
8061 	gf_free(ptr);
8062 }
8063 
txtc_Read(GF_Box * s,GF_BitStream * bs)8064 GF_Err txtc_Read(GF_Box *s, GF_BitStream *bs)
8065 {
8066 	GF_Err e;
8067 	u32 size, i;
8068 	char *str;
8069 	GF_TextConfigBox *ptr = (GF_TextConfigBox*)s;
8070 
8071 	e = gf_isom_full_box_read(s, bs);
8072 	if (e) return e;
8073 
8074 	size = (u32)ptr->size;
8075 	str = (char *)gf_malloc(sizeof(char)*size);
8076 
8077 	i = 0;
8078 
8079 	while (size) {
8080 		str[i] = gf_bs_read_u8(bs);
8081 		size--;
8082 		if (!str[i])
8083 			break;
8084 		i++;
8085 	}
8086 	if (i) ptr->config = gf_strdup(str);
8087 	gf_free(str);
8088 
8089 	return GF_OK;
8090 }
8091 
8092 
8093 #ifndef GPAC_DISABLE_ISOM_WRITE
8094 
txtc_Write(GF_Box * s,GF_BitStream * bs)8095 GF_Err txtc_Write(GF_Box *s, GF_BitStream *bs)
8096 {
8097 	GF_TextConfigBox *ptr = (GF_TextConfigBox *)s;
8098 	GF_Err e = gf_isom_full_box_write(s, bs);
8099 	if (e) return e;
8100 
8101 	if (ptr->config)
8102 		gf_bs_write_data(bs, ptr->config, (u32)strlen(ptr->config));
8103 	gf_bs_write_u8(bs, 0);
8104 	return GF_OK;
8105 }
8106 
txtc_Size(GF_Box * s)8107 GF_Err txtc_Size(GF_Box *s)
8108 {
8109 	GF_TextConfigBox *ptr = (GF_TextConfigBox *)s;
8110 	GF_Err e = gf_isom_full_box_get_size(s);
8111 	if (e) return e;
8112 	if (ptr->config)
8113 		ptr->size += strlen(ptr->config);
8114 	ptr->size++;
8115 	return GF_OK;
8116 }
8117 
8118 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8119 
dac3_New(u32 boxType)8120 GF_Box *dac3_New(u32 boxType)
8121 {
8122 	ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3);
8123 	if (boxType == GF_ISOM_BOX_TYPE_DEC3)
8124 		tmp->cfg.is_ec3 = 1;
8125 	return (GF_Box *)tmp;
8126 }
8127 
dac3_del(GF_Box * s)8128 void dac3_del(GF_Box *s)
8129 {
8130 	GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
8131 	gf_free(ptr);
8132 }
8133 
8134 
dac3_Read(GF_Box * s,GF_BitStream * bs)8135 GF_Err dac3_Read(GF_Box *s, GF_BitStream *bs)
8136 {
8137 	GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
8138 	if (ptr == NULL) return GF_BAD_PARAM;
8139 
8140 	if (ptr->cfg.is_ec3) {
8141 		u32 i;
8142 		ptr->cfg.brcode = gf_bs_read_int(bs, 13);
8143 		ptr->cfg.nb_streams = gf_bs_read_int(bs, 3) + 1;
8144 		for (i = 0; i<ptr->cfg.nb_streams; i++) {
8145 			ptr->cfg.streams[i].fscod = gf_bs_read_int(bs, 2);
8146 			ptr->cfg.streams[i].bsid = gf_bs_read_int(bs, 5);
8147 			ptr->cfg.streams[i].bsmod = gf_bs_read_int(bs, 5);
8148 			ptr->cfg.streams[i].acmod = gf_bs_read_int(bs, 3);
8149 			ptr->cfg.streams[i].lfon = gf_bs_read_int(bs, 1);
8150 			gf_bs_read_int(bs, 3);
8151 			ptr->cfg.streams[i].nb_dep_sub = gf_bs_read_int(bs, 4);
8152 			if (ptr->cfg.streams[i].nb_dep_sub) {
8153 				ptr->cfg.streams[i].chan_loc = gf_bs_read_int(bs, 9);
8154 			}
8155 			else {
8156 				gf_bs_read_int(bs, 1);
8157 			}
8158 		}
8159 	}
8160 	else {
8161 		ptr->cfg.nb_streams = 1;
8162 		ptr->cfg.streams[0].fscod = gf_bs_read_int(bs, 2);
8163 		ptr->cfg.streams[0].bsid = gf_bs_read_int(bs, 5);
8164 		ptr->cfg.streams[0].bsmod = gf_bs_read_int(bs, 3);
8165 		ptr->cfg.streams[0].acmod = gf_bs_read_int(bs, 3);
8166 		ptr->cfg.streams[0].lfon = gf_bs_read_int(bs, 1);
8167 		ptr->cfg.brcode = gf_bs_read_int(bs, 5);
8168 		gf_bs_read_int(bs, 5);
8169 	}
8170 	return GF_OK;
8171 }
8172 
8173 
8174 #ifndef GPAC_DISABLE_ISOM_WRITE
8175 
dac3_Write(GF_Box * s,GF_BitStream * bs)8176 GF_Err dac3_Write(GF_Box *s, GF_BitStream *bs)
8177 {
8178 	GF_Err e;
8179 	GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
8180 
8181 	if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DEC3;
8182 	e = gf_isom_box_write_header(s, bs);
8183 	if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DAC3;
8184 	if (e) return e;
8185 
8186 	if (ptr->cfg.is_ec3) {
8187 		u32 i;
8188 		gf_bs_write_int(bs, ptr->cfg.brcode, 13);
8189 		gf_bs_write_int(bs, ptr->cfg.nb_streams - 1, 3);
8190 		for (i = 0; i<ptr->cfg.nb_streams; i++) {
8191 			gf_bs_write_int(bs, ptr->cfg.streams[i].fscod, 2);
8192 			gf_bs_write_int(bs, ptr->cfg.streams[i].bsid, 5);
8193 			gf_bs_write_int(bs, ptr->cfg.streams[i].bsmod, 5);
8194 			gf_bs_write_int(bs, ptr->cfg.streams[i].acmod, 3);
8195 			gf_bs_write_int(bs, ptr->cfg.streams[i].lfon, 1);
8196 			gf_bs_write_int(bs, 0, 3);
8197 			gf_bs_write_int(bs, ptr->cfg.streams[i].nb_dep_sub, 4);
8198 			if (ptr->cfg.streams[i].nb_dep_sub) {
8199 				gf_bs_write_int(bs, ptr->cfg.streams[i].chan_loc, 9);
8200 			}
8201 			else {
8202 				gf_bs_write_int(bs, 0, 1);
8203 			}
8204 		}
8205 	}
8206 	else {
8207 		gf_bs_write_int(bs, ptr->cfg.streams[0].fscod, 2);
8208 		gf_bs_write_int(bs, ptr->cfg.streams[0].bsid, 5);
8209 		gf_bs_write_int(bs, ptr->cfg.streams[0].bsmod, 3);
8210 		gf_bs_write_int(bs, ptr->cfg.streams[0].acmod, 3);
8211 		gf_bs_write_int(bs, ptr->cfg.streams[0].lfon, 1);
8212 		gf_bs_write_int(bs, ptr->cfg.brcode, 5);
8213 		gf_bs_write_int(bs, 0, 5);
8214 	}
8215 	return GF_OK;
8216 }
8217 
dac3_Size(GF_Box * s)8218 GF_Err dac3_Size(GF_Box *s)
8219 {
8220 	GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
8221 	GF_Err e;
8222 	e = gf_isom_box_get_size(s);
8223 	if (e) return e;
8224 
8225 	if (ptr->cfg.is_ec3) {
8226 		u32 i;
8227 		s->size += 2;
8228 		for (i = 0; i<ptr->cfg.nb_streams; i++) {
8229 			s->size += 3;
8230 			if (ptr->cfg.streams[i].nb_dep_sub)
8231 				s->size += 1;
8232 		}
8233 	}
8234 	else {
8235 		s->size += 3;
8236 	}
8237 	return GF_OK;
8238 }
8239 
8240 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8241 
8242 
8243 
ac3_del(GF_Box * s)8244 void ac3_del(GF_Box *s)
8245 {
8246 	GF_AC3SampleEntryBox *ptr = (GF_AC3SampleEntryBox *)s;
8247 	if (ptr == NULL) return;
8248 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
8249 
8250 	if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info);
8251 	gf_free(ptr);
8252 }
8253 
8254 
ac3_Read(GF_Box * s,GF_BitStream * bs)8255 GF_Err ac3_Read(GF_Box *s, GF_BitStream *bs)
8256 {
8257 	GF_Err e;
8258 	GF_AC3SampleEntryBox *ptr = (GF_AC3SampleEntryBox *)s;
8259 	e = gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox*)s, bs);
8260 	if (e) return e;
8261 	e = gf_isom_parse_box((GF_Box **)&ptr->info, bs);
8262 	if (e) return e;
8263 	return GF_OK;
8264 }
8265 
ac3_New(u32 boxType)8266 GF_Box *ac3_New(u32 boxType)
8267 {
8268 	ISOM_DECL_BOX_ALLOC(GF_AC3SampleEntryBox, GF_ISOM_BOX_TYPE_AC3);
8269 	gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
8270 	if (boxType == GF_ISOM_BOX_TYPE_EC3)
8271 		tmp->is_ec3 = 1;
8272 	return (GF_Box *)tmp;
8273 }
8274 
8275 
8276 #ifndef GPAC_DISABLE_ISOM_WRITE
8277 
ac3_Write(GF_Box * s,GF_BitStream * bs)8278 GF_Err ac3_Write(GF_Box *s, GF_BitStream *bs)
8279 {
8280 	GF_Err e;
8281 	GF_AC3SampleEntryBox *ptr = (GF_AC3SampleEntryBox *)s;
8282 	if (ptr->is_ec3) s->type = GF_ISOM_BOX_TYPE_EC3;
8283 	e = gf_isom_box_write_header(s, bs);
8284 	if (ptr->is_ec3) s->type = GF_ISOM_BOX_TYPE_AC3;
8285 	if (e) return e;
8286 	gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs);
8287 	return gf_isom_box_write((GF_Box *)ptr->info, bs);
8288 }
8289 
ac3_Size(GF_Box * s)8290 GF_Err ac3_Size(GF_Box *s)
8291 {
8292 	GF_Err e;
8293 	GF_AC3SampleEntryBox *ptr = (GF_AC3SampleEntryBox *)s;
8294 	e = gf_isom_box_get_size(s);
8295 	if (e) return e;
8296 	gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox*)s);
8297 	e = gf_isom_box_size((GF_Box *)ptr->info);
8298 	if (e) return e;
8299 	ptr->size += ptr->info->size;
8300 	return GF_OK;
8301 }
8302 
8303 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8304 
8305 
lsrc_del(GF_Box * s)8306 void lsrc_del(GF_Box *s)
8307 {
8308 	GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
8309 	if (ptr == NULL) return;
8310 	if (ptr->hdr) gf_free(ptr->hdr);
8311 	gf_free(ptr);
8312 }
8313 
8314 
lsrc_Read(GF_Box * s,GF_BitStream * bs)8315 GF_Err lsrc_Read(GF_Box *s, GF_BitStream *bs)
8316 {
8317 	GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
8318 	ptr->hdr_size = (u32)ptr->size;
8319 	ptr->hdr = gf_malloc(sizeof(char)*ptr->hdr_size);
8320 	gf_bs_read_data(bs, ptr->hdr, ptr->hdr_size);
8321 	return GF_OK;
8322 }
8323 
lsrc_New()8324 GF_Box *lsrc_New()
8325 {
8326 	ISOM_DECL_BOX_ALLOC(GF_LASERConfigurationBox, GF_ISOM_BOX_TYPE_LSRC);
8327 	return (GF_Box *)tmp;
8328 }
8329 
8330 
8331 #ifndef GPAC_DISABLE_ISOM_WRITE
8332 
lsrc_Write(GF_Box * s,GF_BitStream * bs)8333 GF_Err lsrc_Write(GF_Box *s, GF_BitStream *bs)
8334 {
8335 	GF_Err e;
8336 	GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
8337 	e = gf_isom_box_write_header(s, bs);
8338 	if (e) return e;
8339 	gf_bs_write_data(bs, ptr->hdr, ptr->hdr_size);
8340 	return GF_OK;
8341 }
8342 
lsrc_Size(GF_Box * s)8343 GF_Err lsrc_Size(GF_Box *s)
8344 {
8345 	GF_Err e;
8346 	GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
8347 	e = gf_isom_box_get_size(s);
8348 	if (e) return e;
8349 	ptr->size += ptr->hdr_size;
8350 	return GF_OK;
8351 }
8352 
8353 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8354 
8355 
lsr1_del(GF_Box * s)8356 void lsr1_del(GF_Box *s)
8357 {
8358 	GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
8359 	if (ptr == NULL) return;
8360 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
8361 
8362 	if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
8363 	if (ptr->lsr_config) gf_isom_box_del((GF_Box *)ptr->lsr_config);
8364 	if (ptr->descr) gf_isom_box_del((GF_Box *)ptr->descr);
8365 	gf_free(ptr);
8366 }
8367 
lsr1_AddBox(GF_Box * s,GF_Box * a)8368 GF_Err lsr1_AddBox(GF_Box *s, GF_Box *a)
8369 {
8370 	GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
8371 	switch (a->type) {
8372 	case GF_ISOM_BOX_TYPE_LSRC:
8373 		if (ptr->lsr_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
8374 			ptr->lsr_config = (GF_LASERConfigurationBox *)a;
8375 		break;
8376 	case GF_ISOM_BOX_TYPE_M4DS:
8377 		if (ptr->descr) ERROR_ON_DUPLICATED_BOX(a, ptr)
8378 			ptr->descr = (GF_MPEG4ExtensionDescriptorsBox *)a;
8379 		break;
8380 	default:
8381 		return gf_isom_box_add_default(s, a);
8382 	}
8383 	return GF_OK;
8384 }
8385 
lsr1_Read(GF_Box * s,GF_BitStream * bs)8386 GF_Err lsr1_Read(GF_Box *s, GF_BitStream *bs)
8387 {
8388 	GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox*)s;
8389 	gf_bs_read_data(bs, ptr->reserved, 6);
8390 	ptr->dataReferenceIndex = gf_bs_read_u16(bs);
8391 	ptr->size -= 8;
8392 	return gf_isom_read_box_list(s, bs, lsr1_AddBox);
8393 }
8394 
lsr1_New()8395 GF_Box *lsr1_New()
8396 {
8397 	ISOM_DECL_BOX_ALLOC(GF_LASeRSampleEntryBox, GF_ISOM_BOX_TYPE_LSR1);
8398 	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
8399 	return (GF_Box *)tmp;
8400 }
8401 
8402 
8403 #ifndef GPAC_DISABLE_ISOM_WRITE
8404 
8405 
lsr1_Write(GF_Box * s,GF_BitStream * bs)8406 GF_Err lsr1_Write(GF_Box *s, GF_BitStream *bs)
8407 {
8408 	GF_Err e;
8409 	GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
8410 	e = gf_isom_box_write_header(s, bs);
8411 	if (e) return e;
8412 
8413 	gf_bs_write_data(bs, ptr->reserved, 6);
8414 	gf_bs_write_u16(bs, ptr->dataReferenceIndex);
8415 	if (ptr->lsr_config) {
8416 		e = gf_isom_box_write((GF_Box *)ptr->lsr_config, bs);
8417 		if (e) return e;
8418 	}
8419 	if (ptr->descr) {
8420 		e = gf_isom_box_write((GF_Box *)ptr->descr, bs);
8421 		if (e) return e;
8422 	}
8423 	return e;
8424 }
8425 
lsr1_Size(GF_Box * s)8426 GF_Err lsr1_Size(GF_Box *s)
8427 {
8428 	GF_Err e;
8429 	GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
8430 	e = gf_isom_box_get_size(s);
8431 	if (e) return e;
8432 	s->size += 8;
8433 	if (ptr->lsr_config) {
8434 		e = gf_isom_box_size((GF_Box *)ptr->lsr_config);
8435 		if (e) return e;
8436 		ptr->size += ptr->lsr_config->size;
8437 	}
8438 	if (ptr->descr) {
8439 		e = gf_isom_box_size((GF_Box *)ptr->descr);
8440 		if (e) return e;
8441 		ptr->size += ptr->descr->size;
8442 	}
8443 	return GF_OK;
8444 }
8445 
8446 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8447 
8448 
sidx_del(GF_Box * s)8449 void sidx_del(GF_Box *s)
8450 {
8451 	GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox *)s;
8452 	if (ptr == NULL) return;
8453 	if (ptr->refs) gf_free(ptr->refs);
8454 	gf_free(ptr);
8455 }
8456 
sidx_Read(GF_Box * s,GF_BitStream * bs)8457 GF_Err sidx_Read(GF_Box *s, GF_BitStream *bs)
8458 {
8459 	GF_Err e;
8460 	u32 i;
8461 	GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*)s;
8462 	e = gf_isom_full_box_read(s, bs);
8463 	if (e) return e;
8464 	ptr->reference_ID = gf_bs_read_u32(bs);
8465 	ptr->timescale = gf_bs_read_u32(bs);
8466 	ptr->size -= 8;
8467 	if (ptr->version == 0) {
8468 		ptr->earliest_presentation_time = gf_bs_read_u32(bs);
8469 		ptr->first_offset = gf_bs_read_u32(bs);
8470 		ptr->size -= 8;
8471 	}
8472 	else {
8473 		ptr->earliest_presentation_time = gf_bs_read_u64(bs);
8474 		ptr->first_offset = gf_bs_read_u64(bs);
8475 		ptr->size -= 16;
8476 	}
8477 	gf_bs_read_u16(bs); /* reserved */
8478 	ptr->nb_refs = gf_bs_read_u16(bs);
8479 	ptr->size -= 4;
8480 	ptr->refs = gf_malloc(sizeof(GF_SIDXReference)*ptr->nb_refs);
8481 	for (i = 0; i<ptr->nb_refs; i++) {
8482 		ptr->refs[i].reference_type = gf_bs_read_int(bs, 1);
8483 		ptr->refs[i].reference_size = gf_bs_read_int(bs, 31);
8484 		ptr->refs[i].subsegment_duration = gf_bs_read_u32(bs);
8485 		ptr->refs[i].starts_with_SAP = gf_bs_read_int(bs, 1);
8486 		ptr->refs[i].SAP_type = gf_bs_read_int(bs, 3);
8487 		ptr->refs[i].SAP_delta_time = gf_bs_read_int(bs, 28);
8488 		ptr->size -= 12;
8489 	}
8490 	return GF_OK;
8491 }
8492 
sidx_New()8493 GF_Box *sidx_New()
8494 {
8495 	ISOM_DECL_BOX_ALLOC(GF_SegmentIndexBox, GF_ISOM_BOX_TYPE_SIDX);
8496 	gf_isom_full_box_init((GF_Box *)tmp);
8497 	return (GF_Box *)tmp;
8498 }
8499 
8500 
8501 #ifndef GPAC_DISABLE_ISOM_WRITE
8502 
sidx_Write(GF_Box * s,GF_BitStream * bs)8503 GF_Err sidx_Write(GF_Box *s, GF_BitStream *bs)
8504 {
8505 	GF_Err e;
8506 	u32 i;
8507 	GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*)s;
8508 
8509 	e = gf_isom_full_box_write(s, bs);
8510 	if (e) return e;
8511 
8512 	gf_bs_write_u32(bs, ptr->reference_ID);
8513 	gf_bs_write_u32(bs, ptr->timescale);
8514 	if (ptr->version == 0) {
8515 		gf_bs_write_u32(bs, (u32)ptr->earliest_presentation_time);
8516 		gf_bs_write_u32(bs, (u32)ptr->first_offset);
8517 	}
8518 	else {
8519 		gf_bs_write_u64(bs, ptr->earliest_presentation_time);
8520 		gf_bs_write_u64(bs, ptr->first_offset);
8521 	}
8522 	gf_bs_write_u16(bs, 0);
8523 	gf_bs_write_u16(bs, ptr->nb_refs);
8524 	for (i = 0; i<ptr->nb_refs; i++) {
8525 		gf_bs_write_int(bs, ptr->refs[i].reference_type, 1);
8526 		gf_bs_write_int(bs, ptr->refs[i].reference_size, 31);
8527 		gf_bs_write_u32(bs, ptr->refs[i].subsegment_duration);
8528 		gf_bs_write_int(bs, ptr->refs[i].starts_with_SAP, 1);
8529 		gf_bs_write_int(bs, ptr->refs[i].SAP_type, 3);
8530 		gf_bs_write_int(bs, ptr->refs[i].SAP_delta_time, 28);
8531 	}
8532 	return GF_OK;
8533 }
8534 
sidx_Size(GF_Box * s)8535 GF_Err sidx_Size(GF_Box *s)
8536 {
8537 	GF_Err e;
8538 	GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*)s;
8539 	e = gf_isom_full_box_get_size(s);
8540 	if (e) return e;
8541 
8542 	ptr->size += 12;
8543 	if (ptr->version == 0) {
8544 		ptr->size += 8;
8545 	}
8546 	else {
8547 		ptr->size += 16;
8548 	}
8549 	ptr->size += ptr->nb_refs * 12;
8550 	return GF_OK;
8551 }
8552 
8553 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8554 
pcrb_New()8555 GF_Box *pcrb_New()
8556 {
8557 	ISOM_DECL_BOX_ALLOC(GF_PcrInfoBox, GF_ISOM_BOX_TYPE_PCRB);
8558 	return (GF_Box *)tmp;
8559 }
8560 
pcrb_del(GF_Box * s)8561 void pcrb_del(GF_Box *s)
8562 {
8563 	GF_PcrInfoBox *ptr = (GF_PcrInfoBox *)s;
8564 	if (ptr == NULL) return;
8565 	if (ptr->pcr_values) gf_free(ptr->pcr_values);
8566 	gf_free(ptr);
8567 }
8568 
pcrb_Read(GF_Box * s,GF_BitStream * bs)8569 GF_Err pcrb_Read(GF_Box *s, GF_BitStream *bs)
8570 {
8571 	u32 i;
8572 	GF_PcrInfoBox *ptr = (GF_PcrInfoBox*)s;
8573 
8574 	ptr->subsegment_count = gf_bs_read_u32(bs);
8575 	ptr->size -= 4;
8576 
8577 	ptr->pcr_values = gf_malloc(sizeof(u64)*ptr->subsegment_count);
8578 	for (i = 0; i<ptr->subsegment_count; i++) {
8579 		u64 data1 = gf_bs_read_u32(bs);
8580 		u64 data2 = gf_bs_read_u16(bs);
8581 		ptr->size -= 6;
8582 		ptr->pcr_values[i] = (data1 << 10) | (data2 >> 6);
8583 
8584 	}
8585 	return GF_OK;
8586 }
8587 
8588 #ifndef GPAC_DISABLE_ISOM_WRITE
8589 
pcrb_Write(GF_Box * s,GF_BitStream * bs)8590 GF_Err pcrb_Write(GF_Box *s, GF_BitStream *bs)
8591 {
8592 	GF_Err e;
8593 	u32 i;
8594 	GF_PcrInfoBox *ptr = (GF_PcrInfoBox*)s;
8595 
8596 	e = gf_isom_box_write_header(s, bs);
8597 	if (e) return e;
8598 
8599 	gf_bs_write_u32(bs, ptr->subsegment_count);
8600 
8601 	for (i = 0; i<ptr->subsegment_count; i++) {
8602 		u32 data1 = (u32)(ptr->pcr_values[i] >> 10);
8603 		u16 data2 = (u16)(ptr->pcr_values[i] << 6);
8604 
8605 		gf_bs_write_u32(bs, data1);
8606 		gf_bs_write_u16(bs, data2);
8607 	}
8608 	return GF_OK;
8609 }
8610 
pcrb_Size(GF_Box * s)8611 GF_Err pcrb_Size(GF_Box *s)
8612 {
8613 	GF_Err e;
8614 	GF_PcrInfoBox *ptr = (GF_PcrInfoBox*)s;
8615 	e = gf_isom_box_get_size(s);
8616 	if (e) return e;
8617 
8618 	ptr->size += 4;
8619 	ptr->size += ptr->subsegment_count * 6;
8620 
8621 	return GF_OK;
8622 }
8623 
8624 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8625 
8626 
subs_New()8627 GF_Box *subs_New()
8628 {
8629 	ISOM_DECL_BOX_ALLOC(GF_SubSampleInformationBox, GF_ISOM_BOX_TYPE_SUBS);
8630 	tmp->Samples = gf_list_new();
8631 	return (GF_Box *)tmp;
8632 }
8633 
subs_del(GF_Box * s)8634 void subs_del(GF_Box *s)
8635 {
8636 	GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
8637 	if (ptr == NULL) return;
8638 
8639 	while (gf_list_count(ptr->Samples)) {
8640 		GF_SubSampleInfoEntry *pSamp;
8641 		pSamp = (GF_SubSampleInfoEntry*)gf_list_get(ptr->Samples, 0);
8642 		while (gf_list_count(pSamp->SubSamples)) {
8643 			GF_SubSampleEntry *pSubSamp;
8644 			pSubSamp = (GF_SubSampleEntry*)gf_list_get(pSamp->SubSamples, 0);
8645 			gf_free(pSubSamp);
8646 			gf_list_rem(pSamp->SubSamples, 0);
8647 		}
8648 		gf_list_del(pSamp->SubSamples);
8649 		gf_free(pSamp);
8650 		gf_list_rem(ptr->Samples, 0);
8651 	}
8652 	gf_list_del(ptr->Samples);
8653 	gf_free(ptr);
8654 }
8655 
8656 
8657 #ifndef GPAC_DISABLE_ISOM_WRITE
8658 
subs_Write(GF_Box * s,GF_BitStream * bs)8659 GF_Err subs_Write(GF_Box *s, GF_BitStream *bs)
8660 {
8661 	GF_Err e;
8662 	u32 i, j, entry_count;
8663 	u16 subsample_count;
8664 	GF_SubSampleInfoEntry *pSamp;
8665 	GF_SubSampleEntry *pSubSamp;
8666 	GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
8667 
8668 	if (!s) return GF_BAD_PARAM;
8669 	e = gf_isom_full_box_write(s, bs);
8670 	if (e) return e;
8671 	entry_count = gf_list_count(ptr->Samples);
8672 	gf_bs_write_u32(bs, entry_count);
8673 
8674 	for (i = 0; i<entry_count; i++) {
8675 		pSamp = (GF_SubSampleInfoEntry*)gf_list_get(ptr->Samples, i);
8676 		subsample_count = gf_list_count(pSamp->SubSamples);
8677 		gf_bs_write_u32(bs, pSamp->sample_delta);
8678 		gf_bs_write_u16(bs, subsample_count);
8679 
8680 		for (j = 0; j<subsample_count; j++) {
8681 			pSubSamp = (GF_SubSampleEntry*)gf_list_get(pSamp->SubSamples, j);
8682 			if (ptr->version == 1) {
8683 				gf_bs_write_u32(bs, pSubSamp->subsample_size);
8684 			}
8685 			else {
8686 				gf_bs_write_u16(bs, pSubSamp->subsample_size);
8687 			}
8688 			gf_bs_write_u8(bs, pSubSamp->subsample_priority);
8689 			gf_bs_write_u8(bs, pSubSamp->discardable);
8690 			gf_bs_write_u32(bs, pSubSamp->reserved);
8691 		}
8692 	}
8693 	return e;
8694 }
8695 
subs_Size(GF_Box * s)8696 GF_Err subs_Size(GF_Box *s)
8697 {
8698 	GF_Err e;
8699 	GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
8700 	GF_SubSampleInfoEntry *pSamp;
8701 	u32 entry_count, i;
8702 	u16 subsample_count;
8703 
8704 	// determine the size of the full box
8705 	e = gf_isom_full_box_get_size(s);
8706 	if (e) return e;
8707 
8708 	// add 4 byte for entry_count
8709 	ptr->size += 4;
8710 	entry_count = gf_list_count(ptr->Samples);
8711 	for (i = 0; i<entry_count; i++) {
8712 		pSamp = (GF_SubSampleInfoEntry*)gf_list_get(ptr->Samples, i);
8713 		subsample_count = gf_list_count(pSamp->SubSamples);
8714 		// 4 byte for sample_delta, 2 byte for subsample_count
8715 		// and 6 + (4 or 2) bytes for each subsample
8716 		ptr->size += 4 + 2 + subsample_count * (6 + (ptr->version == 1 ? 4 : 2));
8717 	}
8718 	return GF_OK;
8719 }
8720 
8721 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8722 
subs_Read(GF_Box * s,GF_BitStream * bs)8723 GF_Err subs_Read(GF_Box *s, GF_BitStream *bs)
8724 {
8725 	GF_Err e;
8726 	GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
8727 	u32 entry_count, i, j;
8728 	u16 subsample_count;
8729 
8730 	e = gf_isom_full_box_read(s, bs);
8731 	if (e) return e;
8732 
8733 	entry_count = gf_bs_read_u32(bs);
8734 	ptr->size -= 4;
8735 
8736 	for (i = 0; i<entry_count; i++) {
8737 		GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*)gf_malloc(sizeof(GF_SubSampleInfoEntry));
8738 		if (!pSamp) return GF_OUT_OF_MEM;
8739 
8740 		memset(pSamp, 0, sizeof(GF_SubSampleInfoEntry));
8741 		pSamp->SubSamples = gf_list_new();
8742 		pSamp->sample_delta = gf_bs_read_u32(bs);
8743 		if (!i && !pSamp->sample_delta) {
8744 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] first entry in SubSample has sample_delta of 0, should be one. Fixing\n"));
8745 			pSamp->sample_delta = 1;
8746 		}
8747 		subsample_count = gf_bs_read_u16(bs);
8748 
8749 		for (j = 0; j<subsample_count; j++) {
8750 			GF_SubSampleEntry *pSubSamp = (GF_SubSampleEntry*)gf_malloc(sizeof(GF_SubSampleEntry));
8751 			if (!pSubSamp) return GF_OUT_OF_MEM;
8752 
8753 			memset(pSubSamp, 0, sizeof(GF_SubSampleEntry));
8754 			if (ptr->version == 1) {
8755 				pSubSamp->subsample_size = gf_bs_read_u32(bs);
8756 			}
8757 			else {
8758 				pSubSamp->subsample_size = gf_bs_read_u16(bs);
8759 			}
8760 			pSubSamp->subsample_priority = gf_bs_read_u8(bs);
8761 			pSubSamp->discardable = gf_bs_read_u8(bs);
8762 			pSubSamp->reserved = gf_bs_read_u32(bs);
8763 
8764 			gf_list_add(pSamp->SubSamples, pSubSamp);
8765 		}
8766 		gf_list_add(ptr->Samples, pSamp);
8767 	}
8768 	return GF_OK;
8769 }
8770 
8771 
8772 #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
8773 
tfdt_New()8774 GF_Box *tfdt_New()
8775 {
8776 	ISOM_DECL_BOX_ALLOC(GF_TFBaseMediaDecodeTimeBox, GF_ISOM_BOX_TYPE_TFDT);
8777 	return (GF_Box *)tmp;
8778 }
8779 
tfdt_del(GF_Box * s)8780 void tfdt_del(GF_Box *s)
8781 {
8782 	gf_free(s);
8783 }
8784 
8785 /*this is using chpl format according to some NeroRecode samples*/
tfdt_Read(GF_Box * s,GF_BitStream * bs)8786 GF_Err tfdt_Read(GF_Box *s, GF_BitStream *bs)
8787 {
8788 	GF_Err e;
8789 	GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s;
8790 	e = gf_isom_full_box_read(s, bs);
8791 	if (e) return e;
8792 
8793 	if (ptr->version == 1) {
8794 		ptr->baseMediaDecodeTime = gf_bs_read_u64(bs);
8795 		ptr->size -= 8;
8796 	}
8797 	else {
8798 		ptr->baseMediaDecodeTime = (u32)gf_bs_read_u32(bs);
8799 		ptr->size -= 4;
8800 	}
8801 	return GF_OK;
8802 }
8803 
8804 #ifndef GPAC_DISABLE_ISOM_WRITE
8805 
tfdt_Write(GF_Box * s,GF_BitStream * bs)8806 GF_Err tfdt_Write(GF_Box *s, GF_BitStream *bs)
8807 {
8808 	GF_Err e;
8809 	GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s;
8810 	e = gf_isom_full_box_write(s, bs);
8811 	if (e) return e;
8812 
8813 	if (ptr->version == 1) {
8814 		gf_bs_write_u64(bs, ptr->baseMediaDecodeTime);
8815 	}
8816 	else {
8817 		gf_bs_write_u32(bs, (u32)ptr->baseMediaDecodeTime);
8818 	}
8819 	return GF_OK;
8820 }
8821 
tfdt_Size(GF_Box * s)8822 GF_Err tfdt_Size(GF_Box *s)
8823 {
8824 	GF_Err e;
8825 	GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s;
8826 	e = gf_isom_full_box_get_size(s);
8827 	if (e) return e;
8828 	if (ptr->baseMediaDecodeTime <= 0xFFFFFFFF) {
8829 		ptr->version = 0;
8830 		ptr->size += 4;
8831 	}
8832 	else {
8833 		ptr->version = 1;
8834 		ptr->size += 8;
8835 	}
8836 	return GF_OK;
8837 }
8838 
8839 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8840 
8841 #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
8842 
8843 
rvcc_New()8844 GF_Box *rvcc_New()
8845 {
8846 	ISOM_DECL_BOX_ALLOC(GF_RVCConfigurationBox, GF_ISOM_BOX_TYPE_RVCC);
8847 	return (GF_Box *)tmp;
8848 }
8849 
rvcc_del(GF_Box * s)8850 void rvcc_del(GF_Box *s)
8851 {
8852 	gf_free(s);
8853 }
8854 
rvcc_Read(GF_Box * s,GF_BitStream * bs)8855 GF_Err rvcc_Read(GF_Box *s, GF_BitStream *bs)
8856 {
8857 	GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*)s;
8858 	ptr->predefined_rvc_config = gf_bs_read_u16(bs);
8859 	ptr->size -= 2;
8860 	if (!ptr->predefined_rvc_config) {
8861 		ptr->rvc_meta_idx = gf_bs_read_u16(bs);
8862 		ptr->size -= 2;
8863 	}
8864 	return GF_OK;
8865 }
8866 
8867 #ifndef GPAC_DISABLE_ISOM_WRITE
8868 
rvcc_Write(GF_Box * s,GF_BitStream * bs)8869 GF_Err rvcc_Write(GF_Box *s, GF_BitStream *bs)
8870 {
8871 	GF_Err e;
8872 	GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*)s;
8873 
8874 	e = gf_isom_box_write_header(s, bs);
8875 	if (e) return e;
8876 
8877 	gf_bs_write_u16(bs, ptr->predefined_rvc_config);
8878 	if (!ptr->predefined_rvc_config) {
8879 		gf_bs_write_u16(bs, ptr->rvc_meta_idx);
8880 	}
8881 	return GF_OK;
8882 }
8883 
rvcc_Size(GF_Box * s)8884 GF_Err rvcc_Size(GF_Box *s)
8885 {
8886 	GF_Err e;
8887 	GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox *)s;
8888 	e = gf_isom_box_get_size(s);
8889 	if (e) return e;
8890 	ptr->size += 2;
8891 	if (!ptr->predefined_rvc_config) ptr->size += 2;
8892 	return GF_OK;
8893 }
8894 
8895 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8896 
8897 
8898 
sbgp_New()8899 GF_Box *sbgp_New()
8900 {
8901 	ISOM_DECL_BOX_ALLOC(GF_SampleGroupBox, GF_ISOM_BOX_TYPE_SBGP);
8902 	return (GF_Box *)tmp;
8903 }
sbgp_del(GF_Box * a)8904 void sbgp_del(GF_Box *a)
8905 {
8906 	GF_SampleGroupBox *p = (GF_SampleGroupBox *)a;
8907 	if (p->sample_entries) gf_free(p->sample_entries);
8908 	gf_free(p);
8909 }
8910 
sbgp_Read(GF_Box * s,GF_BitStream * bs)8911 GF_Err sbgp_Read(GF_Box *s, GF_BitStream *bs)
8912 {
8913 	u32 i;
8914 	GF_SampleGroupBox *p = (GF_SampleGroupBox *)s;
8915 	GF_Err e = gf_isom_full_box_read(s, bs);
8916 	if (e) return e;
8917 
8918 	p->grouping_type = gf_bs_read_u32(bs);
8919 	p->size -= 4;
8920 	if (p->version == 1) {
8921 		p->grouping_type_parameter = gf_bs_read_u32(bs);
8922 		p->size -= 4;
8923 	}
8924 	p->entry_count = gf_bs_read_u32(bs);
8925 	p->size -= 4;
8926 	p->sample_entries = gf_malloc(sizeof(GF_SampleGroupEntry)*p->entry_count);
8927 	if (!p->sample_entries) return GF_IO_ERR;
8928 	for (i = 0; i<p->entry_count; i++) {
8929 		p->sample_entries[i].sample_count = gf_bs_read_u32(bs);
8930 		p->sample_entries[i].group_description_index = gf_bs_read_u32(bs);
8931 		p->size -= 8;
8932 	}
8933 	return GF_OK;
8934 }
8935 
8936 #ifndef GPAC_DISABLE_ISOM_WRITE
sbgp_Write(GF_Box * s,GF_BitStream * bs)8937 GF_Err sbgp_Write(GF_Box *s, GF_BitStream *bs)
8938 {
8939 	u32 i;
8940 	GF_Err e;
8941 	GF_SampleGroupBox *p = (GF_SampleGroupBox*)s;
8942 
8943 	e = gf_isom_full_box_write(s, bs);
8944 	if (e) return e;
8945 	gf_bs_write_u32(bs, p->grouping_type);
8946 	if (p->version == 1)
8947 		gf_bs_write_u32(bs, p->grouping_type_parameter);
8948 
8949 	gf_bs_write_u32(bs, p->entry_count);
8950 	for (i = 0; i<p->entry_count; i++) {
8951 		gf_bs_write_u32(bs, p->sample_entries[i].sample_count);
8952 		gf_bs_write_u32(bs, p->sample_entries[i].group_description_index);
8953 	}
8954 	return GF_OK;
8955 }
8956 
sbgp_Size(GF_Box * s)8957 GF_Err sbgp_Size(GF_Box *s)
8958 {
8959 	GF_Err e;
8960 	GF_SampleGroupBox *p = (GF_SampleGroupBox*)s;
8961 	e = gf_isom_full_box_get_size(s);
8962 	if (e) return e;
8963 	p->size += 8;
8964 	if (p->grouping_type_parameter) p->version = 1;
8965 
8966 	if (p->version == 1) p->size += 4;
8967 	p->size += 8 * p->entry_count;
8968 	return GF_OK;
8969 }
8970 
8971 #endif /*GPAC_DISABLE_ISOM_WRITE*/
8972 
sgpd_parse_entry(u32 grouping_type,GF_BitStream * bs,u32 entry_size,u32 * total_bytes)8973 static void *sgpd_parse_entry(u32 grouping_type, GF_BitStream *bs, u32 entry_size, u32 *total_bytes)
8974 {
8975 	GF_DefaultSampleGroupDescriptionEntry *ptr;
8976 	switch (grouping_type) {
8977 	case GF_4CC('r', 'o', 'l', 'l'):
8978 	{
8979 		GF_RollRecoveryEntry *ptr;
8980 		GF_SAFEALLOC(ptr, GF_RollRecoveryEntry);
8981 		if (!ptr) return NULL;
8982 		ptr->roll_distance = gf_bs_read_int(bs, 16);
8983 		*total_bytes = 2;
8984 		return ptr;
8985 	}
8986 	case GF_4CC('r', 'a', 'p', ' '):
8987 	{
8988 		GF_VisualRandomAccessEntry *ptr;
8989 		GF_SAFEALLOC(ptr, GF_VisualRandomAccessEntry);
8990 		if (!ptr) return NULL;
8991 		ptr->num_leading_samples_known = gf_bs_read_int(bs, 1);
8992 		ptr->num_leading_samples = gf_bs_read_int(bs, 7);
8993 		*total_bytes = 1;
8994 		return ptr;
8995 	}
8996 	case GF_4CC('s', 'e', 'i', 'g'):
8997 	{
8998 		GF_CENCSampleEncryptionGroupEntry *ptr;
8999 		GF_SAFEALLOC(ptr, GF_CENCSampleEncryptionGroupEntry);
9000 		if (!ptr) return NULL;
9001 		gf_bs_read_u8(bs); //reserved
9002 		ptr->crypt_byte_block = gf_bs_read_int(bs, 4);
9003 		ptr->skip_byte_block = gf_bs_read_int(bs, 4);
9004 		ptr->IsProtected = gf_bs_read_u8(bs);
9005 		ptr->Per_Sample_IV_size = gf_bs_read_u8(bs);
9006 		gf_bs_read_data(bs, (char *)ptr->KID, 16);
9007 		*total_bytes = 20;
9008 		if ((ptr->IsProtected == 1) && !ptr->Per_Sample_IV_size) {
9009 			ptr->constant_IV_size = gf_bs_read_u8(bs);
9010 			assert((ptr->constant_IV_size == 8) || (ptr->constant_IV_size == 16));
9011 			gf_bs_read_data(bs, (char *)ptr->constant_IV, ptr->constant_IV_size);
9012 			*total_bytes += 1 + ptr->constant_IV_size;
9013 		}
9014 		if (!entry_size) {
9015 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] seig sample group does not indicate entry size, deprecated in spec\n"));
9016 		}
9017 		return ptr;
9018 	}
9019 	case GF_4CC('o', 'i', 'n', 'f'):
9020 	{
9021 		GF_OperatingPointsInformation *ptr = gf_isom_oinf_new_entry();
9022 		u32 s = (u32)gf_bs_get_position(bs);
9023 		gf_isom_oinf_read_entry(ptr, bs);
9024 		*total_bytes = (u32)gf_bs_get_position(bs) - s;
9025 		if (!entry_size) {
9026 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] oinf sample group does not indicate entry size, deprecated in spec\n"));
9027 		}
9028 		return ptr;
9029 	}
9030 	case GF_4CC('l', 'i', 'n', 'f'):
9031 	{
9032 		GF_LHVCLayerInformation *ptr = gf_isom_linf_new_entry();
9033 		u32 s = (u32)gf_bs_get_position(bs);
9034 		gf_isom_linf_read_entry(ptr, bs);
9035 		*total_bytes = (u32)gf_bs_get_position(bs) - s;
9036 		if (!entry_size) {
9037 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] linf sample group does not indicate entry size, deprecated in spec\n"));
9038 		}
9039 		return ptr;
9040 	}
9041 
9042 	case GF_4CC('t', 'r', 'i', 'f'):
9043 		if (!entry_size) {
9044 			u32 flags = gf_bs_peek_bits(bs, 24, 0);
9045 			if (flags & 0x10000) entry_size = 3;
9046 			else {
9047 				if (flags & 0x80000) entry_size = 7;
9048 				else entry_size = 11;
9049 				//have dependency list
9050 				if (flags & 0x200000) {
9051 					u32 nb_entries = gf_bs_peek_bits(bs, 16, entry_size);
9052 					entry_size += 2 + 2 * nb_entries;
9053 				}
9054 			}
9055 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] trif sample group does not indicate entry size, deprecated in spec\n"));
9056 		}
9057 		//fallthrough
9058 		break;
9059 	case GF_4CC('n', 'a', 'l', 'm'):
9060 		if (!entry_size) {
9061 			u64 start = gf_bs_get_position(bs);
9062 			Bool rle, large_size;
9063 			u32 entry_count;
9064 			gf_bs_read_int(bs, 6);
9065 			large_size = gf_bs_read_int(bs, 1);
9066 			rle = gf_bs_read_int(bs, 1);
9067 			entry_count = gf_bs_read_int(bs, large_size ? 16 : 8);
9068 			gf_bs_seek(bs, start);
9069 			entry_size = 1 + large_size ? 2 : 1;
9070 			entry_size += entry_count * 2;
9071 			if (rle) entry_size += entry_count * (large_size ? 2 : 1);
9072 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] nalm sample group does not indicate entry size, deprecated in spec\n"));
9073 		}
9074 		break;
9075 	default:
9076 		break;
9077 	}
9078 
9079 	if (!entry_size) {
9080 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] %s sample group does not indicate entry size, cannot parse!\n", gf_4cc_to_str(grouping_type)));
9081 		return NULL;
9082 	}
9083 	GF_SAFEALLOC(ptr, GF_DefaultSampleGroupDescriptionEntry);
9084 	if (!ptr) return NULL;
9085 	ptr->length = entry_size;
9086 	ptr->data = (u8 *)gf_malloc(sizeof(u8)*ptr->length);
9087 	gf_bs_read_data(bs, (char *)ptr->data, ptr->length);
9088 	*total_bytes = entry_size;
9089 	return ptr;
9090 }
9091 
sgpd_del_entry(u32 grouping_type,void * entry)9092 static void	sgpd_del_entry(u32 grouping_type, void *entry)
9093 {
9094 	switch (grouping_type) {
9095 	case GF_4CC('r', 'o', 'l', 'l'):
9096 	case GF_4CC('r', 'a', 'p', ' '):
9097 	case GF_4CC('s', 'e', 'i', 'g'):
9098 		gf_free(entry);
9099 		return;
9100 	case GF_4CC('o', 'i', 'n', 'f'):
9101 		gf_isom_oinf_del_entry(entry);
9102 		return;
9103 	case GF_4CC('l', 'i', 'n', 'f'):
9104 		gf_isom_linf_del_entry(entry);
9105 		return;
9106 	default:
9107 	{
9108 		GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
9109 		if (ptr->data) gf_free(ptr->data);
9110 		gf_free(ptr);
9111 	}
9112 
9113 	}
9114 }
9115 
sgpd_write_entry(u32 grouping_type,void * entry,GF_BitStream * bs)9116 void sgpd_write_entry(u32 grouping_type, void *entry, GF_BitStream *bs)
9117 {
9118 	switch (grouping_type) {
9119 	case GF_4CC('r', 'o', 'l', 'l'):
9120 		gf_bs_write_int(bs, ((GF_RollRecoveryEntry*)entry)->roll_distance, 16);
9121 		return;
9122 	case GF_4CC('r', 'a', 'p', ' '):
9123 		gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples_known, 1);
9124 		gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples, 7);
9125 		return;
9126 	case GF_4CC('s', 'e', 'i', 'g'):
9127 		gf_bs_write_u8(bs, 0x0);
9128 		gf_bs_write_int(bs, ((GF_CENCSampleEncryptionGroupEntry*)entry)->crypt_byte_block, 4);
9129 		gf_bs_write_int(bs, ((GF_CENCSampleEncryptionGroupEntry*)entry)->skip_byte_block, 4);
9130 		gf_bs_write_u8(bs, ((GF_CENCSampleEncryptionGroupEntry *)entry)->IsProtected);
9131 		gf_bs_write_u8(bs, ((GF_CENCSampleEncryptionGroupEntry *)entry)->Per_Sample_IV_size);
9132 		gf_bs_write_data(bs, (char *)((GF_CENCSampleEncryptionGroupEntry *)entry)->KID, 16);
9133 		if ((((GF_CENCSampleEncryptionGroupEntry *)entry)->IsProtected == 1) && !((GF_CENCSampleEncryptionGroupEntry *)entry)->Per_Sample_IV_size) {
9134 			gf_bs_write_u8(bs, ((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV_size);
9135 			gf_bs_write_data(bs, (char *)((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV, ((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV_size);
9136 		}
9137 		return;
9138 	case GF_4CC('o', 'i', 'n', 'f'):
9139 		gf_isom_oinf_write_entry(entry, bs);
9140 		return;
9141 	case GF_4CC('l', 'i', 'n', 'f'):
9142 		gf_isom_linf_write_entry(entry, bs);
9143 		return;
9144 	default:
9145 	{
9146 		GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
9147 		gf_bs_write_data(bs, (char *)ptr->data, ptr->length);
9148 	}
9149 	}
9150 }
9151 
9152 #ifndef GPAC_DISABLE_ISOM_WRITE
sgpd_size_entry(u32 grouping_type,void * entry)9153 static u32 sgpd_size_entry(u32 grouping_type, void *entry)
9154 {
9155 	switch (grouping_type) {
9156 	case GF_4CC('r', 'o', 'l', 'l'):
9157 		return 2;
9158 	case GF_4CC('r', 'a', 'p', ' '):
9159 		return 1;
9160 	case GF_4CC('s', 'e', 'i', 'g'):
9161 		return ((((GF_CENCSampleEncryptionGroupEntry *)entry)->IsProtected == 1) && !((GF_CENCSampleEncryptionGroupEntry *)entry)->Per_Sample_IV_size) ? 21 + ((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV_size : 20;
9162 	case GF_4CC('o', 'i', 'n', 'f'):
9163 		return gf_isom_oinf_size_entry(entry);
9164 	case GF_4CC('l', 'i', 'n', 'f'):
9165 		return gf_isom_linf_size_entry(entry);
9166 	default:
9167 		return ((GF_DefaultSampleGroupDescriptionEntry *)entry)->length;
9168 	}
9169 }
9170 #endif
9171 
sgpd_New()9172 GF_Box *sgpd_New()
9173 {
9174 	ISOM_DECL_BOX_ALLOC(GF_SampleGroupDescriptionBox, GF_ISOM_BOX_TYPE_SGPD);
9175 	/*version 0 is deprecated, use v1 by default*/
9176 	tmp->version = 1;
9177 	tmp->group_descriptions = gf_list_new();
9178 	return (GF_Box *)tmp;
9179 }
9180 
sgpd_del(GF_Box * a)9181 void sgpd_del(GF_Box *a)
9182 {
9183 	GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)a;
9184 	while (gf_list_count(p->group_descriptions)) {
9185 		void *ptr = gf_list_last(p->group_descriptions);
9186 		sgpd_del_entry(p->grouping_type, ptr);
9187 		gf_list_rem_last(p->group_descriptions);
9188 	}
9189 	gf_list_del(p->group_descriptions);
9190 	gf_free(p);
9191 }
9192 
sgpd_Read(GF_Box * s,GF_BitStream * bs)9193 GF_Err sgpd_Read(GF_Box *s, GF_BitStream *bs)
9194 {
9195 	u32 entry_count;
9196 	GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
9197 	GF_Err e = gf_isom_full_box_read(s, bs);
9198 	if (e) return e;
9199 
9200 	p->grouping_type = gf_bs_read_u32(bs);
9201 	p->size -= 4;
9202 
9203 	if (p->version >= 1) {
9204 		p->default_length = gf_bs_read_u32(bs);
9205 		p->size -= 4;
9206 	}
9207 	if (p->version >= 2) {
9208 		p->default_description_index = gf_bs_read_u32(bs);
9209 		p->size -= 4;
9210 	}
9211 	entry_count = gf_bs_read_u32(bs);
9212 	p->size -= 4;
9213 
9214 	while (entry_count) {
9215 		void *ptr;
9216 		u32 parsed_bytes;
9217 		u32 size = p->default_length;
9218 		if ((p->version >= 1) && !size) {
9219 			size = gf_bs_read_u32(bs);
9220 			p->size -= 4;
9221 		}
9222 		ptr = sgpd_parse_entry(p->grouping_type, bs, size, &parsed_bytes);
9223 		if (!ptr) return GF_ISOM_INVALID_FILE;
9224 		if (p->size < parsed_bytes) return GF_ISOM_INVALID_FILE;
9225 		p->size -= parsed_bytes;
9226 		gf_list_add(p->group_descriptions, ptr);
9227 		entry_count--;
9228 	}
9229 	return GF_OK;
9230 }
9231 
9232 #ifndef GPAC_DISABLE_ISOM_WRITE
sgpd_Write(GF_Box * s,GF_BitStream * bs)9233 GF_Err sgpd_Write(GF_Box *s, GF_BitStream *bs)
9234 {
9235 	u32 i;
9236 	GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
9237 	GF_Err e;
9238 	e = gf_isom_full_box_write(s, bs);
9239 	if (e) return e;
9240 
9241 	gf_bs_write_u32(bs, p->grouping_type);
9242 	if (p->version >= 1) gf_bs_write_u32(bs, p->default_length);
9243 	if (p->version >= 2) gf_bs_write_u32(bs, p->default_description_index);
9244 	gf_bs_write_u32(bs, gf_list_count(p->group_descriptions));
9245 
9246 	for (i = 0; i<gf_list_count(p->group_descriptions); i++) {
9247 		void *ptr = gf_list_get(p->group_descriptions, i);
9248 		if ((p->version >= 1) && !p->default_length) {
9249 			u32 size = sgpd_size_entry(p->grouping_type, ptr);
9250 			gf_bs_write_u32(bs, size);
9251 		}
9252 		sgpd_write_entry(p->grouping_type, ptr, bs);
9253 	}
9254 	return GF_OK;
9255 }
9256 
sgpd_Size(GF_Box * s)9257 GF_Err sgpd_Size(GF_Box *s)
9258 {
9259 	u32 i;
9260 	GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
9261 	GF_Err e;
9262 	e = gf_isom_full_box_get_size(s);
9263 	if (e) return e;
9264 	p->size += 8;
9265 
9266 	//we force all sample groups to version 1, v0 being deprecated
9267 	p->version = 1;
9268 	p->size += 4;
9269 
9270 	if (p->version >= 2) p->size += 4;
9271 	p->default_length = 0;
9272 
9273 	for (i = 0; i<gf_list_count(p->group_descriptions); i++) {
9274 		void *ptr = gf_list_get(p->group_descriptions, i);
9275 		u32 size = sgpd_size_entry(p->grouping_type, ptr);
9276 		p->size += size;
9277 		if (!p->default_length) {
9278 			p->default_length = size;
9279 		}
9280 		else if (p->default_length != size) {
9281 			p->default_length = 0;
9282 		}
9283 	}
9284 	if (p->version >= 1) {
9285 		if (!p->default_length) p->size += gf_list_count(p->group_descriptions) * 4;
9286 	}
9287 	return GF_OK;
9288 }
9289 #endif /*GPAC_DISABLE_ISOM_WRITE*/
9290 
9291 
saiz_del(GF_Box * s)9292 void saiz_del(GF_Box *s)
9293 {
9294 	GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
9295 	if (ptr == NULL) return;
9296 	if (ptr->sample_info_size) gf_free(ptr->sample_info_size);
9297 	gf_free(ptr);
9298 }
9299 
9300 
saiz_Read(GF_Box * s,GF_BitStream * bs)9301 GF_Err saiz_Read(GF_Box *s, GF_BitStream *bs)
9302 {
9303 	GF_Err e;
9304 	GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
9305 
9306 	e = gf_isom_full_box_read(s, bs);
9307 	if (e) return e;
9308 	if (ptr->flags & 1) {
9309 		ptr->aux_info_type = gf_bs_read_u32(bs);
9310 		ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
9311 		ptr->size -= 8;
9312 	}
9313 	ptr->default_sample_info_size = gf_bs_read_u8(bs);
9314 	ptr->sample_count = gf_bs_read_u32(bs);
9315 	ptr->size -= 5;
9316 	if (ptr->default_sample_info_size == 0) {
9317 		ptr->sample_info_size = gf_malloc(sizeof(u8)*ptr->sample_count);
9318 		gf_bs_read_data(bs, (char *)ptr->sample_info_size, ptr->sample_count);
9319 		ptr->size -= ptr->sample_count;
9320 	}
9321 	return GF_OK;
9322 }
9323 
saiz_New()9324 GF_Box *saiz_New()
9325 {
9326 	ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoSizeBox, GF_ISOM_BOX_TYPE_SAIZ);
9327 	return (GF_Box *)tmp;
9328 }
9329 
9330 #ifndef GPAC_DISABLE_ISOM_WRITE
9331 
saiz_Write(GF_Box * s,GF_BitStream * bs)9332 GF_Err saiz_Write(GF_Box *s, GF_BitStream *bs)
9333 {
9334 	GF_Err e;
9335 	GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
9336 	if (!s) return GF_BAD_PARAM;
9337 	e = gf_isom_full_box_write(s, bs);
9338 	if (e) return e;
9339 
9340 	if (ptr->flags & 1) {
9341 		gf_bs_write_u32(bs, ptr->aux_info_type);
9342 		gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
9343 	}
9344 	gf_bs_write_u8(bs, ptr->default_sample_info_size);
9345 	gf_bs_write_u32(bs, ptr->sample_count);
9346 	if (!ptr->default_sample_info_size) {
9347 		gf_bs_write_data(bs, (char *)ptr->sample_info_size, ptr->sample_count);
9348 	}
9349 	return GF_OK;
9350 }
9351 
saiz_Size(GF_Box * s)9352 GF_Err saiz_Size(GF_Box *s)
9353 {
9354 	GF_Err e;
9355 	GF_SampleAuxiliaryInfoSizeBox *ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
9356 
9357 	if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
9358 		ptr->flags |= 1;
9359 	}
9360 
9361 	e = gf_isom_full_box_get_size(s);
9362 	if (e) return e;
9363 	if (ptr->flags & 1) ptr->size += 8;
9364 	ptr->size += 5;
9365 	if (ptr->default_sample_info_size == 0)  ptr->size += ptr->sample_count;
9366 	return GF_OK;
9367 }
9368 #endif //GPAC_DISABLE_ISOM_WRITE
9369 
saio_del(GF_Box * s)9370 void saio_del(GF_Box *s)
9371 {
9372 	GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;
9373 	if (ptr == NULL) return;
9374 	if (ptr->offsets) gf_free(ptr->offsets);
9375 	if (ptr->offsets_large) gf_free(ptr->offsets_large);
9376 	gf_free(ptr);
9377 }
9378 
9379 
saio_Read(GF_Box * s,GF_BitStream * bs)9380 GF_Err saio_Read(GF_Box *s, GF_BitStream *bs)
9381 {
9382 	GF_Err e;
9383 	GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *)s;
9384 
9385 	e = gf_isom_full_box_read(s, bs);
9386 	if (e) return e;
9387 	if (ptr->flags & 1) {
9388 		ptr->aux_info_type = gf_bs_read_u32(bs);
9389 		ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
9390 		ptr->size -= 8;
9391 	}
9392 	ptr->entry_count = gf_bs_read_u32(bs);
9393 	ptr->size -= 4;
9394 	if (ptr->entry_count) {
9395 		u32 i;
9396 		if (ptr->version == 0) {
9397 			ptr->offsets = gf_malloc(sizeof(u32)*ptr->entry_count);
9398 			for (i = 0; i<ptr->entry_count; i++)
9399 				ptr->offsets[i] = gf_bs_read_u32(bs);
9400 			ptr->size -= 4 * ptr->entry_count;
9401 		}
9402 		else {
9403 			ptr->offsets_large = gf_malloc(sizeof(u64)*ptr->entry_count);
9404 			for (i = 0; i<ptr->entry_count; i++)
9405 				ptr->offsets_large[i] = gf_bs_read_u64(bs);
9406 			ptr->size -= 8 * ptr->entry_count;
9407 		}
9408 	}
9409 	return GF_OK;
9410 }
9411 
saio_New()9412 GF_Box *saio_New()
9413 {
9414 	ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoOffsetBox, GF_ISOM_BOX_TYPE_SAIO);
9415 	return (GF_Box *)tmp;
9416 }
9417 
9418 #ifndef GPAC_DISABLE_ISOM_WRITE
9419 
saio_Write(GF_Box * s,GF_BitStream * bs)9420 GF_Err saio_Write(GF_Box *s, GF_BitStream *bs)
9421 {
9422 	GF_Err e;
9423 	GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *)s;
9424 	if (!s) return GF_BAD_PARAM;
9425 	e = gf_isom_full_box_write(s, bs);
9426 	if (e) return e;
9427 
9428 	if (ptr->flags & 1) {
9429 		gf_bs_write_u32(bs, ptr->aux_info_type);
9430 		gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
9431 	}
9432 	gf_bs_write_u32(bs, ptr->entry_count);
9433 	if (ptr->entry_count) {
9434 		u32 i;
9435 		//store position in bitstream before writing data - offsets can be NULL if a single offset is rewritten later on (cf senc_write)
9436 		ptr->offset_first_offset_field = gf_bs_get_position(bs);
9437 		if (ptr->version == 0) {
9438 			if (!ptr->offsets) {
9439 				gf_bs_write_u32(bs, 0);
9440 			}
9441 			else {
9442 				for (i = 0; i<ptr->entry_count; i++)
9443 					gf_bs_write_u32(bs, ptr->offsets[i]);
9444 			}
9445 		}
9446 		else {
9447 			if (!ptr->offsets_large) {
9448 				gf_bs_write_u64(bs, 0);
9449 			}
9450 			else {
9451 				for (i = 0; i<ptr->entry_count; i++)
9452 					gf_bs_write_u64(bs, ptr->offsets_large[i]);
9453 			}
9454 		}
9455 	}
9456 	return GF_OK;
9457 }
9458 
saio_Size(GF_Box * s)9459 GF_Err saio_Size(GF_Box *s)
9460 {
9461 	GF_Err e;
9462 	GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;
9463 
9464 	if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
9465 		ptr->flags |= 1;
9466 	}
9467 	if (ptr->offsets_large) {
9468 		ptr->version = 1;
9469 	}
9470 
9471 	e = gf_isom_full_box_get_size(s);
9472 	if (e) return e;
9473 	if (ptr->flags & 1) ptr->size += 8;
9474 	ptr->size += 4;
9475 	ptr->size += ((ptr->version == 1) ? 8 : 4) * ptr->entry_count;
9476 	return GF_OK;
9477 }
9478 #endif //GPAC_DISABLE_ISOM_WRITE
9479 
9480 
prft_del(GF_Box * s)9481 void prft_del(GF_Box *s)
9482 {
9483 	gf_free(s);
9484 }
9485 
prft_Read(GF_Box * s,GF_BitStream * bs)9486 GF_Err prft_Read(GF_Box *s, GF_BitStream *bs)
9487 {
9488 	GF_Err e;
9489 	GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox *)s;
9490 	e = gf_isom_full_box_read(s, bs);
9491 	if (e) return e;
9492 	ptr->refTrackID = gf_bs_read_u32(bs);
9493 	ptr->ntp = gf_bs_read_u64(bs);
9494 	if (ptr->version == 0) {
9495 		ptr->timestamp = gf_bs_read_u32(bs);
9496 	}
9497 	else {
9498 		ptr->timestamp = gf_bs_read_u64(bs);
9499 	}
9500 	return GF_OK;
9501 }
9502 
prft_New()9503 GF_Box *prft_New()
9504 {
9505 	ISOM_DECL_BOX_ALLOC(GF_ProducerReferenceTimeBox, GF_ISOM_BOX_TYPE_PRFT);
9506 	gf_isom_full_box_init((GF_Box *)tmp);
9507 	return (GF_Box *)tmp;
9508 }
9509 
9510 
trgr_New()9511 GF_Box *trgr_New()
9512 {
9513 	ISOM_DECL_BOX_ALLOC(GF_TrackGroupBox, GF_ISOM_BOX_TYPE_TRGR);
9514 	tmp->groups = gf_list_new();
9515 	if (!tmp->groups) {
9516 		gf_free(tmp);
9517 		return NULL;
9518 	}
9519 	return (GF_Box *)tmp;
9520 }
9521 
trgr_del(GF_Box * s)9522 void trgr_del(GF_Box *s)
9523 {
9524 	GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
9525 	if (ptr == NULL) return;
9526 	gf_isom_box_array_del(ptr->groups);
9527 	gf_free(ptr);
9528 }
9529 
9530 
trgr_AddBox(GF_Box * s,GF_Box * a)9531 GF_Err trgr_AddBox(GF_Box *s, GF_Box *a)
9532 {
9533 	GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
9534 	return gf_list_add(ptr->groups, a);
9535 }
9536 
9537 
trgr_Read(GF_Box * s,GF_BitStream * bs)9538 GF_Err trgr_Read(GF_Box *s, GF_BitStream *bs)
9539 {
9540 	return gf_isom_read_box_list(s, bs, trgr_AddBox);
9541 }
9542 
9543 
9544 #ifndef GPAC_DISABLE_ISOM_WRITE
9545 
9546 
trgr_Write(GF_Box * s,GF_BitStream * bs)9547 GF_Err trgr_Write(GF_Box *s, GF_BitStream *bs)
9548 {
9549 	GF_Err e;
9550 	GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
9551 	if (!s) return GF_BAD_PARAM;
9552 	e = gf_isom_box_write_header(s, bs);
9553 	if (e) return e;
9554 	return gf_isom_box_array_write(s, ptr->groups, bs);
9555 }
9556 
trgr_Size(GF_Box * s)9557 GF_Err trgr_Size(GF_Box *s)
9558 {
9559 	GF_Err e;
9560 	GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
9561 	e = gf_isom_box_get_size(s);
9562 	if (e) return e;
9563 	return gf_isom_box_array_size(s, ptr->groups);
9564 }
9565 
9566 #endif /*GPAC_DISABLE_ISOM_WRITE*/
9567 
9568 
trgt_New(u32 boxType)9569 GF_Box *trgt_New(u32 boxType)
9570 {
9571 	ISOM_DECL_BOX_ALLOC(GF_TrackGroupTypeBox, GF_ISOM_BOX_TYPE_TRGT);
9572 	gf_isom_full_box_init((GF_Box *)tmp);
9573 	tmp->group_type = boxType;
9574 	return (GF_Box *)tmp;
9575 }
9576 
trgt_del(GF_Box * s)9577 void trgt_del(GF_Box *s)
9578 {
9579 	GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s;
9580 	if (ptr == NULL) return;
9581 	gf_free(ptr);
9582 }
9583 
trgt_Read(GF_Box * s,GF_BitStream * bs)9584 GF_Err trgt_Read(GF_Box *s, GF_BitStream *bs)
9585 {
9586 	GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s;
9587 	gf_isom_full_box_read(s, bs);
9588 	ptr->track_group_id = gf_bs_read_u32(bs);
9589 	ptr->size -= 4;
9590 	return GF_OK;
9591 }
9592 
9593 
9594 #ifndef GPAC_DISABLE_ISOM_WRITE
9595 
trgt_Write(GF_Box * s,GF_BitStream * bs)9596 GF_Err trgt_Write(GF_Box *s, GF_BitStream *bs)
9597 {
9598 	GF_Err e;
9599 	GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s;
9600 	if (!s) return GF_BAD_PARAM;
9601 	s->type = ptr->group_type;
9602 	e = gf_isom_full_box_write(s, bs);
9603 	s->type = GF_ISOM_BOX_TYPE_TRGT;
9604 	if (e) return e;
9605 	gf_bs_write_u32(bs, ptr->track_group_id);
9606 	return GF_OK;
9607 }
9608 
trgt_Size(GF_Box * s)9609 GF_Err trgt_Size(GF_Box *s)
9610 {
9611 	GF_Err e;
9612 	GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
9613 	e = gf_isom_full_box_get_size(s);
9614 	if (e) return e;
9615 	ptr->size += 4;
9616 	return GF_OK;
9617 }
9618 
9619 #endif /*GPAC_DISABLE_ISOM_WRITE*/
9620 
9621 #endif /*GPAC_DISABLE_ISOM*/
9622