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