Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2021
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 :
32 4 : void co64_box_del(GF_Box *s)
33 : {
34 : GF_ChunkLargeOffsetBox *ptr;
35 : ptr = (GF_ChunkLargeOffsetBox *) s;
36 4 : if (ptr == NULL) return;
37 4 : if (ptr->offsets) gf_free(ptr->offsets);
38 4 : gf_free(ptr);
39 : }
40 :
41 1 : GF_Err co64_box_read(GF_Box *s,GF_BitStream *bs)
42 : {
43 : u32 entries;
44 : GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;
45 1 : ptr->nb_entries = gf_bs_read_u32(bs);
46 :
47 1 : ISOM_DECREASE_SIZE(ptr, 4)
48 :
49 1 : if (ptr->nb_entries > ptr->size / 8) {
50 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in co64\n", ptr->nb_entries));
51 : return GF_ISOM_INVALID_FILE;
52 : }
53 :
54 1 : ptr->offsets = (u64 *) gf_malloc(ptr->nb_entries * sizeof(u64) );
55 1 : if (ptr->offsets == NULL) return GF_OUT_OF_MEM;
56 1 : ptr->alloc_size = ptr->nb_entries;
57 1 : for (entries = 0; entries < ptr->nb_entries; entries++) {
58 0 : ptr->offsets[entries] = gf_bs_read_u64(bs);
59 : }
60 : return GF_OK;
61 : }
62 :
63 4 : GF_Box *co64_box_new()
64 : {
65 8 : ISOM_DECL_BOX_ALLOC(GF_ChunkLargeOffsetBox, GF_ISOM_BOX_TYPE_CO64);
66 4 : return (GF_Box *)tmp;
67 : }
68 :
69 :
70 : #ifndef GPAC_DISABLE_ISOM_WRITE
71 :
72 2 : GF_Err co64_box_write(GF_Box *s, GF_BitStream *bs)
73 : {
74 : GF_Err e;
75 : u32 i;
76 : GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;
77 :
78 2 : e = gf_isom_full_box_write(s, bs);
79 2 : if (e) return e;
80 2 : gf_bs_write_u32(bs, ptr->nb_entries);
81 17 : for (i = 0; i < ptr->nb_entries; i++ ) {
82 15 : gf_bs_write_u64(bs, ptr->offsets[i]);
83 : }
84 : return GF_OK;
85 : }
86 :
87 4 : GF_Err co64_box_size(GF_Box *s)
88 : {
89 : GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;
90 :
91 4 : ptr->size += 4 + (8 * ptr->nb_entries);
92 4 : return GF_OK;
93 : }
94 :
95 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
96 :
97 7 : void cprt_box_del(GF_Box *s)
98 : {
99 : GF_CopyrightBox *ptr = (GF_CopyrightBox *) s;
100 7 : if (ptr == NULL) return;
101 7 : if (ptr->notice)
102 2 : gf_free(ptr->notice);
103 7 : gf_free(ptr);
104 : }
105 :
106 :
107 9 : GF_Box *chpl_box_new()
108 : {
109 18 : ISOM_DECL_BOX_ALLOC(GF_ChapterListBox, GF_ISOM_BOX_TYPE_CHPL);
110 9 : tmp->list = gf_list_new();
111 9 : tmp->version = 1;
112 9 : return (GF_Box *)tmp;
113 : }
114 :
115 9 : void chpl_box_del(GF_Box *s)
116 : {
117 : GF_ChapterListBox *ptr = (GF_ChapterListBox *) s;
118 9 : if (ptr == NULL) return;
119 37 : while (gf_list_count(ptr->list)) {
120 28 : GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, 0);
121 28 : if (ce->name) gf_free(ce->name);
122 28 : gf_free(ce);
123 28 : gf_list_rem(ptr->list, 0);
124 : }
125 9 : gf_list_del(ptr->list);
126 9 : gf_free(ptr);
127 : }
128 :
129 : /*this is using chpl format according to some NeroRecode samples*/
130 5 : GF_Err chpl_box_read(GF_Box *s,GF_BitStream *bs)
131 : {
132 : GF_ChapterEntry *ce;
133 : u32 nb_chaps, len, i, count;
134 : GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;
135 :
136 5 : ISOM_DECREASE_SIZE(ptr, 5)
137 : /*reserved or ???*/
138 5 : gf_bs_read_u32(bs);
139 5 : nb_chaps = gf_bs_read_u8(bs);
140 :
141 : count = 0;
142 29 : while (nb_chaps) {
143 19 : GF_SAFEALLOC(ce, GF_ChapterEntry);
144 19 : if (!ce) return GF_OUT_OF_MEM;
145 19 : ISOM_DECREASE_SIZE(ptr, 9)
146 19 : ce->start_time = gf_bs_read_u64(bs);
147 19 : len = gf_bs_read_u8(bs);
148 19 : if (ptr->size<len) return GF_ISOM_INVALID_FILE;
149 19 : if (len) {
150 19 : ce->name = (char *)gf_malloc(sizeof(char)*(len+1));
151 19 : if (!ce->name) return GF_OUT_OF_MEM;
152 19 : ISOM_DECREASE_SIZE(ptr, len)
153 19 : gf_bs_read_data(bs, ce->name, len);
154 19 : ce->name[len] = 0;
155 : } else {
156 0 : ce->name = gf_strdup("");
157 : }
158 :
159 36 : for (i=0; i<count; i++) {
160 36 : GF_ChapterEntry *ace = (GF_ChapterEntry *) gf_list_get(ptr->list, i);
161 36 : if (ace->start_time >= ce->start_time) {
162 0 : gf_list_insert(ptr->list, ce, i);
163 : ce = NULL;
164 : break;
165 : }
166 : }
167 19 : if (ce) gf_list_add(ptr->list, ce);
168 19 : count++;
169 19 : nb_chaps--;
170 : }
171 : return GF_OK;
172 : }
173 :
174 : #ifndef GPAC_DISABLE_ISOM_WRITE
175 :
176 3 : GF_Err chpl_box_write(GF_Box *s, GF_BitStream *bs)
177 : {
178 : GF_Err e;
179 : u32 count, i;
180 : GF_ChapterListBox *ptr = (GF_ChapterListBox *) s;
181 3 : e = gf_isom_full_box_write(s, bs);
182 3 : if (e) return e;
183 :
184 3 : count = gf_list_count(ptr->list);
185 3 : gf_bs_write_u32(bs, 0);
186 3 : gf_bs_write_u8(bs, count);
187 12 : for (i=0; i<count; i++) {
188 : u32 len;
189 9 : GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, i);
190 9 : gf_bs_write_u64(bs, ce->start_time);
191 9 : if (ce->name) {
192 9 : len = (u32) strlen(ce->name);
193 9 : if (len>255) len = 255;
194 9 : gf_bs_write_u8(bs, len);
195 9 : gf_bs_write_data(bs, ce->name, len);
196 : } else {
197 0 : gf_bs_write_u8(bs, 0);
198 : }
199 : }
200 : return GF_OK;
201 : }
202 :
203 7 : GF_Err chpl_box_size(GF_Box *s)
204 : {
205 : u32 count, i;
206 : GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;
207 :
208 7 : ptr->size += 5;
209 :
210 7 : count = gf_list_count(ptr->list);
211 34 : for (i=0; i<count; i++) {
212 27 : GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, i);
213 27 : ptr->size += 9; /*64bit time stamp + 8bit str len*/
214 27 : if (ce->name) ptr->size += strlen(ce->name);
215 : }
216 7 : return GF_OK;
217 : }
218 :
219 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
220 :
221 :
222 3 : GF_Err cprt_box_read(GF_Box *s,GF_BitStream *bs)
223 : {
224 : GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;
225 :
226 3 : ISOM_DECREASE_SIZE(ptr, 2);
227 3 : gf_bs_read_int(bs, 1);
228 : //the spec is unclear here, just says "the value 0 is interpreted as undetermined"
229 3 : ptr->packedLanguageCode[0] = gf_bs_read_int(bs, 5);
230 3 : ptr->packedLanguageCode[1] = gf_bs_read_int(bs, 5);
231 3 : ptr->packedLanguageCode[2] = gf_bs_read_int(bs, 5);
232 :
233 : //but before or after compaction ?? We assume before
234 3 : if (ptr->packedLanguageCode[0] || ptr->packedLanguageCode[1] || ptr->packedLanguageCode[2]) {
235 3 : ptr->packedLanguageCode[0] += 0x60;
236 3 : ptr->packedLanguageCode[1] += 0x60;
237 3 : ptr->packedLanguageCode[2] += 0x60;
238 : } else {
239 0 : ptr->packedLanguageCode[0] = 'u';
240 0 : ptr->packedLanguageCode[1] = 'n';
241 0 : ptr->packedLanguageCode[2] = 'd';
242 : }
243 3 : if (ptr->size) {
244 1 : u32 bytesToRead = (u32) ptr->size;
245 1 : ptr->notice = (char*)gf_malloc(bytesToRead * sizeof(char));
246 1 : if (ptr->notice == NULL) return GF_OUT_OF_MEM;
247 1 : gf_bs_read_data(bs, ptr->notice, bytesToRead);
248 : }
249 : return GF_OK;
250 : }
251 :
252 7 : GF_Box *cprt_box_new()
253 : {
254 14 : ISOM_DECL_BOX_ALLOC(GF_CopyrightBox, GF_ISOM_BOX_TYPE_CPRT);
255 7 : tmp->packedLanguageCode[0] = 'u';
256 7 : tmp->packedLanguageCode[1] = 'n';
257 7 : tmp->packedLanguageCode[2] = 'd';
258 :
259 7 : return (GF_Box *)tmp;
260 : }
261 :
262 : #ifndef GPAC_DISABLE_ISOM_WRITE
263 :
264 3 : GF_Err cprt_box_write(GF_Box *s, GF_BitStream *bs)
265 : {
266 : GF_Err e;
267 : GF_CopyrightBox *ptr = (GF_CopyrightBox *) s;
268 :
269 3 : e = gf_isom_full_box_write(s, bs);
270 3 : if (e) return e;
271 3 : gf_bs_write_int(bs, 0, 1);
272 3 : if (ptr->packedLanguageCode[0]) {
273 3 : gf_bs_write_int(bs, ptr->packedLanguageCode[0] - 0x60, 5);
274 3 : gf_bs_write_int(bs, ptr->packedLanguageCode[1] - 0x60, 5);
275 3 : gf_bs_write_int(bs, ptr->packedLanguageCode[2] - 0x60, 5);
276 : } else {
277 0 : gf_bs_write_int(bs, 0, 15);
278 : }
279 3 : if (ptr->notice) {
280 1 : gf_bs_write_data(bs, ptr->notice, (u32) (strlen(ptr->notice) + 1) );
281 : }
282 : return GF_OK;
283 : }
284 :
285 5 : GF_Err cprt_box_size(GF_Box *s)
286 : {
287 : GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;
288 :
289 5 : ptr->size += 2;
290 5 : if (ptr->notice)
291 3 : ptr->size += strlen(ptr->notice) + 1;
292 5 : return GF_OK;
293 : }
294 :
295 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
296 :
297 145 : void kind_box_del(GF_Box *s)
298 : {
299 : GF_KindBox *ptr = (GF_KindBox *) s;
300 145 : if (ptr == NULL) return;
301 145 : if (ptr->schemeURI) gf_free(ptr->schemeURI);
302 145 : if (ptr->value) gf_free(ptr->value);
303 145 : gf_free(ptr);
304 : }
305 :
306 87 : GF_Err kind_box_read(GF_Box *s,GF_BitStream *bs)
307 : {
308 : GF_KindBox *ptr = (GF_KindBox *)s;
309 :
310 87 : if (ptr->size) {
311 87 : u32 bytesToRead = (u32) ptr->size;
312 : char *data;
313 : u32 schemeURIlen;
314 87 : data = (char*)gf_malloc(bytesToRead * sizeof(char));
315 87 : if (!data) return GF_OUT_OF_MEM;
316 87 : gf_bs_read_data(bs, data, bytesToRead);
317 : /*safety check in case the string is not null-terminated*/
318 87 : if (data[bytesToRead-1]) {
319 0 : data = (char*)gf_realloc(data, sizeof(char)*(bytesToRead + 1));
320 0 : if (!data) return GF_OUT_OF_MEM;
321 0 : data[bytesToRead] = 0;
322 : bytesToRead++;
323 : }
324 87 : ptr->schemeURI = gf_strdup(data);
325 87 : if (!ptr->schemeURI) return GF_OUT_OF_MEM;
326 87 : schemeURIlen = (u32) strlen(data);
327 87 : if (bytesToRead > schemeURIlen+1) {
328 : /* read the value */
329 37 : char *data_value = data + schemeURIlen +1;
330 37 : ptr->value = gf_strdup(data_value);
331 37 : if (!ptr->value) return GF_OUT_OF_MEM;
332 : }
333 87 : gf_free(data);
334 : }
335 : return GF_OK;
336 : }
337 :
338 145 : GF_Box *kind_box_new()
339 : {
340 290 : ISOM_DECL_BOX_ALLOC(GF_KindBox, GF_ISOM_BOX_TYPE_KIND);
341 145 : return (GF_Box *)tmp;
342 : }
343 :
344 : #ifndef GPAC_DISABLE_ISOM_WRITE
345 :
346 105 : GF_Err kind_box_write(GF_Box *s, GF_BitStream *bs)
347 : {
348 : GF_Err e;
349 : GF_KindBox *ptr = (GF_KindBox *) s;
350 :
351 105 : e = gf_isom_full_box_write(s, bs);
352 105 : if (e) return e;
353 105 : if (ptr->schemeURI)
354 104 : gf_bs_write_data(bs, ptr->schemeURI, (u32) (strlen(ptr->schemeURI) + 1 ));
355 : else
356 1 : gf_bs_write_u8(bs, 0);
357 :
358 105 : if (ptr->value) {
359 51 : gf_bs_write_data(bs, ptr->value, (u32) (strlen(ptr->value) + 1) );
360 : }
361 : return GF_OK;
362 : }
363 :
364 273 : GF_Err kind_box_size(GF_Box *s)
365 : {
366 : GF_KindBox *ptr = (GF_KindBox *)s;
367 :
368 273 : ptr->size += (ptr->schemeURI ? strlen(ptr->schemeURI) : 0) + 1;
369 273 : if (ptr->value) {
370 137 : ptr->size += strlen(ptr->value) + 1;
371 : }
372 273 : return GF_OK;
373 : }
374 :
375 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
376 :
377 18028 : void ctts_box_del(GF_Box *s)
378 : {
379 : GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
380 18028 : if (ptr->entries) gf_free(ptr->entries);
381 18028 : gf_free(ptr);
382 18028 : }
383 :
384 :
385 :
386 477 : GF_Err ctts_box_read(GF_Box *s, GF_BitStream *bs)
387 : {
388 : u32 i;
389 : u32 sampleCount;
390 : GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
391 :
392 477 : ISOM_DECREASE_SIZE(ptr, 4);
393 477 : ptr->nb_entries = gf_bs_read_u32(bs);
394 :
395 477 : if (ptr->nb_entries > ptr->size / 8) {
396 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", ptr->nb_entries));
397 : return GF_ISOM_INVALID_FILE;
398 : }
399 :
400 477 : ptr->alloc_size = ptr->nb_entries;
401 477 : ptr->entries = (GF_DttsEntry *)gf_malloc(sizeof(GF_DttsEntry)*ptr->alloc_size);
402 477 : if (!ptr->entries) return GF_OUT_OF_MEM;
403 : sampleCount = 0;
404 157101 : for (i=0; i<ptr->nb_entries; i++) {
405 157101 : ISOM_DECREASE_SIZE(ptr, 8);
406 157101 : ptr->entries[i].sampleCount = gf_bs_read_u32(bs);
407 157101 : if (ptr->version)
408 5274 : ptr->entries[i].decodingOffset = gf_bs_read_int(bs, 32);
409 : else
410 151827 : ptr->entries[i].decodingOffset = (s32) gf_bs_read_u32(bs);
411 157101 : sampleCount += ptr->entries[i].sampleCount;
412 :
413 157101 : if (ptr->max_ts_delta < ABS(ptr->entries[i].decodingOffset))
414 1256 : ptr->max_ts_delta = ABS(ptr->entries[i].decodingOffset);
415 : }
416 : #ifndef GPAC_DISABLE_ISOM_WRITE
417 477 : ptr->w_LastSampleNumber = sampleCount;
418 : #endif
419 477 : return GF_OK;
420 : }
421 :
422 18028 : GF_Box *ctts_box_new()
423 : {
424 36056 : ISOM_DECL_BOX_ALLOC(GF_CompositionOffsetBox, GF_ISOM_BOX_TYPE_CTTS);
425 18028 : return (GF_Box *) tmp;
426 : }
427 :
428 :
429 :
430 : #ifndef GPAC_DISABLE_ISOM_WRITE
431 :
432 407 : GF_Err ctts_box_write(GF_Box *s, GF_BitStream *bs)
433 : {
434 : GF_Err e;
435 : u32 i;
436 : GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
437 :
438 407 : e = gf_isom_full_box_write(s, bs);
439 407 : if (e) return e;
440 407 : gf_bs_write_u32(bs, ptr->nb_entries);
441 141097 : for (i=0; i<ptr->nb_entries; i++ ) {
442 140690 : gf_bs_write_u32(bs, ptr->entries[i].sampleCount);
443 140690 : if (ptr->version) {
444 1560 : gf_bs_write_int(bs, ptr->entries[i].decodingOffset, 32);
445 : } else {
446 139130 : gf_bs_write_u32(bs, (u32) ptr->entries[i].decodingOffset);
447 : }
448 : }
449 : return GF_OK;
450 : }
451 :
452 1157 : GF_Err ctts_box_size(GF_Box *s)
453 : {
454 : GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *) s;
455 :
456 1157 : ptr->size += 4 + (8 * ptr->nb_entries);
457 1157 : return GF_OK;
458 : }
459 :
460 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
461 :
462 18 : void cslg_box_del(GF_Box *s)
463 : {
464 : GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
465 18 : if (ptr == NULL) return;
466 18 : gf_free(ptr);
467 18 : return;
468 : }
469 :
470 13 : GF_Err cslg_box_read(GF_Box *s, GF_BitStream *bs)
471 : {
472 : GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
473 :
474 13 : ISOM_DECREASE_SIZE(ptr, 20);
475 13 : ptr->compositionToDTSShift = gf_bs_read_int(bs, 32);
476 13 : ptr->leastDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
477 13 : ptr->greatestDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
478 13 : ptr->compositionStartTime = gf_bs_read_int(bs, 32);
479 13 : ptr->compositionEndTime = gf_bs_read_int(bs, 32);
480 13 : return GF_OK;
481 : }
482 :
483 18 : GF_Box *cslg_box_new()
484 : {
485 36 : ISOM_DECL_BOX_ALLOC(GF_CompositionToDecodeBox, GF_ISOM_BOX_TYPE_CSLG);
486 18 : return (GF_Box *) tmp;
487 : }
488 :
489 : #ifndef GPAC_DISABLE_ISOM_WRITE
490 :
491 9 : GF_Err cslg_box_write(GF_Box *s, GF_BitStream *bs)
492 : {
493 : GF_Err e;
494 : GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
495 :
496 9 : e = gf_isom_full_box_write(s, bs);
497 9 : if (e) return e;
498 9 : gf_bs_write_int(bs, ptr->compositionToDTSShift, 32);
499 9 : gf_bs_write_int(bs, ptr->leastDecodeToDisplayDelta, 32);
500 9 : gf_bs_write_int(bs, ptr->greatestDecodeToDisplayDelta, 32);
501 9 : gf_bs_write_int(bs, ptr->compositionStartTime, 32);
502 9 : gf_bs_write_int(bs, ptr->compositionEndTime, 32);
503 9 : return GF_OK;
504 : }
505 :
506 13 : GF_Err cslg_box_size(GF_Box *s)
507 : {
508 : GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
509 :
510 13 : ptr->size += 20;
511 13 : return GF_OK;
512 : }
513 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
514 :
515 4 : void ccst_box_del(GF_Box *s)
516 : {
517 : GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
518 4 : if (ptr) gf_free(ptr);
519 4 : return;
520 : }
521 :
522 1 : GF_Err ccst_box_read(GF_Box *s, GF_BitStream *bs)
523 : {
524 : GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
525 :
526 1 : ISOM_DECREASE_SIZE(ptr, 4);
527 1 : ptr->all_ref_pics_intra = gf_bs_read_int(bs, 1);
528 1 : ptr->intra_pred_used = gf_bs_read_int(bs, 1);
529 1 : ptr->max_ref_per_pic = gf_bs_read_int(bs, 4);
530 1 : ptr->reserved = gf_bs_read_int(bs, 26);
531 1 : return GF_OK;
532 : }
533 :
534 4 : GF_Box *ccst_box_new()
535 : {
536 8 : ISOM_DECL_BOX_ALLOC(GF_CodingConstraintsBox, GF_ISOM_BOX_TYPE_CCST);
537 4 : return (GF_Box *) tmp;
538 : }
539 :
540 : #ifndef GPAC_DISABLE_ISOM_WRITE
541 :
542 2 : GF_Err ccst_box_write(GF_Box *s, GF_BitStream *bs)
543 : {
544 : GF_Err e;
545 : GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
546 :
547 2 : e = gf_isom_full_box_write(s, bs);
548 2 : if (e) return e;
549 2 : gf_bs_write_int(bs, ptr->all_ref_pics_intra, 1);
550 2 : gf_bs_write_int(bs, ptr->intra_pred_used, 1);
551 2 : gf_bs_write_int(bs, ptr->max_ref_per_pic, 4);
552 2 : gf_bs_write_int(bs, 0, 26);
553 2 : return GF_OK;
554 : }
555 :
556 4 : GF_Err ccst_box_size(GF_Box *s)
557 : {
558 : GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
559 4 : ptr->size += 4;
560 4 : return GF_OK;
561 : }
562 :
563 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
564 :
565 4209 : void url_box_del(GF_Box *s)
566 : {
567 : GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
568 4209 : if (ptr == NULL) return;
569 4209 : if (ptr->location) gf_free(ptr->location);
570 4209 : gf_free(ptr);
571 4209 : return;
572 : }
573 :
574 :
575 2474 : GF_Err url_box_read(GF_Box *s, GF_BitStream *bs)
576 : {
577 : GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
578 :
579 2474 : if (ptr->size) {
580 0 : ptr->location = (char*)gf_malloc((u32) ptr->size);
581 0 : if (! ptr->location) return GF_OUT_OF_MEM;
582 0 : gf_bs_read_data(bs, ptr->location, (u32)ptr->size);
583 0 : if (ptr->location[ptr->size-1]) {
584 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] url box location is not 0-terminated\n" ));
585 : return GF_ISOM_INVALID_FILE;
586 : }
587 : }
588 : return GF_OK;
589 : }
590 :
591 4209 : GF_Box *url_box_new()
592 : {
593 8418 : ISOM_DECL_BOX_ALLOC(GF_DataEntryURLBox, GF_ISOM_BOX_TYPE_URL);
594 4209 : return (GF_Box *)tmp;
595 : }
596 :
597 : #ifndef GPAC_DISABLE_ISOM_WRITE
598 :
599 2038 : GF_Err url_box_write(GF_Box *s, GF_BitStream *bs)
600 : {
601 : GF_Err e;
602 : GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
603 :
604 2038 : e = gf_isom_full_box_write(s, bs);
605 2038 : if (e) return e;
606 : //the flag set indicates we have a string (WE HAVE TO for URLs)
607 2038 : if ( !(ptr->flags & 1)) {
608 4 : if (ptr->location) {
609 3 : gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1);
610 : }
611 : }
612 : return GF_OK;
613 : }
614 :
615 4987 : GF_Err url_box_size(GF_Box *s)
616 : {
617 : GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
618 :
619 4987 : if ( !(ptr->flags & 1)) {
620 10 : if (ptr->location) ptr->size += 1 + strlen(ptr->location);
621 : }
622 4987 : return GF_OK;
623 : }
624 :
625 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
626 :
627 3 : void urn_box_del(GF_Box *s)
628 : {
629 : GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
630 3 : if (ptr == NULL) return;
631 3 : if (ptr->location) gf_free(ptr->location);
632 3 : if (ptr->nameURN) gf_free(ptr->nameURN);
633 3 : gf_free(ptr);
634 : }
635 :
636 :
637 1 : GF_Err urn_box_read(GF_Box *s, GF_BitStream *bs)
638 : {
639 : u32 i, to_read;
640 : char *tmpName;
641 : GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
642 1 : if (! ptr->size ) return GF_OK;
643 :
644 : //here we have to handle that in a clever way
645 0 : to_read = (u32) ptr->size;
646 0 : tmpName = (char*)gf_malloc(sizeof(char) * to_read);
647 0 : if (!tmpName) return GF_OUT_OF_MEM;
648 : //get the data
649 0 : gf_bs_read_data(bs, tmpName, to_read);
650 :
651 : //then get the break
652 : i = 0;
653 0 : while ( (i < to_read) && (tmpName[i] != 0) ) {
654 0 : i++;
655 : }
656 : //check the data is consistent
657 0 : if (i == to_read) {
658 0 : gf_free(tmpName);
659 0 : return GF_ISOM_INVALID_FILE;
660 : }
661 : //no NULL char, URL is not specified
662 0 : if (i == to_read - 1) {
663 0 : ptr->nameURN = tmpName;
664 0 : ptr->location = NULL;
665 0 : return GF_OK;
666 : }
667 : //OK, this has both URN and URL
668 0 : ptr->nameURN = (char*)gf_malloc(sizeof(char) * (i+1));
669 0 : if (!ptr->nameURN) {
670 0 : gf_free(tmpName);
671 0 : return GF_OUT_OF_MEM;
672 : }
673 : memcpy(ptr->nameURN, tmpName, i + 1);
674 :
675 0 : if (tmpName[to_read - 1] != 0) {
676 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] urn box contains invalid location field\n" ));
677 : }
678 : else {
679 0 : ptr->location = (char*)gf_malloc(sizeof(char) * (to_read - i - 1));
680 0 : if (!ptr->location) {
681 0 : gf_free(tmpName);
682 0 : gf_free(ptr->nameURN);
683 0 : ptr->nameURN = NULL;
684 0 : return GF_OUT_OF_MEM;
685 : }
686 0 : memcpy(ptr->location, tmpName + i + 1, (to_read - i - 1));
687 : }
688 :
689 0 : gf_free(tmpName);
690 0 : return GF_OK;
691 : }
692 :
693 3 : GF_Box *urn_box_new()
694 : {
695 6 : ISOM_DECL_BOX_ALLOC(GF_DataEntryURNBox, GF_ISOM_BOX_TYPE_URN);
696 3 : return (GF_Box *)tmp;
697 : }
698 :
699 : #ifndef GPAC_DISABLE_ISOM_WRITE
700 :
701 :
702 1 : GF_Err urn_box_write(GF_Box *s, GF_BitStream *bs)
703 : {
704 : GF_Err e;
705 : GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
706 :
707 1 : e = gf_isom_full_box_write(s, bs);
708 1 : if (e) return e;
709 : //the flag set indicates we have a string (WE HAVE TO for URLs)
710 1 : if ( !(ptr->flags & 1)) {
711 : //to check, the spec says: First name, then location
712 1 : if (ptr->nameURN) {
713 0 : gf_bs_write_data(bs, ptr->nameURN, (u32)strlen(ptr->nameURN) + 1);
714 : }
715 1 : if (ptr->location) {
716 0 : gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1);
717 : }
718 : }
719 : return GF_OK;
720 : }
721 :
722 1 : GF_Err urn_box_size(GF_Box *s)
723 : {
724 : GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
725 :
726 1 : if ( !(ptr->flags & 1)) {
727 1 : if (ptr->nameURN) ptr->size += 1 + strlen(ptr->nameURN);
728 1 : if (ptr->location) ptr->size += 1 + strlen(ptr->location);
729 : }
730 1 : return GF_OK;
731 : }
732 :
733 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
734 :
735 1388 : void unkn_box_del(GF_Box *s)
736 : {
737 : GF_UnknownBox *ptr = (GF_UnknownBox *) s;
738 1388 : if (!s) return;
739 1388 : if (ptr->data) gf_free(ptr->data);
740 1388 : gf_free(ptr);
741 : }
742 :
743 :
744 1362 : GF_Err unkn_box_read(GF_Box *s, GF_BitStream *bs)
745 : {
746 : GF_Err e;
747 : u32 bytesToRead, sub_size, sub_a;
748 : GF_BitStream *sub_bs;
749 : GF_UnknownBox *ptr = (GF_UnknownBox *)s;
750 1362 : if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE;
751 1362 : bytesToRead = (u32) (ptr->size);
752 :
753 1362 : if (!bytesToRead) return GF_OK;
754 1233 : if (bytesToRead>1000000) {
755 0 : 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 ));
756 0 : gf_bs_skip_bytes(bs, ptr->dataSize);
757 0 : return GF_OK;
758 : }
759 :
760 1233 : ptr->data = (char*)gf_malloc(bytesToRead);
761 1233 : if (ptr->data == NULL ) return GF_OUT_OF_MEM;
762 1233 : ptr->dataSize = bytesToRead;
763 1233 : gf_bs_read_data(bs, ptr->data, ptr->dataSize);
764 :
765 : //try to parse container boxes, check if next 8 bytes match a subbox
766 1233 : sub_bs = gf_bs_new(ptr->data, ptr->dataSize, GF_BITSTREAM_READ);
767 1233 : sub_size = gf_bs_read_u32(sub_bs);
768 1233 : sub_a = gf_bs_read_u8(sub_bs);
769 1233 : e = (sub_size && (sub_size <= ptr->dataSize)) ? GF_OK : GF_NOT_SUPPORTED;
770 1233 : if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
771 1233 : sub_a = gf_bs_read_u8(sub_bs);
772 1233 : if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
773 1233 : sub_a = gf_bs_read_u8(sub_bs);
774 1233 : if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
775 1233 : sub_a = gf_bs_read_u8(sub_bs);
776 1233 : if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
777 :
778 992 : if (e == GF_OK) {
779 968 : gf_bs_seek(sub_bs, 0);
780 968 : gf_bs_set_cookie(sub_bs, GF_ISOM_BS_COOKIE_NO_LOGS);
781 968 : e = gf_isom_box_array_read(s, sub_bs);
782 : }
783 1233 : gf_bs_del(sub_bs);
784 1233 : if (e==GF_OK) {
785 968 : gf_free(ptr->data);
786 968 : ptr->data = NULL;
787 968 : ptr->dataSize = 0;
788 265 : } else if (s->child_boxes) {
789 0 : gf_isom_box_array_del(s->child_boxes);
790 0 : s->child_boxes=NULL;
791 : }
792 :
793 : return GF_OK;
794 : }
795 :
796 1388 : GF_Box *unkn_box_new()
797 : {
798 2776 : ISOM_DECL_BOX_ALLOC(GF_UnknownBox, GF_ISOM_BOX_TYPE_UNKNOWN);
799 1388 : return (GF_Box *) tmp;
800 : }
801 :
802 : #ifndef GPAC_DISABLE_ISOM_WRITE
803 :
804 956 : GF_Err unkn_box_write(GF_Box *s, GF_BitStream *bs)
805 : {
806 : GF_Err e;
807 : u32 type;
808 : GF_UnknownBox *ptr = (GF_UnknownBox *)s;
809 956 : if (!s) return GF_BAD_PARAM;
810 956 : type = s->type;
811 956 : ptr->type = ptr->original_4cc;
812 956 : e = gf_isom_box_write_header(s, bs);
813 956 : ptr->type = type;
814 956 : if (e) return e;
815 :
816 956 : if (ptr->dataSize && ptr->data) {
817 184 : gf_bs_write_data(bs, ptr->data, ptr->dataSize);
818 : }
819 : return GF_OK;
820 : }
821 :
822 1688 : GF_Err unkn_box_size(GF_Box *s)
823 : {
824 : GF_UnknownBox *ptr = (GF_UnknownBox *)s;
825 :
826 1688 : if (ptr->dataSize && ptr->data) {
827 334 : ptr->size += ptr->dataSize;
828 : }
829 1688 : return GF_OK;
830 : }
831 :
832 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
833 :
834 :
835 176 : void def_parent_box_del(GF_Box *s)
836 : {
837 176 : if (s) gf_free(s);
838 176 : }
839 :
840 :
841 150 : GF_Err def_parent_box_read(GF_Box *s, GF_BitStream *bs)
842 : {
843 150 : return gf_isom_box_array_read(s, bs);
844 : }
845 :
846 176 : GF_Box *def_parent_box_new()
847 : {
848 352 : ISOM_DECL_BOX_ALLOC(GF_Box, 0);
849 176 : return (GF_Box *) tmp;
850 : }
851 :
852 : #ifndef GPAC_DISABLE_ISOM_WRITEHintSa
853 :
854 116 : GF_Err def_parent_box_write(GF_Box *s, GF_BitStream *bs)
855 : {
856 116 : return gf_isom_box_write_header(s, bs);
857 : }
858 :
859 206 : GF_Err def_parent_box_size(GF_Box *s)
860 : {
861 206 : return GF_OK;
862 : }
863 :
864 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
865 :
866 :
867 3 : void def_parent_full_box_del(GF_Box *s)
868 : {
869 3 : if (s) gf_free(s);
870 3 : }
871 :
872 :
873 1 : GF_Err def_parent_full_box_read(GF_Box *s, GF_BitStream *bs)
874 : {
875 1 : return gf_isom_box_array_read(s, bs);
876 : }
877 :
878 3 : GF_Box *def_parent_full_box_new()
879 : {
880 6 : ISOM_DECL_BOX_ALLOC(GF_Box, 0);
881 3 : return (GF_Box *) tmp;
882 : }
883 :
884 : #ifndef GPAC_DISABLE_ISOM_WRITEHintSa
885 :
886 1 : GF_Err def_parent_full_box_write(GF_Box *s, GF_BitStream *bs)
887 : {
888 1 : return gf_isom_full_box_write(s, bs);
889 : }
890 :
891 1 : GF_Err def_parent_full_box_size(GF_Box *s)
892 : {
893 1 : return GF_OK;
894 : }
895 :
896 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
897 :
898 21 : void uuid_box_del(GF_Box *s)
899 : {
900 : GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *) s;
901 21 : if (!s) return;
902 21 : if (ptr->data) gf_free(ptr->data);
903 21 : gf_free(ptr);
904 : }
905 :
906 :
907 13 : GF_Err uuid_box_read(GF_Box *s, GF_BitStream *bs)
908 : {
909 : u32 bytesToRead;
910 : GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *)s;
911 13 : if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE;
912 13 : bytesToRead = (u32) (ptr->size);
913 :
914 13 : if (bytesToRead) {
915 11 : ptr->data = (char*)gf_malloc(bytesToRead);
916 11 : if (ptr->data == NULL ) return GF_OUT_OF_MEM;
917 11 : ptr->dataSize = bytesToRead;
918 11 : gf_bs_read_data(bs, ptr->data, ptr->dataSize);
919 : }
920 : return GF_OK;
921 : }
922 :
923 21 : GF_Box *uuid_box_new()
924 : {
925 42 : ISOM_DECL_BOX_ALLOC(GF_UnknownUUIDBox, GF_ISOM_BOX_TYPE_UUID);
926 21 : return (GF_Box *) tmp;
927 : }
928 :
929 : #ifndef GPAC_DISABLE_ISOM_WRITE
930 :
931 10 : GF_Err uuid_box_write(GF_Box *s, GF_BitStream *bs)
932 : {
933 : GF_Err e;
934 : GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox*)s;
935 10 : if (!s) return GF_BAD_PARAM;
936 :
937 10 : e = gf_isom_box_write_header(s, bs);
938 10 : if (e) return e;
939 10 : if (ptr->data) {
940 8 : gf_bs_write_data(bs, ptr->data, ptr->dataSize);
941 : }
942 : return GF_OK;
943 : }
944 :
945 22 : GF_Err uuid_box_size(GF_Box *s)
946 : {
947 : GF_UnknownUUIDBox*ptr = (GF_UnknownUUIDBox*)s;
948 22 : ptr->size += ptr->dataSize;
949 22 : return GF_OK;
950 : }
951 :
952 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
953 :
954 :
955 4120 : void dinf_box_del(GF_Box *s)
956 : {
957 4120 : gf_free(s);
958 4120 : }
959 :
960 :
961 3495 : GF_Err dinf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
962 : {
963 : GF_DataInformationBox *ptr = (GF_DataInformationBox *)s;
964 3495 : switch(a->type) {
965 3495 : case GF_ISOM_BOX_TYPE_DREF:
966 3495 : BOX_FIELD_ASSIGN(dref, GF_DataReferenceBox)
967 3495 : return GF_OK;
968 : }
969 : return GF_OK;
970 : }
971 :
972 3100 : GF_Err dinf_box_read(GF_Box *s, GF_BitStream *bs)
973 : {
974 : GF_DataInformationBox *dinf;
975 3100 : GF_Err e = gf_isom_box_array_read(s, bs);
976 3100 : if (e) {
977 : return e;
978 : }
979 : dinf = (GF_DataInformationBox *)s;
980 3100 : if (!dinf->dref) {
981 616 : if (! (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_NO_LOGS) ) {
982 1 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing dref box in dinf\n"));
983 : }
984 616 : dinf->dref = (GF_DataReferenceBox *) gf_isom_box_new_parent(&dinf->child_boxes, GF_ISOM_BOX_TYPE_DREF);
985 : }
986 : return GF_OK;
987 : }
988 :
989 4120 : GF_Box *dinf_box_new()
990 : {
991 8240 : ISOM_DECL_BOX_ALLOC(GF_DataInformationBox, GF_ISOM_BOX_TYPE_DINF);
992 4120 : return (GF_Box *)tmp;
993 : }
994 :
995 : #ifndef GPAC_DISABLE_ISOM_WRITE
996 :
997 3171 : GF_Err dinf_box_write(GF_Box *s, GF_BitStream *bs)
998 : {
999 3171 : return gf_isom_box_write_header(s, bs);
1000 : }
1001 :
1002 6120 : GF_Err dinf_box_size(GF_Box *s)
1003 : {
1004 6120 : return GF_OK;
1005 : }
1006 :
1007 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1008 :
1009 4121 : void dref_box_del(GF_Box *s)
1010 : {
1011 : GF_DataReferenceBox *ptr = (GF_DataReferenceBox *) s;
1012 4121 : if (ptr == NULL) return;
1013 4121 : gf_free(ptr);
1014 : }
1015 :
1016 :
1017 2485 : GF_Err dref_box_read(GF_Box *s, GF_BitStream *bs)
1018 : {
1019 : GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
1020 2485 : ISOM_DECREASE_SIZE(ptr, 4);
1021 2485 : gf_bs_read_u32(bs);
1022 2485 : return gf_isom_box_array_read(s, bs);
1023 : }
1024 :
1025 4121 : GF_Box *dref_box_new()
1026 : {
1027 8242 : ISOM_DECL_BOX_ALLOC(GF_DataReferenceBox, GF_ISOM_BOX_TYPE_DREF);
1028 4121 : return (GF_Box *)tmp;
1029 : }
1030 :
1031 :
1032 : #ifndef GPAC_DISABLE_ISOM_WRITE
1033 :
1034 2038 : GF_Err dref_box_write(GF_Box *s, GF_BitStream *bs)
1035 : {
1036 : GF_Err e;
1037 : u32 count;
1038 : GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
1039 2038 : if (!s) return GF_BAD_PARAM;
1040 :
1041 2038 : e = gf_isom_full_box_write(s, bs);
1042 2038 : if (e) return e;
1043 2038 : count = ptr->child_boxes ? gf_list_count(ptr->child_boxes) : 0;
1044 2038 : gf_bs_write_u32(bs, count);
1045 2038 : return GF_OK;
1046 : }
1047 :
1048 4987 : GF_Err dref_box_size(GF_Box *s)
1049 : {
1050 : GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
1051 4987 : if (!s) return GF_BAD_PARAM;
1052 :
1053 4987 : ptr->size += 4;
1054 4987 : return GF_OK;
1055 : }
1056 :
1057 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1058 :
1059 1237 : void edts_box_del(GF_Box *s)
1060 : {
1061 1237 : gf_free(s);
1062 1237 : }
1063 :
1064 :
1065 1235 : GF_Err edts_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
1066 : {
1067 : GF_EditBox *ptr = (GF_EditBox *)s;
1068 1235 : if (a->type == GF_ISOM_BOX_TYPE_ELST) {
1069 1235 : BOX_FIELD_ASSIGN(editList, GF_EditListBox)
1070 1235 : return GF_OK;
1071 : } else {
1072 : return GF_OK;
1073 : }
1074 : return GF_OK;
1075 : }
1076 :
1077 :
1078 762 : GF_Err edts_box_read(GF_Box *s, GF_BitStream *bs)
1079 : {
1080 762 : return gf_isom_box_array_read(s, bs);
1081 : }
1082 :
1083 1237 : GF_Box *edts_box_new()
1084 : {
1085 2474 : ISOM_DECL_BOX_ALLOC(GF_EditBox, GF_ISOM_BOX_TYPE_EDTS);
1086 1237 : return (GF_Box *) tmp;
1087 : }
1088 :
1089 : #ifndef GPAC_DISABLE_ISOM_WRITE
1090 :
1091 783 : GF_Err edts_box_write(GF_Box *s, GF_BitStream *bs)
1092 : {
1093 : GF_EditBox *ptr = (GF_EditBox *)s;
1094 :
1095 : //here we have a trick: if editList is empty, skip the box
1096 783 : if (ptr->editList && gf_list_count(ptr->editList->entryList)) {
1097 783 : return gf_isom_box_write_header(s, bs);
1098 : } else {
1099 0 : s->size = 0;
1100 : }
1101 0 : return GF_OK;
1102 : }
1103 :
1104 1580 : GF_Err edts_box_size(GF_Box *s)
1105 : {
1106 : GF_EditBox *ptr = (GF_EditBox *)s;
1107 :
1108 : //here we have a trick: if editList is empty, skip the box
1109 1580 : if (!ptr->editList || ! gf_list_count(ptr->editList->entryList)) {
1110 1 : ptr->size = 0;
1111 : }
1112 1580 : return GF_OK;
1113 : }
1114 :
1115 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1116 :
1117 1239 : void elst_box_del(GF_Box *s)
1118 : {
1119 : GF_EditListBox *ptr;
1120 : u32 nb_entries;
1121 : u32 i;
1122 :
1123 : ptr = (GF_EditListBox *)s;
1124 1239 : if (ptr == NULL) return;
1125 1239 : nb_entries = gf_list_count(ptr->entryList);
1126 2265 : for (i = 0; i < nb_entries; i++) {
1127 1026 : GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
1128 1026 : if (p) gf_free(p);
1129 : }
1130 1239 : gf_list_del(ptr->entryList);
1131 1239 : gf_free(ptr);
1132 : }
1133 :
1134 763 : GF_Err elst_box_read(GF_Box *s, GF_BitStream *bs)
1135 : {
1136 : u32 entries;
1137 : s32 tr;
1138 : u32 nb_entries;
1139 : GF_EditListBox *ptr = (GF_EditListBox *)s;
1140 :
1141 763 : ISOM_DECREASE_SIZE(ptr, 4);
1142 763 : nb_entries = gf_bs_read_u32(bs);
1143 :
1144 763 : if (ptr->version == 1) {
1145 0 : if (nb_entries > ptr->size / 20) {
1146 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", nb_entries));
1147 : return GF_ISOM_INVALID_FILE;
1148 : }
1149 : } else {
1150 763 : if (nb_entries > ptr->size / 12) {
1151 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", nb_entries));
1152 : return GF_ISOM_INVALID_FILE;
1153 : }
1154 : }
1155 :
1156 :
1157 763 : for (entries = 0; entries < nb_entries; entries++) {
1158 : GF_EdtsEntry *p;
1159 763 : GF_SAFEALLOC(p, GF_EdtsEntry);
1160 763 : if (!p) return GF_OUT_OF_MEM;
1161 763 : if (ptr->version == 1) {
1162 0 : ISOM_DECREASE_SIZE(ptr, 16);
1163 0 : p->segmentDuration = gf_bs_read_u64(bs);
1164 0 : p->mediaTime = (s64) gf_bs_read_u64(bs);
1165 : } else {
1166 763 : ISOM_DECREASE_SIZE(ptr, 8);
1167 763 : p->segmentDuration = gf_bs_read_u32(bs);
1168 763 : tr = gf_bs_read_u32(bs);
1169 763 : p->mediaTime = (s64) tr;
1170 : }
1171 763 : ISOM_DECREASE_SIZE(ptr, 4);
1172 763 : p->mediaRate = gf_bs_read_u32(bs);
1173 763 : gf_list_add(ptr->entryList, p);
1174 : }
1175 : return GF_OK;
1176 : }
1177 :
1178 1239 : GF_Box *elst_box_new()
1179 : {
1180 2478 : ISOM_DECL_BOX_ALLOC(GF_EditListBox, GF_ISOM_BOX_TYPE_ELST);
1181 1239 : tmp->entryList = gf_list_new();
1182 1239 : if (!tmp->entryList) {
1183 0 : gf_free(tmp);
1184 0 : return NULL;
1185 : }
1186 : return (GF_Box *)tmp;
1187 : }
1188 :
1189 : #ifndef GPAC_DISABLE_ISOM_WRITE
1190 :
1191 784 : GF_Err elst_box_write(GF_Box *s, GF_BitStream *bs)
1192 : {
1193 : GF_Err e;
1194 : u32 i;
1195 : u32 nb_entries;
1196 : GF_EditListBox *ptr = (GF_EditListBox *)s;
1197 784 : if (!ptr) return GF_BAD_PARAM;
1198 :
1199 784 : nb_entries = gf_list_count(ptr->entryList);
1200 784 : e = gf_isom_full_box_write(s, bs);
1201 784 : if (e) return e;
1202 784 : gf_bs_write_u32(bs, nb_entries);
1203 1621 : for (i = 0; i < nb_entries; i++ ) {
1204 837 : GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
1205 837 : if (ptr->version == 1) {
1206 0 : gf_bs_write_u64(bs, p->segmentDuration);
1207 0 : gf_bs_write_u64(bs, p->mediaTime);
1208 : } else {
1209 837 : gf_bs_write_u32(bs, (u32) p->segmentDuration);
1210 837 : gf_bs_write_u32(bs, (s32) p->mediaTime);
1211 : }
1212 837 : gf_bs_write_u32(bs, p->mediaRate);
1213 : }
1214 : return GF_OK;
1215 : }
1216 :
1217 1580 : GF_Err elst_box_size(GF_Box *s)
1218 : {
1219 : u32 durtimebytes;
1220 : u32 i, nb_entries;
1221 : GF_EditListBox *ptr = (GF_EditListBox *)s;
1222 :
1223 : //entry count
1224 1580 : ptr->size += 4;
1225 1580 : nb_entries = gf_list_count(ptr->entryList);
1226 1580 : ptr->version = 0;
1227 3309 : for (i=0; i<nb_entries; i++) {
1228 1729 : GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
1229 1729 : if ((p->segmentDuration>0xFFFFFFFF) || (p->mediaTime>0xFFFFFFFF)) {
1230 0 : ptr->version = 1;
1231 0 : break;
1232 : }
1233 : }
1234 1580 : durtimebytes = (ptr->version == 1 ? 16 : 8) + 4;
1235 1580 : ptr->size += (nb_entries * durtimebytes);
1236 1580 : return GF_OK;
1237 : }
1238 :
1239 :
1240 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1241 :
1242 1542 : void esds_box_del(GF_Box *s)
1243 : {
1244 : GF_ESDBox *ptr = (GF_ESDBox *)s;
1245 1542 : if (ptr == NULL) return;
1246 1542 : if (ptr->desc) gf_odf_desc_del((GF_Descriptor *)ptr->desc);
1247 1542 : gf_free(ptr);
1248 : }
1249 :
1250 :
1251 1049 : GF_Err esds_box_read(GF_Box *s, GF_BitStream *bs)
1252 : {
1253 : GF_Err e=GF_OK;
1254 : u32 descSize;
1255 : GF_ESDBox *ptr = (GF_ESDBox *)s;
1256 :
1257 1049 : descSize = (u32) (ptr->size);
1258 :
1259 1049 : if (descSize) {
1260 1049 : char *enc_desc = (char*)gf_malloc(sizeof(char) * descSize);
1261 1049 : if (!enc_desc) return GF_OUT_OF_MEM;
1262 : //get the payload
1263 1049 : gf_bs_read_data(bs, enc_desc, descSize);
1264 : //send it to the OD Codec
1265 1049 : e = gf_odf_desc_read(enc_desc, descSize, (GF_Descriptor **) &ptr->desc);
1266 : //OK, free our desc
1267 1049 : gf_free(enc_desc);
1268 :
1269 1049 : if (ptr->desc && (ptr->desc->tag!=GF_ODF_ESD_TAG) ) {
1270 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid descriptor tag 0x%x in esds\n", ptr->desc->tag));
1271 0 : gf_odf_desc_del((GF_Descriptor*)ptr->desc);
1272 0 : ptr->desc=NULL;
1273 0 : return GF_ISOM_INVALID_FILE;
1274 : }
1275 :
1276 1049 : if (e) {
1277 0 : ptr->desc = NULL;
1278 : } else {
1279 : /*fix broken files*/
1280 1049 : if (ptr->desc && !ptr->desc->URLString) {
1281 1049 : if (!ptr->desc->slConfig) {
1282 0 : ptr->desc->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);
1283 0 : ptr->desc->slConfig->predefined = SLPredef_MP4;
1284 1049 : } else if (ptr->desc->slConfig->predefined != SLPredef_MP4) {
1285 0 : ptr->desc->slConfig->predefined = SLPredef_MP4;
1286 0 : gf_odf_slc_set_pref(ptr->desc->slConfig);
1287 : }
1288 : }
1289 : }
1290 : }
1291 : return e;
1292 : }
1293 :
1294 1542 : GF_Box *esds_box_new()
1295 : {
1296 3084 : ISOM_DECL_BOX_ALLOC(GF_ESDBox, GF_ISOM_BOX_TYPE_ESDS);
1297 1542 : return (GF_Box *)tmp;
1298 : }
1299 :
1300 :
1301 : #ifndef GPAC_DISABLE_ISOM_WRITE
1302 :
1303 913 : GF_Err esds_box_write(GF_Box *s, GF_BitStream *bs)
1304 : {
1305 : GF_Err e;
1306 : u8 *enc_desc;
1307 913 : u32 descSize = 0;
1308 : GF_ESDBox *ptr = (GF_ESDBox *)s;
1309 : //make sure we write with no ESID and no OCRESID
1310 913 : if (ptr->desc) {
1311 912 : ptr->desc->ESID = 0;
1312 912 : ptr->desc->OCRESID = 0;
1313 : }
1314 913 : e = gf_isom_full_box_write(s, bs);
1315 913 : if (e) return e;
1316 913 : e = gf_odf_desc_write((GF_Descriptor *)ptr->desc, &enc_desc, &descSize);
1317 913 : if (e) return e;
1318 912 : gf_bs_write_data(bs, enc_desc, descSize);
1319 : //free our buffer
1320 912 : gf_free(enc_desc);
1321 912 : return GF_OK;
1322 : }
1323 :
1324 1938 : GF_Err esds_box_size(GF_Box *s)
1325 : {
1326 : u32 descSize = 0;
1327 : GF_ESDBox *ptr = (GF_ESDBox *)s;
1328 : //make sure we write with no ESID and no OCRESID
1329 1938 : if (ptr->desc) {
1330 1937 : ptr->desc->ESID = 0;
1331 1937 : ptr->desc->OCRESID = 0;
1332 : }
1333 1938 : descSize = gf_odf_desc_size((GF_Descriptor *)ptr->desc);
1334 1938 : ptr->size += descSize;
1335 1938 : return GF_OK;
1336 : }
1337 :
1338 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1339 :
1340 3045 : void free_box_del(GF_Box *s)
1341 : {
1342 : GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
1343 3045 : if (ptr->data) gf_free(ptr->data);
1344 3045 : gf_free(ptr);
1345 3045 : }
1346 :
1347 :
1348 1791 : GF_Err free_box_read(GF_Box *s, GF_BitStream *bs)
1349 : {
1350 : u32 bytesToRead;
1351 : GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
1352 :
1353 1791 : if (ptr->size > 0xFFFFFFFF) return GF_IO_ERR;
1354 :
1355 1791 : bytesToRead = (u32) (ptr->size);
1356 :
1357 1791 : if (bytesToRead) {
1358 1717 : ptr->data = (char*)gf_malloc(bytesToRead * sizeof(char));
1359 1717 : if (!ptr->data) return GF_OUT_OF_MEM;
1360 1717 : gf_bs_read_data(bs, ptr->data, bytesToRead);
1361 1717 : ptr->dataSize = bytesToRead;
1362 : }
1363 : return GF_OK;
1364 : }
1365 :
1366 3045 : GF_Box *free_box_new()
1367 : {
1368 6090 : ISOM_DECL_BOX_ALLOC(GF_FreeSpaceBox, GF_ISOM_BOX_TYPE_FREE);
1369 3045 : return (GF_Box *)tmp;
1370 : }
1371 :
1372 : #ifndef GPAC_DISABLE_ISOM_WRITE
1373 :
1374 1418 : GF_Err free_box_write(GF_Box *s, GF_BitStream *bs)
1375 : {
1376 : GF_Err e;
1377 : GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
1378 1418 : if (ptr->original_4cc) {
1379 0 : u32 t = s->type;
1380 0 : s->type=ptr->original_4cc;
1381 0 : e = gf_isom_box_write_header(s, bs);
1382 0 : s->type=t;
1383 : } else {
1384 1418 : e = gf_isom_box_write_header(s, bs);
1385 : }
1386 1418 : if (e) return e;
1387 1418 : if (ptr->dataSize) {
1388 1403 : if (ptr->data) {
1389 1403 : gf_bs_write_data(bs, ptr->data, ptr->dataSize);
1390 : } else {
1391 : u32 i = 0;
1392 0 : while (i<ptr->dataSize) {
1393 0 : gf_bs_write_u8(bs, 0);
1394 0 : i++;
1395 : }
1396 : }
1397 : }
1398 : return GF_OK;
1399 : }
1400 :
1401 1425 : GF_Err free_box_size(GF_Box *s)
1402 : {
1403 : GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
1404 1425 : ptr->size += ptr->dataSize;
1405 1425 : return GF_OK;
1406 : }
1407 :
1408 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1409 :
1410 5720 : void ftyp_box_del(GF_Box *s)
1411 : {
1412 : GF_FileTypeBox *ptr = (GF_FileTypeBox *) s;
1413 5720 : if (ptr->altBrand) gf_free(ptr->altBrand);
1414 5720 : gf_free(ptr);
1415 5720 : }
1416 :
1417 5720 : GF_Box *ftyp_box_new()
1418 : {
1419 11440 : ISOM_DECL_BOX_ALLOC(GF_FileTypeBox, GF_ISOM_BOX_TYPE_FTYP);
1420 5720 : return (GF_Box *)tmp;
1421 : }
1422 :
1423 4419 : GF_Err ftyp_box_read(GF_Box *s,GF_BitStream *bs)
1424 : {
1425 : u32 i;
1426 : GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;
1427 :
1428 4419 : ISOM_DECREASE_SIZE(ptr, 8);
1429 4419 : ptr->majorBrand = gf_bs_read_u32(bs);
1430 4419 : ptr->minorVersion = gf_bs_read_u32(bs);
1431 :
1432 4419 : if (ptr->size % 4) return GF_ISOM_INVALID_FILE;
1433 4419 : ptr->altCount = ( (u32) (ptr->size)) / 4;
1434 4419 : if (!ptr->altCount) return GF_OK;
1435 :
1436 4417 : ptr->altBrand = (u32*)gf_malloc(sizeof(u32)*ptr->altCount);
1437 4417 : if (!ptr->altBrand) return GF_OUT_OF_MEM;
1438 :
1439 8585 : for (i = 0; i<ptr->altCount; i++) {
1440 8585 : ptr->altBrand[i] = gf_bs_read_u32(bs);
1441 : }
1442 : return GF_OK;
1443 : }
1444 :
1445 :
1446 :
1447 : #ifndef GPAC_DISABLE_ISOM_WRITE
1448 :
1449 4036 : GF_Err ftyp_box_write(GF_Box *s, GF_BitStream *bs)
1450 : {
1451 : GF_Err e;
1452 : u32 i;
1453 : GF_FileTypeBox *ptr = (GF_FileTypeBox *) s;
1454 :
1455 4036 : e = gf_isom_box_write_header(s, bs);
1456 4036 : if (e) return e;
1457 4036 : gf_bs_write_u32(bs, ptr->majorBrand);
1458 4036 : gf_bs_write_u32(bs, ptr->minorVersion);
1459 12012 : for (i=0; i<ptr->altCount; i++) {
1460 7976 : gf_bs_write_u32(bs, ptr->altBrand[i]);
1461 : }
1462 : return GF_OK;
1463 : }
1464 :
1465 4055 : GF_Err ftyp_box_size(GF_Box *s)
1466 : {
1467 : GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;
1468 :
1469 4055 : ptr->size += 8 + ptr->altCount * 4;
1470 4055 : return GF_OK;
1471 : }
1472 :
1473 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1474 :
1475 :
1476 :
1477 8 : void gnrm_box_del(GF_Box *s)
1478 : {
1479 : GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
1480 8 : gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
1481 8 : if (ptr->data) gf_free(ptr->data);
1482 8 : gf_free(ptr);
1483 8 : }
1484 :
1485 8 : GF_Box *gnrm_box_new()
1486 : {
1487 16 : ISOM_DECL_BOX_ALLOC(GF_GenericSampleEntryBox, GF_ISOM_BOX_TYPE_GNRM);
1488 :
1489 8 : gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
1490 8 : return (GF_Box *)tmp;
1491 : }
1492 :
1493 : //dummy
1494 0 : GF_Err gnrm_box_read(GF_Box *s, GF_BitStream *bs)
1495 : {
1496 0 : return GF_OK;
1497 : }
1498 :
1499 : #ifndef GPAC_DISABLE_ISOM_WRITE
1500 :
1501 1 : GF_Err gnrm_box_write(GF_Box *s, GF_BitStream *bs)
1502 : {
1503 : GF_Err e;
1504 : GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
1505 :
1506 : //careful we are not writing the box type but the entry type so switch for write
1507 1 : ptr->type = ptr->EntryType;
1508 1 : e = gf_isom_box_write_header(s, bs);
1509 1 : if (e) return e;
1510 1 : ptr->type = GF_ISOM_BOX_TYPE_GNRM;
1511 1 : gf_bs_write_data(bs, ptr->reserved, 6);
1512 1 : gf_bs_write_u16(bs, ptr->dataReferenceIndex);
1513 1 : gf_bs_write_data(bs, ptr->data, ptr->data_size);
1514 1 : return GF_OK;
1515 : }
1516 :
1517 1 : GF_Err gnrm_box_size(GF_Box *s)
1518 : {
1519 : GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
1520 1 : s->type = GF_ISOM_BOX_TYPE_GNRM;
1521 1 : ptr->size += 8+ptr->data_size;
1522 1 : return GF_OK;
1523 : }
1524 :
1525 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1526 :
1527 :
1528 22 : void gnrv_box_del(GF_Box *s)
1529 : {
1530 : GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
1531 22 : gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
1532 22 : if (ptr->data) gf_free(ptr->data);
1533 22 : gf_free(ptr);
1534 22 : }
1535 :
1536 22 : GF_Box *gnrv_box_new()
1537 : {
1538 44 : ISOM_DECL_BOX_ALLOC(GF_GenericVisualSampleEntryBox, GF_ISOM_BOX_TYPE_GNRV);
1539 22 : gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox*) tmp);
1540 22 : return (GF_Box *)tmp;
1541 : }
1542 : //dummy
1543 0 : GF_Err gnrv_box_read(GF_Box *s, GF_BitStream *bs)
1544 : {
1545 0 : return GF_OK;
1546 : }
1547 :
1548 :
1549 : #ifndef GPAC_DISABLE_ISOM_WRITE
1550 :
1551 20 : GF_Err gnrv_box_write(GF_Box *s, GF_BitStream *bs)
1552 : {
1553 : GF_Err e;
1554 : GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
1555 :
1556 : //careful we are not writing the box type but the entry type so switch for write
1557 20 : ptr->type = ptr->EntryType;
1558 20 : e = gf_isom_box_write_header(s, bs);
1559 20 : if (e) return e;
1560 20 : ptr->type = GF_ISOM_BOX_TYPE_GNRV;
1561 :
1562 20 : gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)ptr, bs);
1563 20 : gf_bs_write_data(bs, ptr->data, ptr->data_size);
1564 20 : return GF_OK;
1565 : }
1566 :
1567 58 : GF_Err gnrv_box_size(GF_Box *s)
1568 : {
1569 : GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
1570 58 : s->type = GF_ISOM_BOX_TYPE_GNRV;
1571 58 : gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);
1572 58 : ptr->size += ptr->data_size;
1573 58 : return GF_OK;
1574 : }
1575 :
1576 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1577 :
1578 :
1579 :
1580 70 : void gnra_box_del(GF_Box *s)
1581 : {
1582 : GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
1583 70 : gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
1584 70 : if (ptr->data) gf_free(ptr->data);
1585 70 : gf_free(ptr);
1586 70 : }
1587 :
1588 70 : GF_Box *gnra_box_new()
1589 : {
1590 140 : ISOM_DECL_BOX_ALLOC(GF_GenericAudioSampleEntryBox, GF_ISOM_BOX_TYPE_GNRA);
1591 70 : gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*) tmp);
1592 70 : return (GF_Box *)tmp;
1593 : }
1594 : //dummy
1595 0 : GF_Err gnra_box_read(GF_Box *s, GF_BitStream *bs)
1596 : {
1597 0 : return GF_OK;
1598 : }
1599 : #ifndef GPAC_DISABLE_ISOM_WRITE
1600 :
1601 :
1602 69 : GF_Err gnra_box_write(GF_Box *s, GF_BitStream *bs)
1603 : {
1604 : GF_Err e;
1605 : GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
1606 :
1607 : //careful we are not writing the box type but the entry type so switch for write
1608 69 : ptr->type = ptr->EntryType;
1609 69 : e = gf_isom_box_write_header(s, bs);
1610 69 : if (e) return e;
1611 69 : ptr->type = GF_ISOM_BOX_TYPE_GNRA;
1612 :
1613 69 : gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox *)ptr, bs);
1614 69 : if (ptr->data) {
1615 5 : gf_bs_write_data(bs, ptr->data, ptr->data_size);
1616 : }
1617 : return GF_OK;
1618 : }
1619 :
1620 195 : GF_Err gnra_box_size(GF_Box *s)
1621 : {
1622 : GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
1623 195 : s->type = GF_ISOM_BOX_TYPE_GNRA;
1624 195 : gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox *)s);
1625 195 : ptr->size += ptr->data_size;
1626 195 : return GF_OK;
1627 : }
1628 :
1629 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1630 :
1631 4536 : void hdlr_box_del(GF_Box *s)
1632 : {
1633 : GF_HandlerBox *ptr = (GF_HandlerBox *)s;
1634 4536 : if (ptr == NULL) return;
1635 4536 : if (ptr->nameUTF8) gf_free(ptr->nameUTF8);
1636 4536 : gf_free(ptr);
1637 : }
1638 :
1639 :
1640 3426 : GF_Err hdlr_box_read(GF_Box *s, GF_BitStream *bs)
1641 : {
1642 : u64 cookie;
1643 : GF_HandlerBox *ptr = (GF_HandlerBox *)s;
1644 :
1645 3426 : ISOM_DECREASE_SIZE(ptr, 20);
1646 3426 : ptr->reserved1 = gf_bs_read_u32(bs);
1647 3426 : ptr->handlerType = gf_bs_read_u32(bs);
1648 3426 : gf_bs_read_data(bs, (char*)ptr->reserved2, 12);
1649 :
1650 3426 : cookie = gf_bs_get_cookie(bs);
1651 3426 : if (ptr->handlerType==GF_ISOM_MEDIA_VISUAL)
1652 1814 : cookie |= GF_ISOM_BS_COOKIE_VISUAL_TRACK;
1653 : else
1654 1612 : cookie &= ~GF_ISOM_BS_COOKIE_VISUAL_TRACK;
1655 3426 : gf_bs_set_cookie(bs, cookie);
1656 :
1657 3426 : if (ptr->size) {
1658 3426 : ptr->nameUTF8 = (char*)gf_malloc((u32) ptr->size);
1659 3426 : if (!ptr->nameUTF8) return GF_OUT_OF_MEM;
1660 3426 : gf_bs_read_data(bs, ptr->nameUTF8, (u32) ptr->size);
1661 :
1662 : //patch for old QT files - we cannot rely on checking if str[0]==len(str+1) since we may have
1663 : //cases where the first character of the string decimal value is indeed the same as the string length!!
1664 : //we had this issue with encryption_import test
1665 : //we therefore only check if last char is null, and if not so assume old QT style
1666 3426 : if (ptr->nameUTF8[ptr->size-1]) {
1667 266 : memmove(ptr->nameUTF8, ptr->nameUTF8+1, sizeof(char) * (u32) (ptr->size-1) );
1668 266 : ptr->nameUTF8[ptr->size-1] = 0;
1669 266 : ptr->store_counted_string = GF_TRUE;
1670 : }
1671 : }
1672 : return GF_OK;
1673 : }
1674 :
1675 4536 : GF_Box *hdlr_box_new()
1676 : {
1677 9072 : ISOM_DECL_BOX_ALLOC(GF_HandlerBox, GF_ISOM_BOX_TYPE_HDLR);
1678 4536 : return (GF_Box *)tmp;
1679 : }
1680 :
1681 :
1682 : #ifndef GPAC_DISABLE_ISOM_WRITE
1683 :
1684 3453 : GF_Err hdlr_box_write(GF_Box *s, GF_BitStream *bs)
1685 : {
1686 : GF_Err e;
1687 : GF_HandlerBox *ptr = (GF_HandlerBox *)s;
1688 3453 : e = gf_isom_full_box_write(s, bs);
1689 3453 : if (e) return e;
1690 3453 : gf_bs_write_u32(bs, ptr->reserved1);
1691 3453 : gf_bs_write_u32(bs, ptr->handlerType);
1692 3453 : gf_bs_write_data(bs, (char*)ptr->reserved2, 12);
1693 :
1694 3453 : if (ptr->nameUTF8) {
1695 3446 : u32 len = (u32)strlen(ptr->nameUTF8);
1696 3446 : if (ptr->store_counted_string) {
1697 178 : gf_bs_write_u8(bs, len);
1698 178 : gf_bs_write_data(bs, ptr->nameUTF8, len);
1699 : } else {
1700 3268 : gf_bs_write_data(bs, ptr->nameUTF8, len);
1701 3268 : gf_bs_write_u8(bs, 0);
1702 : }
1703 : } else {
1704 7 : gf_bs_write_u8(bs, 0);
1705 : }
1706 : return GF_OK;
1707 : }
1708 :
1709 6728 : GF_Err hdlr_box_size(GF_Box *s)
1710 : {
1711 : GF_HandlerBox *ptr = (GF_HandlerBox *)s;
1712 6728 : ptr->size += 20 + 1; //null term or counted string
1713 6728 : if (ptr->nameUTF8) {
1714 6719 : ptr->size += strlen(ptr->nameUTF8);
1715 : }
1716 6728 : return GF_OK;
1717 : }
1718 :
1719 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1720 :
1721 :
1722 3 : void hinf_box_del(GF_Box *s)
1723 : {
1724 : GF_HintInfoBox *hinf = (GF_HintInfoBox *)s;
1725 3 : gf_free(hinf);
1726 3 : }
1727 :
1728 3 : GF_Box *hinf_box_new()
1729 : {
1730 6 : ISOM_DECL_BOX_ALLOC(GF_HintInfoBox, GF_ISOM_BOX_TYPE_HINF);
1731 :
1732 3 : tmp->child_boxes = gf_list_new();
1733 3 : return (GF_Box *)tmp;
1734 : }
1735 :
1736 0 : GF_Err hinf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
1737 : {
1738 : GF_HintInfoBox *hinf = (GF_HintInfoBox *)s;
1739 0 : switch (a->type) {
1740 0 : case GF_ISOM_BOX_TYPE_MAXR:
1741 0 : if (!is_rem) {
1742 0 : u32 i=0;
1743 : GF_MAXRBox *maxR;
1744 0 : while ((maxR = (GF_MAXRBox *)gf_list_enum(hinf->child_boxes, &i))) {
1745 0 : if ((maxR->type==GF_ISOM_BOX_TYPE_MAXR) && (maxR->granularity == ((GF_MAXRBox *)a)->granularity))
1746 0 : ERROR_ON_DUPLICATED_BOX(a, s)
1747 : }
1748 : }
1749 : break;
1750 : }
1751 : return GF_OK;
1752 : }
1753 :
1754 :
1755 1 : GF_Err hinf_box_read(GF_Box *s, GF_BitStream *bs)
1756 : {
1757 1 : return gf_isom_box_array_read(s, bs);
1758 : }
1759 :
1760 : #ifndef GPAC_DISABLE_ISOM_WRITE
1761 :
1762 1 : GF_Err hinf_box_write(GF_Box *s, GF_BitStream *bs)
1763 : {
1764 : // GF_HintInfoBox *ptr = (GF_HintInfoBox *)s;
1765 1 : if (!s) return GF_BAD_PARAM;
1766 1 : return gf_isom_box_write_header(s, bs);
1767 : }
1768 :
1769 1 : GF_Err hinf_box_size(GF_Box *s)
1770 : {
1771 1 : return GF_OK;
1772 : }
1773 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1774 :
1775 121 : void hmhd_box_del(GF_Box *s)
1776 : {
1777 : GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
1778 121 : if (ptr == NULL) return;
1779 121 : gf_free(ptr);
1780 : }
1781 :
1782 :
1783 46 : GF_Err hmhd_box_read(GF_Box *s,GF_BitStream *bs)
1784 : {
1785 : GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
1786 :
1787 46 : ISOM_DECREASE_SIZE(ptr, 16);
1788 46 : ptr->maxPDUSize = gf_bs_read_u16(bs);
1789 46 : ptr->avgPDUSize = gf_bs_read_u16(bs);
1790 46 : ptr->maxBitrate = gf_bs_read_u32(bs);
1791 46 : ptr->avgBitrate = gf_bs_read_u32(bs);
1792 46 : ptr->slidingAverageBitrate = gf_bs_read_u32(bs);
1793 46 : return GF_OK;
1794 : }
1795 :
1796 121 : GF_Box *hmhd_box_new()
1797 : {
1798 242 : ISOM_DECL_BOX_ALLOC(GF_HintMediaHeaderBox, GF_ISOM_BOX_TYPE_HMHD);
1799 121 : return (GF_Box *)tmp;
1800 : }
1801 :
1802 :
1803 : #ifndef GPAC_DISABLE_ISOM_WRITE
1804 :
1805 74 : GF_Err hmhd_box_write(GF_Box *s, GF_BitStream *bs)
1806 : {
1807 : GF_Err e;
1808 : GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
1809 :
1810 74 : e = gf_isom_full_box_write(s, bs);
1811 74 : if (e) return e;
1812 74 : gf_bs_write_u16(bs, ptr->maxPDUSize);
1813 74 : gf_bs_write_u16(bs, ptr->avgPDUSize);
1814 74 : gf_bs_write_u32(bs, ptr->maxBitrate);
1815 74 : gf_bs_write_u32(bs, ptr->avgBitrate);
1816 74 : gf_bs_write_u32(bs, ptr->slidingAverageBitrate);
1817 74 : return GF_OK;
1818 : }
1819 :
1820 220 : GF_Err hmhd_box_size(GF_Box *s)
1821 : {
1822 : GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
1823 220 : ptr->size += 16;
1824 220 : return GF_OK;
1825 : }
1826 :
1827 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1828 :
1829 219 : GF_Box *hnti_box_new()
1830 : {
1831 438 : ISOM_DECL_BOX_ALLOC(GF_HintTrackInfoBox, GF_ISOM_BOX_TYPE_HNTI);
1832 219 : return (GF_Box *)tmp;
1833 : }
1834 :
1835 219 : void hnti_box_del(GF_Box *a)
1836 : {
1837 219 : gf_free(a);
1838 219 : }
1839 :
1840 216 : GF_Err hnti_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
1841 : {
1842 : GF_HintTrackInfoBox *ptr = (GF_HintTrackInfoBox *)s;
1843 216 : if (!ptr || !a) return GF_BAD_PARAM;
1844 :
1845 216 : switch (a->type) {
1846 : //this is the value for GF_RTPBox - same as HintSampleEntry for RTP !!!
1847 216 : case GF_ISOM_BOX_TYPE_RTP:
1848 : case GF_ISOM_BOX_TYPE_SDP:
1849 216 : BOX_FIELD_ASSIGN(SDP, GF_Box)
1850 216 : break;
1851 : default:
1852 : break;
1853 : }
1854 : return GF_OK;
1855 : }
1856 :
1857 89 : GF_Err hnti_box_read(GF_Box *s, GF_BitStream *bs)
1858 : {
1859 89 : return gf_isom_box_array_read_ex(s, bs, s->type);
1860 : }
1861 :
1862 : #ifndef GPAC_DISABLE_ISOM_WRITE
1863 129 : GF_Err hnti_box_write(GF_Box *s, GF_BitStream *bs)
1864 : {
1865 129 : return gf_isom_box_write_header(s, bs);
1866 : }
1867 :
1868 :
1869 385 : GF_Err hnti_box_size(GF_Box *s)
1870 : {
1871 385 : return GF_OK;
1872 : }
1873 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1874 :
1875 : /**********************************************************
1876 : GF_SDPBox
1877 : **********************************************************/
1878 :
1879 121 : void sdp_box_del(GF_Box *s)
1880 : {
1881 : GF_SDPBox *ptr = (GF_SDPBox *)s;
1882 121 : if (ptr->sdpText) gf_free(ptr->sdpText);
1883 121 : gf_free(ptr);
1884 :
1885 121 : }
1886 46 : GF_Err sdp_box_read(GF_Box *s, GF_BitStream *bs)
1887 : {
1888 : u32 length;
1889 : GF_SDPBox *ptr = (GF_SDPBox *)s;
1890 46 : if (ptr == NULL) return GF_BAD_PARAM;
1891 :
1892 46 : length = (u32) (ptr->size);
1893 : //sdp text has no delimiter !!!
1894 46 : ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length+1));
1895 46 : if (!ptr->sdpText) return GF_OUT_OF_MEM;
1896 :
1897 46 : gf_bs_read_data(bs, ptr->sdpText, length);
1898 46 : ptr->sdpText[length] = 0;
1899 46 : return GF_OK;
1900 : }
1901 121 : GF_Box *sdp_box_new()
1902 : {
1903 242 : ISOM_DECL_BOX_ALLOC(GF_SDPBox, GF_ISOM_BOX_TYPE_SDP);
1904 121 : return (GF_Box *)tmp;
1905 : }
1906 : #ifndef GPAC_DISABLE_ISOM_WRITE
1907 74 : GF_Err sdp_box_write(GF_Box *s, GF_BitStream *bs)
1908 : {
1909 : GF_Err e;
1910 : GF_SDPBox *ptr = (GF_SDPBox *)s;
1911 74 : if (ptr == NULL) return GF_BAD_PARAM;
1912 74 : e = gf_isom_box_write_header(s, bs);
1913 74 : if (e) return e;
1914 : //don't write the NULL char!!!
1915 74 : if (ptr->sdpText)
1916 73 : gf_bs_write_data(bs, ptr->sdpText, (u32) strlen(ptr->sdpText));
1917 : return GF_OK;
1918 : }
1919 220 : GF_Err sdp_box_size(GF_Box *s)
1920 : {
1921 : GF_SDPBox *ptr = (GF_SDPBox *)s;
1922 : //don't count the NULL char!!!
1923 220 : if (ptr->sdpText)
1924 219 : ptr->size += strlen(ptr->sdpText);
1925 220 : return GF_OK;
1926 : }
1927 :
1928 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1929 :
1930 :
1931 :
1932 :
1933 99 : void rtp_hnti_box_del(GF_Box *s)
1934 : {
1935 : GF_RTPBox *ptr = (GF_RTPBox *)s;
1936 99 : if (ptr->sdpText) gf_free(ptr->sdpText);
1937 99 : gf_free(ptr);
1938 :
1939 99 : }
1940 43 : GF_Err rtp_hnti_box_read(GF_Box *s, GF_BitStream *bs)
1941 : {
1942 : u32 length;
1943 : GF_RTPBox *ptr = (GF_RTPBox *)s;
1944 43 : if (ptr == NULL) return GF_BAD_PARAM;
1945 :
1946 43 : ISOM_DECREASE_SIZE(ptr, 4)
1947 43 : ptr->subType = gf_bs_read_u32(bs);
1948 :
1949 43 : length = (u32) (ptr->size);
1950 : //sdp text has no delimiter !!!
1951 43 : ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length+1));
1952 43 : if (!ptr->sdpText) return GF_OUT_OF_MEM;
1953 :
1954 43 : gf_bs_read_data(bs, ptr->sdpText, length);
1955 43 : ptr->sdpText[length] = 0;
1956 43 : return GF_OK;
1957 : }
1958 :
1959 99 : GF_Box *rtp_hnti_box_new()
1960 : {
1961 198 : ISOM_DECL_BOX_ALLOC(GF_RTPBox, GF_ISOM_BOX_TYPE_RTP);
1962 99 : tmp->subType = GF_ISOM_BOX_TYPE_SDP;
1963 99 : return (GF_Box *)tmp;
1964 : }
1965 : #ifndef GPAC_DISABLE_ISOM_WRITE
1966 55 : GF_Err rtp_hnti_box_write(GF_Box *s, GF_BitStream *bs)
1967 : {
1968 : GF_Err e;
1969 : GF_RTPBox *ptr = (GF_RTPBox *)s;
1970 55 : if (ptr == NULL) return GF_BAD_PARAM;
1971 55 : e = gf_isom_box_write_header(s, bs);
1972 55 : if (e) return e;
1973 55 : gf_bs_write_u32(bs, ptr->subType);
1974 : //don't write the NULL char!!!
1975 55 : gf_bs_write_data(bs, ptr->sdpText, (u32) strlen(ptr->sdpText));
1976 55 : return GF_OK;
1977 : }
1978 :
1979 165 : GF_Err rtp_hnti_box_size(GF_Box *s)
1980 : {
1981 : GF_RTPBox *ptr = (GF_RTPBox *)s;
1982 165 : ptr->size += 4 + strlen(ptr->sdpText);
1983 165 : return GF_OK;
1984 : }
1985 :
1986 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1987 :
1988 :
1989 : /**********************************************************
1990 : TRPY GF_Box
1991 : **********************************************************/
1992 :
1993 3 : void trpy_box_del(GF_Box *s)
1994 : {
1995 3 : gf_free((GF_TRPYBox *)s);
1996 3 : }
1997 1 : GF_Err trpy_box_read(GF_Box *s, GF_BitStream *bs)
1998 : {
1999 : GF_TRPYBox *ptr = (GF_TRPYBox *)s;
2000 1 : ISOM_DECREASE_SIZE(ptr, 8);
2001 1 : ptr->nbBytes = gf_bs_read_u64(bs);
2002 1 : return GF_OK;
2003 : }
2004 3 : GF_Box *trpy_box_new()
2005 : {
2006 6 : ISOM_DECL_BOX_ALLOC(GF_TRPYBox, GF_ISOM_BOX_TYPE_TRPY);
2007 3 : return (GF_Box *)tmp;
2008 : }
2009 : #ifndef GPAC_DISABLE_ISOM_WRITE
2010 :
2011 1 : GF_Err trpy_box_write(GF_Box *s, GF_BitStream *bs)
2012 : {
2013 : GF_Err e;
2014 : GF_TRPYBox *ptr = (GF_TRPYBox *)s;
2015 1 : if (ptr == NULL) return GF_BAD_PARAM;
2016 :
2017 1 : e = gf_isom_box_write_header(s, bs);
2018 1 : if (e) return e;
2019 1 : gf_bs_write_u64(bs, ptr->nbBytes);
2020 1 : return GF_OK;
2021 : }
2022 1 : GF_Err trpy_box_size(GF_Box *s)
2023 : {
2024 1 : s->size += 8;
2025 1 : return GF_OK;
2026 : }
2027 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2028 :
2029 : /**********************************************************
2030 : TOTL GF_Box
2031 : **********************************************************/
2032 :
2033 3 : void totl_box_del(GF_Box *s)
2034 : {
2035 3 : gf_free((GF_TRPYBox *)s);
2036 3 : }
2037 1 : GF_Err totl_box_read(GF_Box *s, GF_BitStream *bs)
2038 : {
2039 : GF_TOTLBox *ptr = (GF_TOTLBox *)s;
2040 1 : ISOM_DECREASE_SIZE(ptr, 4);
2041 1 : ptr->nbBytes = gf_bs_read_u32(bs);
2042 1 : return GF_OK;
2043 : }
2044 3 : GF_Box *totl_box_new()
2045 : {
2046 6 : ISOM_DECL_BOX_ALLOC(GF_TOTLBox, GF_ISOM_BOX_TYPE_TOTL);
2047 3 : return (GF_Box *)tmp;
2048 : }
2049 :
2050 : #ifndef GPAC_DISABLE_ISOM_WRITE
2051 :
2052 1 : GF_Err totl_box_write(GF_Box *s, GF_BitStream *bs)
2053 : {
2054 : GF_Err e;
2055 : GF_TOTLBox *ptr = (GF_TOTLBox *)s;
2056 1 : if (ptr == NULL) return GF_BAD_PARAM;
2057 1 : e = gf_isom_box_write_header(s, bs);
2058 1 : if (e) return e;
2059 1 : gf_bs_write_u32(bs, ptr->nbBytes);
2060 1 : return GF_OK;
2061 : }
2062 1 : GF_Err totl_box_size(GF_Box *s)
2063 : {
2064 1 : s->size += 4;
2065 1 : return GF_OK;
2066 : }
2067 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2068 :
2069 :
2070 : /**********************************************************
2071 : NUMP GF_Box
2072 : **********************************************************/
2073 :
2074 3 : void nump_box_del(GF_Box *s)
2075 : {
2076 3 : gf_free((GF_NUMPBox *)s);
2077 3 : }
2078 1 : GF_Err nump_box_read(GF_Box *s, GF_BitStream *bs)
2079 : {
2080 : GF_NUMPBox *ptr = (GF_NUMPBox *)s;
2081 1 : ISOM_DECREASE_SIZE(ptr, 8);
2082 1 : ptr->nbPackets = gf_bs_read_u64(bs);
2083 1 : return GF_OK;
2084 : }
2085 3 : GF_Box *nump_box_new()
2086 : {
2087 6 : ISOM_DECL_BOX_ALLOC(GF_NUMPBox, GF_ISOM_BOX_TYPE_NUMP);
2088 3 : return (GF_Box *)tmp;
2089 : }
2090 :
2091 : #ifndef GPAC_DISABLE_ISOM_WRITE
2092 1 : GF_Err nump_box_write(GF_Box *s, GF_BitStream *bs)
2093 : {
2094 : GF_Err e;
2095 : GF_NUMPBox *ptr = (GF_NUMPBox *)s;
2096 1 : if (ptr == NULL) return GF_BAD_PARAM;
2097 1 : e = gf_isom_box_write_header(s, bs);
2098 1 : if (e) return e;
2099 1 : gf_bs_write_u64(bs, ptr->nbPackets);
2100 1 : return GF_OK;
2101 : }
2102 1 : GF_Err nump_box_size(GF_Box *s)
2103 : {
2104 1 : s->size += 8;
2105 1 : return GF_OK;
2106 : }
2107 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2108 :
2109 :
2110 : /**********************************************************
2111 : NPCK GF_Box
2112 : **********************************************************/
2113 :
2114 3 : void npck_box_del(GF_Box *s)
2115 : {
2116 3 : gf_free((GF_NPCKBox *)s);
2117 3 : }
2118 1 : GF_Err npck_box_read(GF_Box *s, GF_BitStream *bs)
2119 : {
2120 : GF_NPCKBox *ptr = (GF_NPCKBox *)s;
2121 1 : ISOM_DECREASE_SIZE(ptr, 4);
2122 1 : ptr->nbPackets = gf_bs_read_u32(bs);
2123 1 : return GF_OK;
2124 : }
2125 3 : GF_Box *npck_box_new()
2126 : {
2127 6 : ISOM_DECL_BOX_ALLOC(GF_NPCKBox, GF_ISOM_BOX_TYPE_NPCK);
2128 3 : return (GF_Box *)tmp;
2129 : }
2130 : #ifndef GPAC_DISABLE_ISOM_WRITE
2131 1 : GF_Err npck_box_write(GF_Box *s, GF_BitStream *bs)
2132 : {
2133 : GF_Err e;
2134 : GF_NPCKBox *ptr = (GF_NPCKBox *)s;
2135 1 : if (ptr == NULL) return GF_BAD_PARAM;
2136 1 : e = gf_isom_box_write_header(s, bs);
2137 1 : if (e) return e;
2138 1 : gf_bs_write_u32(bs, ptr->nbPackets);
2139 1 : return GF_OK;
2140 : }
2141 1 : GF_Err npck_box_size(GF_Box *s)
2142 : {
2143 1 : s->size += 4;
2144 1 : return GF_OK;
2145 : }
2146 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2147 :
2148 :
2149 : /**********************************************************
2150 : TPYL GF_Box
2151 : **********************************************************/
2152 :
2153 3 : void tpyl_box_del(GF_Box *s)
2154 : {
2155 3 : gf_free((GF_NTYLBox *)s);
2156 3 : }
2157 1 : GF_Err tpyl_box_read(GF_Box *s, GF_BitStream *bs)
2158 : {
2159 : GF_NTYLBox *ptr = (GF_NTYLBox *)s;
2160 1 : if (ptr == NULL) return GF_BAD_PARAM;
2161 1 : ISOM_DECREASE_SIZE(ptr, 8);
2162 1 : ptr->nbBytes = gf_bs_read_u64(bs);
2163 1 : return GF_OK;
2164 : }
2165 3 : GF_Box *tpyl_box_new()
2166 : {
2167 6 : ISOM_DECL_BOX_ALLOC(GF_NTYLBox, GF_ISOM_BOX_TYPE_TPYL);
2168 3 : return (GF_Box *)tmp;
2169 : }
2170 : #ifndef GPAC_DISABLE_ISOM_WRITE
2171 1 : GF_Err tpyl_box_write(GF_Box *s, GF_BitStream *bs)
2172 : {
2173 : GF_Err e;
2174 : GF_NTYLBox *ptr = (GF_NTYLBox *)s;
2175 1 : if (ptr == NULL) return GF_BAD_PARAM;
2176 1 : e = gf_isom_box_write_header(s, bs);
2177 1 : if (e) return e;
2178 1 : gf_bs_write_u64(bs, ptr->nbBytes);
2179 1 : return GF_OK;
2180 : }
2181 1 : GF_Err tpyl_box_size(GF_Box *s)
2182 : {
2183 1 : s->size += 8;
2184 1 : return GF_OK;
2185 : }
2186 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2187 :
2188 : /**********************************************************
2189 : TPAY GF_Box
2190 : **********************************************************/
2191 :
2192 3 : void tpay_box_del(GF_Box *s)
2193 : {
2194 3 : gf_free((GF_TPAYBox *)s);
2195 3 : }
2196 1 : GF_Err tpay_box_read(GF_Box *s, GF_BitStream *bs)
2197 : {
2198 : GF_TPAYBox *ptr = (GF_TPAYBox *)s;
2199 1 : ISOM_DECREASE_SIZE(ptr, 4);
2200 1 : ptr->nbBytes = gf_bs_read_u32(bs);
2201 1 : return GF_OK;
2202 : }
2203 3 : GF_Box *tpay_box_new()
2204 : {
2205 6 : ISOM_DECL_BOX_ALLOC(GF_TPAYBox, GF_ISOM_BOX_TYPE_TPAY);
2206 3 : return (GF_Box *)tmp;
2207 : }
2208 : #ifndef GPAC_DISABLE_ISOM_WRITE
2209 1 : GF_Err tpay_box_write(GF_Box *s, GF_BitStream *bs)
2210 : {
2211 : GF_Err e;
2212 : GF_TPAYBox *ptr = (GF_TPAYBox *)s;
2213 1 : if (ptr == NULL) return GF_BAD_PARAM;
2214 1 : e = gf_isom_box_write_header(s, bs);
2215 1 : if (e) return e;
2216 1 : gf_bs_write_u32(bs, ptr->nbBytes);
2217 1 : return GF_OK;
2218 : }
2219 1 : GF_Err tpay_box_size(GF_Box *s)
2220 : {
2221 1 : s->size += 4;
2222 1 : return GF_OK;
2223 : }
2224 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2225 :
2226 :
2227 : /**********************************************************
2228 : MAXR GF_Box
2229 : **********************************************************/
2230 :
2231 3 : void maxr_box_del(GF_Box *s)
2232 : {
2233 3 : gf_free((GF_MAXRBox *)s);
2234 3 : }
2235 1 : GF_Err maxr_box_read(GF_Box *s, GF_BitStream *bs)
2236 : {
2237 : GF_MAXRBox *ptr = (GF_MAXRBox *)s;
2238 1 : if (ptr == NULL) return GF_BAD_PARAM;
2239 1 : ISOM_DECREASE_SIZE(ptr, 8);
2240 1 : ptr->granularity = gf_bs_read_u32(bs);
2241 1 : ptr->maxDataRate = gf_bs_read_u32(bs);
2242 1 : return GF_OK;
2243 : }
2244 3 : GF_Box *maxr_box_new()
2245 : {
2246 6 : ISOM_DECL_BOX_ALLOC(GF_MAXRBox, GF_ISOM_BOX_TYPE_MAXR);
2247 3 : return (GF_Box *)tmp;
2248 : }
2249 : #ifndef GPAC_DISABLE_ISOM_WRITE
2250 1 : GF_Err maxr_box_write(GF_Box *s, GF_BitStream *bs)
2251 : {
2252 : GF_Err e;
2253 : GF_MAXRBox *ptr = (GF_MAXRBox *)s;
2254 1 : if (ptr == NULL) return GF_BAD_PARAM;
2255 1 : e = gf_isom_box_write_header(s, bs);
2256 1 : if (e) return e;
2257 1 : gf_bs_write_u32(bs, ptr->granularity);
2258 1 : gf_bs_write_u32(bs, ptr->maxDataRate);
2259 1 : return GF_OK;
2260 : }
2261 1 : GF_Err maxr_box_size(GF_Box *s)
2262 : {
2263 1 : s->size += 8;
2264 1 : return GF_OK;
2265 : }
2266 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2267 :
2268 :
2269 : /**********************************************************
2270 : DMED GF_Box
2271 : **********************************************************/
2272 :
2273 3 : void dmed_box_del(GF_Box *s)
2274 : {
2275 3 : gf_free((GF_DMEDBox *)s);
2276 3 : }
2277 1 : GF_Err dmed_box_read(GF_Box *s, GF_BitStream *bs)
2278 : {
2279 : GF_DMEDBox *ptr = (GF_DMEDBox *)s;
2280 1 : ISOM_DECREASE_SIZE(ptr, 8);
2281 1 : ptr->nbBytes = gf_bs_read_u64(bs);
2282 1 : return GF_OK;
2283 : }
2284 3 : GF_Box *dmed_box_new()
2285 : {
2286 6 : ISOM_DECL_BOX_ALLOC(GF_DMEDBox, GF_ISOM_BOX_TYPE_DMED);
2287 3 : return (GF_Box *)tmp;
2288 : }
2289 : #ifndef GPAC_DISABLE_ISOM_WRITE
2290 1 : GF_Err dmed_box_write(GF_Box *s, GF_BitStream *bs)
2291 : {
2292 : GF_Err e;
2293 : GF_DMEDBox *ptr = (GF_DMEDBox *)s;
2294 1 : if (ptr == NULL) return GF_BAD_PARAM;
2295 1 : e = gf_isom_box_write_header(s, bs);
2296 1 : if (e) return e;
2297 1 : gf_bs_write_u64(bs, ptr->nbBytes);
2298 1 : return GF_OK;
2299 : }
2300 1 : GF_Err dmed_box_size(GF_Box *s)
2301 : {
2302 1 : s->size += 8;
2303 1 : return GF_OK;
2304 : }
2305 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2306 :
2307 : /**********************************************************
2308 : DIMM GF_Box
2309 : **********************************************************/
2310 :
2311 3 : void dimm_box_del(GF_Box *s)
2312 : {
2313 3 : gf_free((GF_DIMMBox *)s);
2314 3 : }
2315 1 : GF_Err dimm_box_read(GF_Box *s, GF_BitStream *bs)
2316 : {
2317 : GF_DIMMBox *ptr = (GF_DIMMBox *)s;
2318 1 : ISOM_DECREASE_SIZE(ptr, 8)
2319 1 : ptr->nbBytes = gf_bs_read_u64(bs);
2320 1 : return GF_OK;
2321 : }
2322 3 : GF_Box *dimm_box_new()
2323 : {
2324 6 : ISOM_DECL_BOX_ALLOC(GF_DIMMBox, GF_ISOM_BOX_TYPE_DIMM);
2325 3 : return (GF_Box *)tmp;
2326 : }
2327 : #ifndef GPAC_DISABLE_ISOM_WRITE
2328 1 : GF_Err dimm_box_write(GF_Box *s, GF_BitStream *bs)
2329 : {
2330 : GF_Err e;
2331 : GF_DIMMBox *ptr = (GF_DIMMBox *)s;
2332 1 : if (ptr == NULL) return GF_BAD_PARAM;
2333 1 : e = gf_isom_box_write_header(s, bs);
2334 1 : if (e) return e;
2335 1 : gf_bs_write_u64(bs, ptr->nbBytes);
2336 1 : return GF_OK;
2337 : }
2338 1 : GF_Err dimm_box_size(GF_Box *s)
2339 : {
2340 1 : s->size += 8;
2341 1 : return GF_OK;
2342 : }
2343 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2344 :
2345 : /**********************************************************
2346 : DREP GF_Box
2347 : **********************************************************/
2348 :
2349 3 : void drep_box_del(GF_Box *s)
2350 : {
2351 3 : gf_free((GF_DREPBox *)s);
2352 3 : }
2353 1 : GF_Err drep_box_read(GF_Box *s, GF_BitStream *bs)
2354 : {
2355 : GF_DREPBox *ptr = (GF_DREPBox *)s;
2356 1 : ISOM_DECREASE_SIZE(ptr, 8)
2357 1 : ptr->nbBytes = gf_bs_read_u64(bs);
2358 1 : return GF_OK;
2359 : }
2360 3 : GF_Box *drep_box_new()
2361 : {
2362 6 : ISOM_DECL_BOX_ALLOC(GF_DREPBox, GF_ISOM_BOX_TYPE_DREP);
2363 3 : return (GF_Box *)tmp;
2364 : }
2365 : #ifndef GPAC_DISABLE_ISOM_WRITE
2366 1 : GF_Err drep_box_write(GF_Box *s, GF_BitStream *bs)
2367 : {
2368 : GF_Err e;
2369 : GF_DREPBox *ptr = (GF_DREPBox *)s;
2370 1 : if (ptr == NULL) return GF_BAD_PARAM;
2371 1 : e = gf_isom_box_write_header(s, bs);
2372 1 : if (e) return e;
2373 1 : gf_bs_write_u64(bs, ptr->nbBytes);
2374 1 : return GF_OK;
2375 : }
2376 1 : GF_Err drep_box_size(GF_Box *s)
2377 : {
2378 1 : s->size += 8;
2379 1 : return GF_OK;
2380 : }
2381 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2382 :
2383 :
2384 :
2385 : /**********************************************************
2386 : TMIN GF_Box
2387 : **********************************************************/
2388 :
2389 3 : void tmin_box_del(GF_Box *s)
2390 : {
2391 3 : gf_free((GF_TMINBox *)s);
2392 3 : }
2393 1 : GF_Err tmin_box_read(GF_Box *s, GF_BitStream *bs)
2394 : {
2395 : GF_TMINBox *ptr = (GF_TMINBox *)s;
2396 1 : ISOM_DECREASE_SIZE(ptr, 4)
2397 1 : ptr->minTime = gf_bs_read_u32(bs);
2398 1 : return GF_OK;
2399 : }
2400 3 : GF_Box *tmin_box_new()
2401 : {
2402 6 : ISOM_DECL_BOX_ALLOC(GF_TMINBox, GF_ISOM_BOX_TYPE_TMIN);
2403 3 : return (GF_Box *)tmp;
2404 : }
2405 : #ifndef GPAC_DISABLE_ISOM_WRITE
2406 1 : GF_Err tmin_box_write(GF_Box *s, GF_BitStream *bs)
2407 : {
2408 : GF_Err e;
2409 : GF_TMINBox *ptr = (GF_TMINBox *)s;
2410 1 : if (ptr == NULL) return GF_BAD_PARAM;
2411 1 : e = gf_isom_box_write_header(s, bs);
2412 1 : if (e) return e;
2413 1 : gf_bs_write_u32(bs, ptr->minTime);
2414 1 : return GF_OK;
2415 : }
2416 1 : GF_Err tmin_box_size(GF_Box *s)
2417 : {
2418 1 : s->size += 4;
2419 1 : return GF_OK;
2420 : }
2421 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2422 :
2423 :
2424 : /**********************************************************
2425 : TMAX GF_Box
2426 : **********************************************************/
2427 :
2428 3 : void tmax_box_del(GF_Box *s)
2429 : {
2430 3 : gf_free((GF_TMAXBox *)s);
2431 3 : }
2432 1 : GF_Err tmax_box_read(GF_Box *s, GF_BitStream *bs)
2433 : {
2434 : GF_TMAXBox *ptr = (GF_TMAXBox *)s;
2435 1 : ISOM_DECREASE_SIZE(ptr, 4)
2436 1 : ptr->maxTime = gf_bs_read_u32(bs);
2437 1 : return GF_OK;
2438 : }
2439 3 : GF_Box *tmax_box_new()
2440 : {
2441 6 : ISOM_DECL_BOX_ALLOC(GF_TMAXBox, GF_ISOM_BOX_TYPE_TMAX);
2442 3 : return (GF_Box *)tmp;
2443 : }
2444 : #ifndef GPAC_DISABLE_ISOM_WRITE
2445 1 : GF_Err tmax_box_write(GF_Box *s, GF_BitStream *bs)
2446 : {
2447 : GF_Err e;
2448 : GF_TMAXBox *ptr = (GF_TMAXBox *)s;
2449 1 : if (ptr == NULL) return GF_BAD_PARAM;
2450 1 : e = gf_isom_box_write_header(s, bs);
2451 1 : if (e) return e;
2452 1 : gf_bs_write_u32(bs, ptr->maxTime);
2453 1 : return GF_OK;
2454 : }
2455 1 : GF_Err tmax_box_size(GF_Box *s)
2456 : {
2457 1 : s->size += 4;
2458 1 : return GF_OK;
2459 : }
2460 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2461 :
2462 :
2463 : /**********************************************************
2464 : PMAX GF_Box
2465 : **********************************************************/
2466 :
2467 3 : void pmax_box_del(GF_Box *s)
2468 : {
2469 3 : gf_free((GF_PMAXBox *)s);
2470 3 : }
2471 1 : GF_Err pmax_box_read(GF_Box *s, GF_BitStream *bs)
2472 : {
2473 : GF_PMAXBox *ptr = (GF_PMAXBox *)s;
2474 1 : ISOM_DECREASE_SIZE(ptr, 4)
2475 1 : ptr->maxSize = gf_bs_read_u32(bs);
2476 1 : return GF_OK;
2477 : }
2478 3 : GF_Box *pmax_box_new()
2479 : {
2480 6 : ISOM_DECL_BOX_ALLOC(GF_PMAXBox, GF_ISOM_BOX_TYPE_PMAX);
2481 3 : return (GF_Box *)tmp;
2482 : }
2483 : #ifndef GPAC_DISABLE_ISOM_WRITE
2484 1 : GF_Err pmax_box_write(GF_Box *s, GF_BitStream *bs)
2485 : {
2486 : GF_Err e;
2487 : GF_PMAXBox *ptr = (GF_PMAXBox *)s;
2488 1 : if (ptr == NULL) return GF_BAD_PARAM;
2489 1 : e = gf_isom_box_write_header(s, bs);
2490 1 : if (e) return e;
2491 1 : gf_bs_write_u32(bs, ptr->maxSize);
2492 1 : return GF_OK;
2493 : }
2494 1 : GF_Err pmax_box_size(GF_Box *s)
2495 : {
2496 1 : s->size += 4;
2497 1 : return GF_OK;
2498 : }
2499 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2500 :
2501 :
2502 : /**********************************************************
2503 : DMAX GF_Box
2504 : **********************************************************/
2505 :
2506 3 : void dmax_box_del(GF_Box *s)
2507 : {
2508 3 : gf_free((GF_DMAXBox *)s);
2509 3 : }
2510 1 : GF_Err dmax_box_read(GF_Box *s, GF_BitStream *bs)
2511 : {
2512 : GF_DMAXBox *ptr = (GF_DMAXBox *)s;
2513 1 : ISOM_DECREASE_SIZE(ptr, 4)
2514 1 : ptr->maxDur = gf_bs_read_u32(bs);
2515 1 : return GF_OK;
2516 : }
2517 3 : GF_Box *dmax_box_new()
2518 : {
2519 6 : ISOM_DECL_BOX_ALLOC(GF_DMAXBox, GF_ISOM_BOX_TYPE_DMAX);
2520 3 : return (GF_Box *)tmp;
2521 : }
2522 : #ifndef GPAC_DISABLE_ISOM_WRITE
2523 1 : GF_Err dmax_box_write(GF_Box *s, GF_BitStream *bs)
2524 : {
2525 : GF_Err e;
2526 : GF_DMAXBox *ptr = (GF_DMAXBox *)s;
2527 1 : if (ptr == NULL) return GF_BAD_PARAM;
2528 1 : e = gf_isom_box_write_header(s, bs);
2529 1 : if (e) return e;
2530 1 : gf_bs_write_u32(bs, ptr->maxDur);
2531 1 : return GF_OK;
2532 : }
2533 1 : GF_Err dmax_box_size(GF_Box *s)
2534 : {
2535 1 : s->size += 4;
2536 1 : return GF_OK;
2537 : }
2538 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2539 :
2540 :
2541 : /**********************************************************
2542 : PAYT GF_Box
2543 : **********************************************************/
2544 :
2545 3 : void payt_box_del(GF_Box *s)
2546 : {
2547 : GF_PAYTBox *payt = (GF_PAYTBox *)s;
2548 3 : if (payt->payloadString) gf_free(payt->payloadString);
2549 3 : gf_free(payt);
2550 3 : }
2551 1 : GF_Err payt_box_read(GF_Box *s, GF_BitStream *bs)
2552 : {
2553 : u32 length;
2554 : GF_PAYTBox *ptr = (GF_PAYTBox *)s;
2555 :
2556 1 : ISOM_DECREASE_SIZE(ptr, 5 );
2557 1 : ptr->payloadCode = gf_bs_read_u32(bs);
2558 1 : length = gf_bs_read_u8(bs);
2559 1 : ISOM_DECREASE_SIZE(ptr, length);
2560 1 : ptr->payloadString = (char*)gf_malloc(sizeof(char) * (length+1) );
2561 1 : if (! ptr->payloadString) return GF_OUT_OF_MEM;
2562 1 : gf_bs_read_data(bs, ptr->payloadString, length);
2563 1 : ptr->payloadString[length] = 0;
2564 :
2565 1 : return GF_OK;
2566 : }
2567 3 : GF_Box *payt_box_new()
2568 : {
2569 6 : ISOM_DECL_BOX_ALLOC(GF_PAYTBox, GF_ISOM_BOX_TYPE_PAYT);
2570 3 : return (GF_Box *)tmp;
2571 : }
2572 : #ifndef GPAC_DISABLE_ISOM_WRITE
2573 1 : GF_Err payt_box_write(GF_Box *s, GF_BitStream *bs)
2574 : {
2575 : u32 len;
2576 : GF_Err e;
2577 : GF_PAYTBox *ptr = (GF_PAYTBox *)s;
2578 1 : if (ptr == NULL) return GF_BAD_PARAM;
2579 1 : e = gf_isom_box_write_header(s, bs);
2580 1 : if (e) return e;
2581 1 : gf_bs_write_u32(bs, ptr->payloadCode);
2582 1 : len = ptr->payloadString ? (u32) strlen(ptr->payloadString) : 0;
2583 1 : gf_bs_write_u8(bs, len);
2584 1 : if (len) gf_bs_write_data(bs, ptr->payloadString, len);
2585 : return GF_OK;
2586 : }
2587 1 : GF_Err payt_box_size(GF_Box *s)
2588 : {
2589 : GF_PAYTBox *ptr = (GF_PAYTBox *)s;
2590 1 : s->size += 4 + 1;
2591 1 : if (ptr->payloadString) ptr->size += strlen(ptr->payloadString);
2592 1 : return GF_OK;
2593 : }
2594 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2595 :
2596 :
2597 : /**********************************************************
2598 : PAYT GF_Box
2599 : **********************************************************/
2600 :
2601 5 : void name_box_del(GF_Box *s)
2602 : {
2603 : GF_NameBox *name = (GF_NameBox *)s;
2604 5 : if (name->string) gf_free(name->string);
2605 5 : gf_free(name);
2606 5 : }
2607 2 : GF_Err name_box_read(GF_Box *s, GF_BitStream *bs)
2608 : {
2609 : u32 length;
2610 : GF_NameBox *ptr = (GF_NameBox *)s;
2611 :
2612 2 : length = (u32) (ptr->size);
2613 2 : ptr->string = (char*)gf_malloc(sizeof(char) * (length+1));
2614 2 : if (! ptr->string) return GF_OUT_OF_MEM;
2615 :
2616 2 : gf_bs_read_data(bs, ptr->string, length);
2617 2 : ptr->string[length] = 0;
2618 2 : return GF_OK;
2619 : }
2620 5 : GF_Box *name_box_new()
2621 : {
2622 10 : ISOM_DECL_BOX_ALLOC(GF_NameBox, GF_ISOM_BOX_TYPE_NAME);
2623 5 : return (GF_Box *)tmp;
2624 : }
2625 : #ifndef GPAC_DISABLE_ISOM_WRITE
2626 2 : GF_Err name_box_write(GF_Box *s, GF_BitStream *bs)
2627 : {
2628 : GF_Err e;
2629 : GF_NameBox *ptr = (GF_NameBox *)s;
2630 2 : if (ptr == NULL) return GF_BAD_PARAM;
2631 2 : e = gf_isom_box_write_header(s, bs);
2632 2 : if (e) return e;
2633 2 : if (ptr->string) {
2634 0 : gf_bs_write_data(bs, ptr->string, (u32) strlen(ptr->string) + 1);
2635 : }
2636 : return GF_OK;
2637 : }
2638 2 : GF_Err name_box_size(GF_Box *s)
2639 : {
2640 : GF_NameBox *ptr = (GF_NameBox *)s;
2641 2 : if (ptr->string) ptr->size += strlen(ptr->string) + 1;
2642 2 : return GF_OK;
2643 : }
2644 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2645 :
2646 :
2647 3 : void tssy_box_del(GF_Box *s)
2648 : {
2649 3 : gf_free(s);
2650 3 : }
2651 1 : GF_Err tssy_box_read(GF_Box *s, GF_BitStream *bs)
2652 : {
2653 : GF_TimeStampSynchronyBox *ptr = (GF_TimeStampSynchronyBox *)s;
2654 1 : ISOM_DECREASE_SIZE(ptr, 1)
2655 1 : gf_bs_read_int(bs, 6);
2656 1 : ptr->timestamp_sync = gf_bs_read_int(bs, 2);
2657 1 : return GF_OK;
2658 : }
2659 3 : GF_Box *tssy_box_new()
2660 : {
2661 6 : ISOM_DECL_BOX_ALLOC(GF_TimeStampSynchronyBox, GF_ISOM_BOX_TYPE_TSSY);
2662 3 : return (GF_Box *)tmp;
2663 : }
2664 : #ifndef GPAC_DISABLE_ISOM_WRITE
2665 1 : GF_Err tssy_box_write(GF_Box *s, GF_BitStream *bs)
2666 : {
2667 : GF_Err e;
2668 : GF_TimeStampSynchronyBox *ptr = (GF_TimeStampSynchronyBox *)s;
2669 1 : if (ptr == NULL) return GF_BAD_PARAM;
2670 1 : e = gf_isom_box_write_header(s, bs);
2671 1 : if (e) return e;
2672 1 : gf_bs_write_int(bs, 0, 6);
2673 1 : gf_bs_write_int(bs, ptr->timestamp_sync, 2);
2674 1 : return GF_OK;
2675 : }
2676 1 : GF_Err tssy_box_size(GF_Box *s)
2677 : {
2678 1 : s->size += 1;
2679 1 : return GF_OK;
2680 : }
2681 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2682 :
2683 :
2684 3 : void srpp_box_del(GF_Box *s)
2685 : {
2686 3 : gf_free(s);
2687 3 : }
2688 :
2689 0 : GF_Err srpp_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
2690 : {
2691 : GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
2692 0 : switch(a->type) {
2693 0 : case GF_ISOM_BOX_TYPE_SCHI:
2694 0 : BOX_FIELD_ASSIGN(info, GF_SchemeInformationBox)
2695 0 : return GF_OK;
2696 0 : case GF_ISOM_BOX_TYPE_SCHM:
2697 0 : BOX_FIELD_ASSIGN(scheme_type, GF_SchemeTypeBox)
2698 0 : return GF_OK;
2699 : }
2700 : return GF_OK;
2701 : }
2702 :
2703 1 : GF_Err srpp_box_read(GF_Box *s, GF_BitStream *bs)
2704 : {
2705 : GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
2706 :
2707 1 : ISOM_DECREASE_SIZE(s, 16)
2708 1 : ptr->encryption_algorithm_rtp = gf_bs_read_u32(bs);
2709 1 : ptr->encryption_algorithm_rtcp = gf_bs_read_u32(bs);
2710 1 : ptr->integrity_algorithm_rtp = gf_bs_read_u32(bs);
2711 1 : ptr->integrity_algorithm_rtcp = gf_bs_read_u32(bs);
2712 1 : return gf_isom_box_array_read(s, bs);
2713 : }
2714 3 : GF_Box *srpp_box_new()
2715 : {
2716 6 : ISOM_DECL_BOX_ALLOC(GF_SRTPProcessBox, GF_ISOM_BOX_TYPE_SRPP);
2717 3 : return (GF_Box *)tmp;
2718 : }
2719 : #ifndef GPAC_DISABLE_ISOM_WRITE
2720 1 : GF_Err srpp_box_write(GF_Box *s, GF_BitStream *bs)
2721 : {
2722 : GF_Err e;
2723 : GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
2724 1 : if (ptr == NULL) return GF_BAD_PARAM;
2725 1 : e = gf_isom_full_box_write(s, bs);
2726 1 : if (e) return e;
2727 :
2728 1 : gf_bs_write_u32(bs, ptr->encryption_algorithm_rtp);
2729 1 : gf_bs_write_u32(bs, ptr->encryption_algorithm_rtcp);
2730 1 : gf_bs_write_u32(bs, ptr->integrity_algorithm_rtp);
2731 1 : gf_bs_write_u32(bs, ptr->integrity_algorithm_rtcp);
2732 :
2733 1 : return GF_OK;
2734 : }
2735 1 : GF_Err srpp_box_size(GF_Box *s)
2736 : {
2737 1 : u32 pos = 0;
2738 : GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
2739 1 : s->size += 16;
2740 1 : gf_isom_check_position(s, (GF_Box*)ptr->info, &pos);
2741 1 : gf_isom_check_position(s, (GF_Box*)ptr->scheme_type, &pos);
2742 1 : return GF_OK;
2743 : }
2744 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2745 :
2746 :
2747 :
2748 3 : void rssr_box_del(GF_Box *s)
2749 : {
2750 3 : gf_free(s);
2751 3 : }
2752 1 : GF_Err rssr_box_read(GF_Box *s, GF_BitStream *bs)
2753 : {
2754 : GF_ReceivedSsrcBox *ptr = (GF_ReceivedSsrcBox *)s;
2755 1 : ISOM_DECREASE_SIZE(ptr, 4)
2756 1 : ptr->ssrc = gf_bs_read_u32(bs);
2757 1 : return GF_OK;
2758 : }
2759 3 : GF_Box *rssr_box_new()
2760 : {
2761 6 : ISOM_DECL_BOX_ALLOC(GF_ReceivedSsrcBox, GF_ISOM_BOX_TYPE_RSSR);
2762 3 : return (GF_Box *)tmp;
2763 : }
2764 : #ifndef GPAC_DISABLE_ISOM_WRITE
2765 1 : GF_Err rssr_box_write(GF_Box *s, GF_BitStream *bs)
2766 : {
2767 : GF_Err e;
2768 : GF_ReceivedSsrcBox *ptr = (GF_ReceivedSsrcBox *)s;
2769 1 : e = gf_isom_box_write_header(s, bs);
2770 1 : if (e) return e;
2771 1 : gf_bs_write_u32(bs, ptr->ssrc);
2772 1 : return GF_OK;
2773 : }
2774 1 : GF_Err rssr_box_size(GF_Box *s)
2775 : {
2776 1 : s->size += 4;
2777 1 : return GF_OK;
2778 : }
2779 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2780 :
2781 :
2782 :
2783 :
2784 1316 : void iods_box_del(GF_Box *s)
2785 : {
2786 : GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
2787 1316 : if (ptr == NULL) return;
2788 1316 : if (ptr->descriptor) gf_odf_desc_del(ptr->descriptor);
2789 1316 : gf_free(ptr);
2790 : }
2791 :
2792 :
2793 804 : GF_Err iods_box_read(GF_Box *s, GF_BitStream *bs)
2794 : {
2795 : GF_Err e;
2796 : u32 descSize;
2797 : char *desc;
2798 : GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
2799 :
2800 : //use the OD codec...
2801 804 : descSize = (u32) (ptr->size);
2802 804 : desc = (char*)gf_malloc(sizeof(char) * descSize);
2803 804 : if (!desc) return GF_OUT_OF_MEM;
2804 :
2805 804 : gf_bs_read_data(bs, desc, descSize);
2806 804 : e = gf_odf_desc_read(desc, descSize, &ptr->descriptor);
2807 : //OK, free our desc
2808 804 : gf_free(desc);
2809 804 : return e;
2810 : }
2811 :
2812 1316 : GF_Box *iods_box_new()
2813 : {
2814 2632 : ISOM_DECL_BOX_ALLOC(GF_ObjectDescriptorBox, GF_ISOM_BOX_TYPE_IODS);
2815 1316 : return (GF_Box *)tmp;
2816 : }
2817 :
2818 :
2819 :
2820 : #ifndef GPAC_DISABLE_ISOM_WRITE
2821 :
2822 626 : GF_Err iods_box_write(GF_Box *s, GF_BitStream *bs)
2823 : {
2824 : GF_Err e;
2825 : u32 descSize;
2826 : u8 *desc;
2827 : GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
2828 626 : e = gf_isom_full_box_write(s, bs);
2829 626 : if (e) return e;
2830 : //call our OD codec
2831 626 : e = gf_odf_desc_write(ptr->descriptor, &desc, &descSize);
2832 626 : if (e) return e;
2833 625 : gf_bs_write_data(bs, desc, descSize);
2834 : //and free our stuff maybe!!
2835 625 : gf_free(desc);
2836 625 : return GF_OK;
2837 : }
2838 :
2839 1796 : GF_Err iods_box_size(GF_Box *s)
2840 : {
2841 : GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
2842 :
2843 1796 : ptr->size += gf_odf_desc_size(ptr->descriptor);
2844 1796 : return GF_OK;
2845 : }
2846 :
2847 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2848 :
2849 11322 : void mdat_box_del(GF_Box *s)
2850 : {
2851 : GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
2852 11322 : if (!s) return;
2853 :
2854 11322 : if (ptr->data) gf_free(ptr->data);
2855 11322 : gf_free(ptr);
2856 : }
2857 :
2858 :
2859 5405 : GF_Err mdat_box_read(GF_Box *s, GF_BitStream *bs)
2860 : {
2861 : GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
2862 5405 : if (ptr == NULL) return GF_BAD_PARAM;
2863 :
2864 5405 : ptr->dataSize = s->size;
2865 5405 : ptr->bsOffset = gf_bs_get_position(bs);
2866 :
2867 : //then skip these bytes
2868 5405 : gf_bs_skip_bytes(bs, ptr->dataSize);
2869 5405 : return GF_OK;
2870 : }
2871 :
2872 11322 : GF_Box *mdat_box_new()
2873 : {
2874 22644 : ISOM_DECL_BOX_ALLOC(GF_MediaDataBox, GF_ISOM_BOX_TYPE_MDAT);
2875 11322 : return (GF_Box *)tmp;
2876 : }
2877 :
2878 : #ifndef GPAC_DISABLE_ISOM_WRITE
2879 :
2880 1049 : GF_Err mdat_box_write(GF_Box *s, GF_BitStream *bs)
2881 : {
2882 : GF_Err e;
2883 : GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
2884 1049 : e = gf_isom_box_write_header(s, bs);
2885 1049 : if (e) return e;
2886 :
2887 : //make sure we have some data ...
2888 : //if not, we handle that independently (edit files)
2889 1049 : if (ptr->data) {
2890 0 : gf_bs_write_data(bs, ptr->data, (u32) ptr->dataSize);
2891 : }
2892 : return GF_OK;
2893 : }
2894 :
2895 1066 : GF_Err mdat_box_size(GF_Box *s)
2896 : {
2897 : GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
2898 1066 : ptr->size += ptr->dataSize;
2899 1066 : return GF_OK;
2900 : }
2901 :
2902 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
2903 :
2904 4126 : void mdhd_box_del(GF_Box *s)
2905 : {
2906 : GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
2907 4126 : if (ptr == NULL) return;
2908 4126 : gf_free(ptr);
2909 : }
2910 :
2911 3106 : GF_Err mdhd_box_read(GF_Box *s, GF_BitStream *bs)
2912 : {
2913 : GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
2914 :
2915 3106 : if (ptr->version == 1) {
2916 0 : ISOM_DECREASE_SIZE(ptr, 28)
2917 0 : ptr->creationTime = gf_bs_read_u64(bs);
2918 0 : ptr->modificationTime = gf_bs_read_u64(bs);
2919 0 : ptr->timeScale = gf_bs_read_u32(bs);
2920 0 : ptr->duration = gf_bs_read_u64(bs);
2921 : } else {
2922 3106 : ISOM_DECREASE_SIZE(ptr, 16)
2923 3106 : ptr->creationTime = gf_bs_read_u32(bs);
2924 3106 : ptr->modificationTime = gf_bs_read_u32(bs);
2925 3106 : ptr->timeScale = gf_bs_read_u32(bs);
2926 3106 : ptr->duration = gf_bs_read_u32(bs);
2927 : }
2928 3106 : if (!ptr->timeScale) {
2929 1 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Media header timescale is 0 - defaulting to 90000\n" ));
2930 1 : ptr->timeScale = 90000;
2931 : }
2932 :
2933 3106 : ptr->original_duration = ptr->duration;
2934 :
2935 3106 : ISOM_DECREASE_SIZE(ptr, 4)
2936 : //our padding bit
2937 3106 : gf_bs_read_int(bs, 1);
2938 : //the spec is unclear here, just says "the value 0 is interpreted as undetermined"
2939 3106 : ptr->packedLanguage[0] = gf_bs_read_int(bs, 5);
2940 3106 : ptr->packedLanguage[1] = gf_bs_read_int(bs, 5);
2941 3106 : ptr->packedLanguage[2] = gf_bs_read_int(bs, 5);
2942 : //but before or after compaction ?? We assume before
2943 3106 : if (ptr->packedLanguage[0] || ptr->packedLanguage[1] || ptr->packedLanguage[2]) {
2944 3094 : ptr->packedLanguage[0] += 0x60;
2945 3094 : ptr->packedLanguage[1] += 0x60;
2946 3094 : ptr->packedLanguage[2] += 0x60;
2947 : } else {
2948 12 : ptr->packedLanguage[0] = 'u';
2949 12 : ptr->packedLanguage[1] = 'n';
2950 12 : ptr->packedLanguage[2] = 'd';
2951 : }
2952 3106 : ptr->reserved = gf_bs_read_u16(bs);
2953 3106 : return GF_OK;
2954 : }
2955 :
2956 4126 : GF_Box *mdhd_box_new()
2957 : {
2958 8252 : ISOM_DECL_BOX_ALLOC(GF_MediaHeaderBox, GF_ISOM_BOX_TYPE_MDHD);
2959 :
2960 4126 : tmp->packedLanguage[0] = 'u';
2961 4126 : tmp->packedLanguage[1] = 'n';
2962 4126 : tmp->packedLanguage[2] = 'd';
2963 4126 : return (GF_Box *)tmp;
2964 : }
2965 :
2966 :
2967 : #ifndef GPAC_DISABLE_ISOM_WRITE
2968 :
2969 3176 : GF_Err mdhd_box_write(GF_Box *s, GF_BitStream *bs)
2970 : {
2971 : GF_Err e;
2972 : GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
2973 3176 : e = gf_isom_full_box_write(s, bs);
2974 3176 : if (e) return e;
2975 3176 : if (ptr->version == 1) {
2976 0 : gf_bs_write_u64(bs, ptr->creationTime);
2977 0 : gf_bs_write_u64(bs, ptr->modificationTime);
2978 0 : gf_bs_write_u32(bs, ptr->timeScale);
2979 0 : gf_bs_write_u64(bs, ptr->duration);
2980 : } else {
2981 3176 : gf_bs_write_u32(bs, (u32) ptr->creationTime);
2982 3176 : gf_bs_write_u32(bs, (u32) ptr->modificationTime);
2983 3176 : gf_bs_write_u32(bs, ptr->timeScale);
2984 3176 : gf_bs_write_u32(bs, (u32) ptr->duration);
2985 : }
2986 : //SPECS: BIT(1) of padding
2987 3176 : gf_bs_write_int(bs, 0, 1);
2988 3176 : gf_bs_write_int(bs, ptr->packedLanguage[0] - 0x60, 5);
2989 3176 : gf_bs_write_int(bs, ptr->packedLanguage[1] - 0x60, 5);
2990 3176 : gf_bs_write_int(bs, ptr->packedLanguage[2] - 0x60, 5);
2991 3176 : gf_bs_write_u16(bs, ptr->reserved);
2992 3176 : return GF_OK;
2993 : }
2994 :
2995 6125 : GF_Err mdhd_box_size(GF_Box *s)
2996 : {
2997 : GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
2998 6125 : ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
2999 :
3000 6125 : ptr->size += 4;
3001 6125 : ptr->size += (ptr->version == 1) ? 28 : 16;
3002 6125 : return GF_OK;
3003 : }
3004 :
3005 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
3006 :
3007 :
3008 4125 : void mdia_box_del(GF_Box *s)
3009 : {
3010 : GF_MediaBox *ptr = (GF_MediaBox *)s;
3011 4125 : if (ptr == NULL) return;
3012 4125 : if (ptr->nalu_parser) gf_bs_del(ptr->nalu_parser);
3013 4125 : if (ptr->nalu_out_bs) gf_bs_del(ptr->nalu_out_bs);
3014 4125 : if (ptr->nalu_ps_bs) gf_bs_del(ptr->nalu_ps_bs);
3015 4125 : if (ptr->extracted_bs) gf_bs_del(ptr->extracted_bs);
3016 4125 : if (ptr->extracted_samp) gf_isom_sample_del(&ptr->extracted_samp);
3017 4125 : if (ptr->in_sample_buffer) gf_free(ptr->in_sample_buffer);
3018 4125 : if (ptr->tmp_nal_copy_buffer) gf_free(ptr->tmp_nal_copy_buffer);
3019 4125 : gf_free(ptr);
3020 : }
3021 :
3022 :
3023 12379 : GF_Err mdia_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
3024 : {
3025 : GF_MediaBox *ptr = (GF_MediaBox *)s;
3026 12379 : switch(a->type) {
3027 4116 : case GF_ISOM_BOX_TYPE_MDHD:
3028 4116 : BOX_FIELD_ASSIGN(mediaHeader, GF_MediaHeaderBox)
3029 4116 : return GF_OK;
3030 :
3031 4116 : case GF_ISOM_BOX_TYPE_HDLR:
3032 4116 : BOX_FIELD_ASSIGN(handler, GF_HandlerBox)
3033 4116 : return GF_OK;
3034 :
3035 4116 : case GF_ISOM_BOX_TYPE_MINF:
3036 4116 : BOX_FIELD_ASSIGN(information, GF_MediaInformationBox)
3037 4116 : return GF_OK;
3038 : }
3039 : return GF_OK;
3040 : }
3041 :
3042 :
3043 3106 : GF_Err mdia_box_read(GF_Box *s, GF_BitStream *bs)
3044 : {
3045 : GF_Err e;
3046 3106 : u64 cookie = gf_bs_get_cookie(bs);
3047 3106 : cookie &= ~GF_ISOM_BS_COOKIE_VISUAL_TRACK;
3048 3106 : gf_bs_set_cookie(bs, cookie);
3049 3106 : e = gf_isom_box_array_read(s, bs);
3050 3106 : gf_bs_set_cookie(bs, cookie);
3051 :
3052 3106 : if (e) return e;
3053 3106 : if (!((GF_MediaBox *)s)->information) {
3054 1 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaInformationBox\n"));
3055 : return GF_ISOM_INVALID_FILE;
3056 : }
3057 3105 : if (!((GF_MediaBox *)s)->handler) {
3058 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing HandlerBox\n"));
3059 : return GF_ISOM_INVALID_FILE;
3060 : }
3061 3105 : if (!((GF_MediaBox *)s)->mediaHeader) {
3062 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaHeaderBox\n"));
3063 : return GF_ISOM_INVALID_FILE;
3064 : }
3065 : return GF_OK;
3066 : }
3067 :
3068 4125 : GF_Box *mdia_box_new()
3069 : {
3070 8250 : ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_MDIA);
3071 4125 : return (GF_Box *)tmp;
3072 : }
3073 :
3074 : #ifndef GPAC_DISABLE_ISOM_WRITE
3075 :
3076 3176 : GF_Err mdia_box_write(GF_Box *s, GF_BitStream *bs)
3077 : {
3078 3176 : return gf_isom_box_write_header(s, bs);
3079 : }
3080 :
3081 6125 : GF_Err mdia_box_size(GF_Box *s)
3082 : {
3083 6125 : u32 pos = 0;
3084 : GF_MediaBox *ptr = (GF_MediaBox *)s;
3085 : //Header first
3086 6125 : gf_isom_check_position(s, (GF_Box*)ptr->mediaHeader, &pos);
3087 : //then handler
3088 6125 : gf_isom_check_position(s, (GF_Box*)ptr->handler, &pos);
3089 :
3090 : #if 0
3091 : //elng before info for CMAF info - we deactiveate for now, no specific errors raised and CMAF should not impose any order
3092 : GF_Box *elng = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_ELNG);
3093 : if (elng)
3094 : gf_isom_check_position(s, elng, &pos);
3095 : #endif
3096 :
3097 : //then info
3098 6125 : gf_isom_check_position(s, (GF_Box*)ptr->information, &pos);
3099 6125 : return GF_OK;
3100 : }
3101 :
3102 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
3103 :
3104 7 : void mfra_box_del(GF_Box *s)
3105 : {
3106 : GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
3107 7 : if (ptr == NULL) return;
3108 7 : gf_list_del(ptr->tfra_list);
3109 7 : gf_free(ptr);
3110 : }
3111 :
3112 7 : GF_Box *mfra_box_new()
3113 : {
3114 14 : ISOM_DECL_BOX_ALLOC(GF_MovieFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_MFRA);
3115 7 : tmp->tfra_list = gf_list_new();
3116 7 : return (GF_Box *)tmp;
3117 : }
3118 :
3119 12 : GF_Err mfra_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
3120 : {
3121 : GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
3122 12 : switch(a->type) {
3123 9 : case GF_ISOM_BOX_TYPE_TFRA:
3124 9 : BOX_FIELD_LIST_ASSIGN(tfra_list);
3125 : return GF_OK;
3126 3 : case GF_ISOM_BOX_TYPE_MFRO:
3127 3 : BOX_FIELD_ASSIGN(mfro, GF_MovieFragmentRandomAccessOffsetBox)
3128 3 : return GF_OK;
3129 : }
3130 : return GF_OK;
3131 : }
3132 :
3133 4 : GF_Err mfra_box_read(GF_Box *s, GF_BitStream *bs)
3134 : {
3135 4 : return gf_isom_box_array_read(s, bs);
3136 : }
3137 :
3138 : #ifndef GPAC_DISABLE_ISOM_WRITE
3139 :
3140 2 : GF_Err mfra_box_write(GF_Box *s, GF_BitStream *bs)
3141 : {
3142 2 : return gf_isom_box_write_header(s, bs);
3143 : }
3144 :
3145 2 : GF_Err mfra_box_size(GF_Box *s)
3146 : {
3147 2 : u32 pos=0;
3148 : GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
3149 2 : gf_isom_check_position_list(s, ptr->tfra_list, &pos);
3150 2 : gf_isom_check_position(s, (GF_Box *)ptr->mfro, &pos);
3151 2 : return GF_OK;
3152 : }
3153 :
3154 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
3155 :
3156 :
3157 16 : void tfra_box_del(GF_Box *s)
3158 : {
3159 : GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
3160 16 : if (ptr == NULL) return;
3161 16 : if (ptr->entries) gf_free(ptr->entries);
3162 16 : gf_free(ptr);
3163 : }
3164 :
3165 16 : GF_Box *tfra_box_new()
3166 : {
3167 32 : ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_TFRA);
3168 16 : return (GF_Box *)tmp;
3169 : }
3170 :
3171 10 : GF_Err tfra_box_read(GF_Box *s, GF_BitStream *bs)
3172 : {
3173 : u32 i;
3174 : GF_RandomAccessEntry *p = 0;
3175 : GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
3176 :
3177 10 : ISOM_DECREASE_SIZE(ptr, 12);
3178 :
3179 10 : ptr->track_id = gf_bs_read_u32(bs);
3180 10 : if (gf_bs_read_int(bs, 26) != 0)
3181 : return GF_ISOM_INVALID_FILE;
3182 :
3183 10 : ptr->traf_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
3184 10 : ptr->trun_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
3185 10 : ptr->sample_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
3186 :
3187 10 : ptr->nb_entries = gf_bs_read_u32(bs);
3188 :
3189 10 : if (ptr->version == 1) {
3190 0 : if (ptr->nb_entries > ptr->size / (16+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) {
3191 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries));
3192 : return GF_ISOM_INVALID_FILE;
3193 : }
3194 : } else {
3195 10 : if (ptr->nb_entries > ptr->size / (8+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) {
3196 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries));
3197 : return GF_ISOM_INVALID_FILE;
3198 : }
3199 : }
3200 :
3201 10 : if (ptr->nb_entries) {
3202 9 : p = (GF_RandomAccessEntry *) gf_malloc(sizeof(GF_RandomAccessEntry) * ptr->nb_entries);
3203 9 : if (!p) return GF_OUT_OF_MEM;
3204 : }
3205 :
3206 10 : ptr->entries = p;
3207 :
3208 19 : for (i=0; i<ptr->nb_entries; i++) {
3209 : memset(p, 0, sizeof(GF_RandomAccessEntry));
3210 :
3211 9 : if (ptr->version == 1) {
3212 0 : p->time = gf_bs_read_u64(bs);
3213 0 : p->moof_offset = gf_bs_read_u64(bs);
3214 : } else {
3215 9 : p->time = gf_bs_read_u32(bs);
3216 9 : p->moof_offset = gf_bs_read_u32(bs);
3217 : }
3218 9 : p->traf_number = gf_bs_read_int(bs, ptr->traf_bits);
3219 9 : p->trun_number = gf_bs_read_int(bs, ptr->trun_bits);
3220 9 : p->sample_number = gf_bs_read_int(bs, ptr->sample_bits);
3221 :
3222 9 : ++p;
3223 : }
3224 :
3225 : return GF_OK;
3226 : }
3227 :
3228 :
3229 : #ifndef GPAC_DISABLE_ISOM_WRITE
3230 :
3231 4 : GF_Err tfra_box_write(GF_Box *s, GF_BitStream *bs)
3232 : {
3233 : GF_Err e;
3234 : u32 i, sap_nb_entries;
3235 : GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
3236 :
3237 4 : e = gf_isom_full_box_write(s, bs);
3238 4 : if (e) return e;
3239 :
3240 4 : gf_bs_write_u32(bs, ptr->track_id);
3241 4 : gf_bs_write_int(bs, 0, 26);
3242 :
3243 4 : gf_bs_write_int(bs, ptr->traf_bits/8 - 1, 2);
3244 4 : gf_bs_write_int(bs, ptr->trun_bits/8 - 1, 2);
3245 4 : gf_bs_write_int(bs, ptr->sample_bits/8 - 1, 2);
3246 :
3247 : sap_nb_entries = 0;
3248 28 : for (i=0; i<ptr->nb_entries; i++) {
3249 24 : GF_RandomAccessEntry *p = &ptr->entries[i];
3250 : //no sap found, do not store
3251 24 : if (p->trun_number) sap_nb_entries++;
3252 : }
3253 :
3254 4 : gf_bs_write_u32(bs, sap_nb_entries);
3255 :
3256 28 : for (i=0; i<ptr->nb_entries; i++) {
3257 24 : GF_RandomAccessEntry *p = &ptr->entries[i];
3258 : //no sap found, do not store
3259 24 : if (!p->trun_number) continue;
3260 18 : if (ptr->version==1) {
3261 0 : gf_bs_write_u64(bs, p->time);
3262 0 : gf_bs_write_u64(bs, p->moof_offset);
3263 : } else {
3264 18 : gf_bs_write_u32(bs, (u32) p->time);
3265 18 : gf_bs_write_u32(bs, (u32) p->moof_offset);
3266 : }
3267 18 : gf_bs_write_int(bs, p->traf_number, ptr->traf_bits);
3268 18 : gf_bs_write_int(bs, p->trun_number, ptr->trun_bits);
3269 18 : gf_bs_write_int(bs, p->sample_number, ptr->sample_bits);
3270 : }
3271 : return GF_OK;
3272 : }
3273 :
3274 4 : GF_Err tfra_box_size(GF_Box *s)
3275 : {
3276 : u32 i;
3277 : GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
3278 4 : ptr->size += 12;
3279 :
3280 28 : for (i=0; i<ptr->nb_entries; i++) {
3281 24 : GF_RandomAccessEntry *p = &ptr->entries[i];
3282 : //no sap found, do not store
3283 24 : if (!p->trun_number) continue;
3284 18 : ptr->size += ((ptr->version==1) ? 16 : 8 ) + ptr->traf_bits/8 + ptr->trun_bits/8 + ptr->sample_bits/8;
3285 : }
3286 4 : return GF_OK;
3287 : }
3288 :
3289 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
3290 :
3291 :
3292 :
3293 7 : void mfro_box_del(GF_Box *s)
3294 : {
3295 : GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;
3296 7 : if (ptr == NULL) return;
3297 7 : gf_free(ptr);
3298 : }
3299 :
3300 7 : GF_Box *mfro_box_new()
3301 : {
3302 14 : ISOM_DECL_BOX_ALLOC(GF_MovieFragmentRandomAccessOffsetBox, GF_ISOM_BOX_TYPE_MFRO);
3303 7 : return (GF_Box *)tmp;
3304 : }
3305 :
3306 4 : GF_Err mfro_box_read(GF_Box *s, GF_BitStream *bs)
3307 : {
3308 : GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;
3309 :
3310 4 : ISOM_DECREASE_SIZE(ptr, 4);
3311 4 : ptr->container_size = gf_bs_read_u32(bs);
3312 4 : return GF_OK;
3313 : }
3314 :
3315 :
3316 : #ifndef GPAC_DISABLE_ISOM_WRITE
3317 :
3318 2 : GF_Err mfro_box_write(GF_Box *s, GF_BitStream *bs)
3319 : {
3320 : GF_Err e;
3321 : GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;
3322 :
3323 2 : e = gf_isom_full_box_write(s, bs);
3324 2 : if (e) return e;
3325 :
3326 2 : gf_bs_write_u32(bs, ptr->container_size);
3327 2 : return GF_OK;
3328 : }
3329 :
3330 2 : GF_Err mfro_box_size(GF_Box *s)
3331 : {
3332 2 : s->size += 4;
3333 2 : return GF_OK;
3334 : }
3335 :
3336 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
3337 :
3338 :
3339 44 : void elng_box_del(GF_Box *s)
3340 : {
3341 : GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
3342 44 : if (ptr == NULL) return;
3343 44 : if (ptr->extended_language) gf_free(ptr->extended_language);
3344 44 : gf_free(ptr);
3345 : }
3346 :
3347 32 : GF_Err elng_box_read(GF_Box *s, GF_BitStream *bs)
3348 : {
3349 : GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
3350 :
3351 32 : if (ptr->size) {
3352 31 : ptr->extended_language = (char*)gf_malloc((u32) ptr->size);
3353 31 : if (ptr->extended_language == NULL) return GF_OUT_OF_MEM;
3354 31 : gf_bs_read_data(bs, ptr->extended_language, (u32) ptr->size);
3355 : /*safety check in case the string is not null-terminated*/
3356 31 : if (ptr->extended_language[ptr->size-1]) {
3357 0 : char *str = (char*)gf_malloc((u32) ptr->size + 1);
3358 0 : if (!str) return GF_OUT_OF_MEM;
3359 0 : memcpy(str, ptr->extended_language, (u32) ptr->size);
3360 0 : str[ptr->size] = 0;
3361 0 : gf_free(ptr->extended_language);
3362 0 : ptr->extended_language = str;
3363 : }
3364 : }
3365 : return GF_OK;
3366 : }
3367 :
3368 44 : GF_Box *elng_box_new()
3369 : {
3370 88 : ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_ELNG);
3371 44 : return (GF_Box *)tmp;
3372 : }
3373 :
3374 : #ifndef GPAC_DISABLE_ISOM_WRITE
3375 :
3376 16 : GF_Err elng_box_write(GF_Box *s, GF_BitStream *bs)
3377 : {
3378 : GF_Err e;
3379 : GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
3380 16 : e = gf_isom_full_box_write(s, bs);
3381 16 : if (e) return e;
3382 16 : if (ptr->extended_language) {
3383 15 : gf_bs_write_data(bs, ptr->extended_language, (u32)(strlen(ptr->extended_language)+1));
3384 : }
3385 : return GF_OK;
3386 : }
3387 :
3388 42 : GF_Err elng_box_size(GF_Box *s)
3389 : {
3390 : GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
3391 :
3392 42 : if (ptr->extended_language) {
3393 41 : ptr->size += strlen(ptr->extended_language)+1;
3394 : }
3395 42 : return GF_OK;
3396 : }
3397 :
3398 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
3399 :
3400 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
3401 :
3402 7675 : void mfhd_box_del(GF_Box *s)
3403 : {
3404 : GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
3405 7675 : if (ptr == NULL) return;
3406 7675 : gf_free(ptr);
3407 : }
3408 :
3409 4102 : GF_Err mfhd_box_read(GF_Box *s, GF_BitStream *bs)
3410 : {
3411 : GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
3412 4102 : ISOM_DECREASE_SIZE(ptr, 4);
3413 4102 : ptr->sequence_number = gf_bs_read_u32(bs);
3414 4102 : return GF_OK;
3415 : }
3416 :
3417 7675 : GF_Box *mfhd_box_new()
3418 : {
3419 15350 : ISOM_DECL_BOX_ALLOC(GF_MovieFragmentHeaderBox, GF_ISOM_BOX_TYPE_MFHD);
3420 7675 : return (GF_Box *)tmp;
3421 : }
3422 :
3423 :
3424 : #ifndef GPAC_DISABLE_ISOM_WRITE
3425 :
3426 :
3427 3746 : GF_Err mfhd_box_write(GF_Box *s, GF_BitStream *bs)
3428 : {
3429 : GF_Err e;
3430 : GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *) s;
3431 3746 : if (!s) return GF_BAD_PARAM;
3432 :
3433 3746 : e = gf_isom_full_box_write(s, bs);
3434 3746 : if (e) return e;
3435 3746 : gf_bs_write_u32(bs, ptr->sequence_number);
3436 3746 : return GF_OK;
3437 : }
3438 :
3439 10776 : GF_Err mfhd_box_size(GF_Box *s)
3440 : {
3441 10776 : s->size += 4;
3442 10776 : return GF_OK;
3443 : }
3444 :
3445 :
3446 :
3447 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
3448 :
3449 : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
3450 :
3451 :
3452 4125 : void minf_box_del(GF_Box *s)
3453 : {
3454 : GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
3455 4125 : if (ptr == NULL) return;
3456 :
3457 : //if we have a Handler not self-contained, delete it (the self-contained belongs to the movie)
3458 4125 : if (ptr->dataHandler) {
3459 2668 : gf_isom_datamap_close(ptr);
3460 : }
3461 4125 : gf_free(ptr);
3462 : }
3463 :
3464 12469 : GF_Err minf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
3465 : {
3466 : GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
3467 12469 : switch (a->type) {
3468 4110 : case GF_ISOM_BOX_TYPE_NMHD:
3469 : case GF_ISOM_BOX_TYPE_STHD:
3470 : case GF_ISOM_BOX_TYPE_VMHD:
3471 : case GF_ISOM_BOX_TYPE_SMHD:
3472 : case GF_ISOM_BOX_TYPE_HMHD:
3473 : case GF_ISOM_BOX_TYPE_GMHD:
3474 4110 : BOX_FIELD_ASSIGN(InfoHeader, GF_Box)
3475 4110 : return GF_OK;
3476 :
3477 4110 : case GF_ISOM_BOX_TYPE_DINF:
3478 4110 : BOX_FIELD_ASSIGN(dataInformation, GF_DataInformationBox)
3479 4110 : return GF_OK;
3480 :
3481 4116 : case GF_ISOM_BOX_TYPE_STBL:
3482 4116 : BOX_FIELD_ASSIGN(sampleTable, GF_SampleTableBox)
3483 4116 : return GF_OK;
3484 : }
3485 : return GF_OK;
3486 : }
3487 :
3488 :
3489 3106 : GF_Err minf_box_read(GF_Box *s, GF_BitStream *bs)
3490 : {
3491 : GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
3492 : GF_Err e;
3493 :
3494 3106 : e = gf_isom_box_array_read(s, bs);
3495 :
3496 3106 : if (!e && ! ptr->dataInformation) {
3497 : GF_Box *url;
3498 7 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing DataInformationBox\n"));
3499 : //commented on purpose, we are still able to handle the file, we only throw an error but keep processing
3500 : // e = GF_ISOM_INVALID_FILE;
3501 :
3502 : //add a dinf box to avoid any access to a null dinf
3503 7 : ptr->dataInformation = (GF_DataInformationBox *) gf_isom_box_new_parent(&ptr->child_boxes, GF_ISOM_BOX_TYPE_DINF);
3504 7 : if (!ptr->dataInformation) return GF_OUT_OF_MEM;
3505 :
3506 7 : ptr->dataInformation->dref = (GF_DataReferenceBox *) gf_isom_box_new_parent(&ptr->dataInformation->child_boxes, GF_ISOM_BOX_TYPE_DREF);
3507 7 : if (!ptr->dataInformation->dref) return GF_OUT_OF_MEM;
3508 :
3509 7 : url = gf_isom_box_new_parent(&ptr->dataInformation->dref->child_boxes, GF_ISOM_BOX_TYPE_URL);
3510 7 : if (!url) return GF_OUT_OF_MEM;
3511 7 : ((GF_FullBox*)url)->flags = 1;
3512 : }
3513 : return e;
3514 : }
3515 :
3516 4125 : GF_Box *minf_box_new()
3517 : {
3518 8250 : ISOM_DECL_BOX_ALLOC(GF_MediaInformationBox, GF_ISOM_BOX_TYPE_MINF);
3519 4125 : return (GF_Box *)tmp;
3520 : }
3521 :
3522 :
3523 : #ifndef GPAC_DISABLE_ISOM_WRITE
3524 :
3525 3176 : GF_Err minf_box_write(GF_Box *s, GF_BitStream *bs)
3526 : {
3527 3176 : return gf_isom_box_write_header(s, bs);
3528 : }
3529 :
3530 6125 : GF_Err minf_box_size(GF_Box *s)
3531 : {
3532 6125 : u32 pos=0;
3533 : GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
3534 : //Header first
3535 6125 : gf_isom_check_position(s, (GF_Box *)ptr->InfoHeader, &pos);
3536 : //then dataInfo
3537 6125 : gf_isom_check_position(s, (GF_Box *)ptr->dataInformation, &pos);
3538 6125 : gf_isom_check_position(s, gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_MVCI), &pos);
3539 : //then sampleTable
3540 6125 : gf_isom_check_position(s, (GF_Box *)ptr->sampleTable, &pos);
3541 6125 : return GF_OK;
3542 : }
3543 :
3544 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
3545 :
3546 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
3547 :
3548 7736 : void moof_box_del(GF_Box *s)
3549 : {
3550 : GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
3551 7736 : if (ptr == NULL) return;
3552 :
3553 7736 : gf_list_del(ptr->TrackList);
3554 7736 : if (ptr->PSSHs) gf_list_del(ptr->PSSHs);
3555 7736 : if (ptr->mdat) gf_free(ptr->mdat);
3556 7736 : gf_free(ptr);
3557 : }
3558 :
3559 8343 : GF_Err moof_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
3560 : {
3561 : GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
3562 8343 : switch (a->type) {
3563 4101 : case GF_ISOM_BOX_TYPE_MFHD:
3564 4101 : BOX_FIELD_ASSIGN(mfhd, GF_MovieFragmentHeaderBox)
3565 4101 : return GF_OK;
3566 4242 : case GF_ISOM_BOX_TYPE_TRAF:
3567 4242 : BOX_FIELD_LIST_ASSIGN(TrackList)
3568 : return GF_OK;
3569 0 : case GF_ISOM_BOX_TYPE_PSSH:
3570 0 : BOX_FIELD_LIST_ASSIGN(PSSHs)
3571 : return GF_OK;
3572 : }
3573 : return GF_OK;
3574 : }
3575 :
3576 4102 : GF_Err moof_box_read(GF_Box *s, GF_BitStream *bs)
3577 : {
3578 4102 : return gf_isom_box_array_read(s, bs);
3579 : }
3580 :
3581 7736 : GF_Box *moof_box_new()
3582 : {
3583 15472 : ISOM_DECL_BOX_ALLOC(GF_MovieFragmentBox, GF_ISOM_BOX_TYPE_MOOF);
3584 7736 : tmp->TrackList = gf_list_new();
3585 7736 : return (GF_Box *)tmp;
3586 : }
3587 :
3588 :
3589 : #ifndef GPAC_DISABLE_ISOM_WRITE
3590 :
3591 3746 : GF_Err moof_box_write(GF_Box *s, GF_BitStream *bs)
3592 : {
3593 3746 : return gf_isom_box_write_header(s, bs);
3594 : }
3595 :
3596 10774 : GF_Err moof_box_size(GF_Box *s)
3597 : {
3598 10774 : u32 pos=0;
3599 : GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *) s;
3600 10774 : if (!s) return GF_BAD_PARAM;
3601 : //Header First
3602 10774 : gf_isom_check_position(s, (GF_Box *)ptr->mfhd, &pos);
3603 : //then PSSH
3604 10774 : gf_isom_check_position_list(s, ptr->PSSHs, &pos);
3605 : //then the track list
3606 10774 : gf_isom_check_position_list(s, ptr->TrackList, &pos);
3607 10774 : return GF_OK;
3608 : }
3609 :
3610 :
3611 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
3612 :
3613 : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
3614 :
3615 2989 : void moov_box_del(GF_Box *s)
3616 : {
3617 : GF_MovieBox *ptr = (GF_MovieBox *)s;
3618 2989 : if (ptr == NULL) return;
3619 2989 : gf_list_del(ptr->trackList);
3620 2989 : gf_free(ptr);
3621 : }
3622 :
3623 9509 : GF_Err moov_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
3624 : {
3625 : GF_MovieBox *ptr = (GF_MovieBox *)s;
3626 9509 : switch (a->type) {
3627 1314 : case GF_ISOM_BOX_TYPE_IODS:
3628 1314 : BOX_FIELD_ASSIGN(iods, GF_ObjectDescriptorBox)
3629 : //if no IOD, delete the box
3630 1314 : if (ptr->iods && !ptr->iods->descriptor) {
3631 0 : ptr->iods = NULL;
3632 0 : gf_isom_box_del_parent(&s->child_boxes, a);
3633 : }
3634 : return GF_OK;
3635 :
3636 2951 : case GF_ISOM_BOX_TYPE_MVHD:
3637 2951 : BOX_FIELD_ASSIGN(mvhd, GF_MovieHeaderBox)
3638 2951 : return GF_OK;
3639 :
3640 142 : case GF_ISOM_BOX_TYPE_UDTA:
3641 142 : BOX_FIELD_ASSIGN(udta, GF_UserDataBox)
3642 142 : return GF_OK;
3643 :
3644 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
3645 593 : case GF_ISOM_BOX_TYPE_MVEX:
3646 593 : BOX_FIELD_ASSIGN(mvex, GF_MovieExtendsBox)
3647 : if (ptr->mvex)
3648 593 : ptr->mvex->mov = ptr->mov;
3649 593 : return GF_OK;
3650 : #endif
3651 :
3652 0 : case GF_ISOM_BOX_TYPE_META:
3653 0 : BOX_FIELD_ASSIGN(meta, GF_MetaBox)
3654 0 : return GF_OK;
3655 :
3656 4116 : case GF_ISOM_BOX_TYPE_TRAK:
3657 4116 : if (is_rem) {
3658 0 : gf_list_del_item(ptr->trackList, a);
3659 0 : return GF_OK;
3660 : }
3661 : //set our pointer to this obj
3662 4116 : ((GF_TrackBox *)a)->moov = ptr;
3663 4116 : ((GF_TrackBox *)a)->index = gf_list_count(ptr->trackList);
3664 4116 : return gf_list_add(ptr->trackList, a);
3665 : }
3666 : return GF_OK;
3667 : }
3668 :
3669 :
3670 1666 : GF_Err moov_box_read(GF_Box *s, GF_BitStream *bs)
3671 : {
3672 1666 : return gf_isom_box_array_read(s, bs);
3673 : }
3674 :
3675 2989 : GF_Box *moov_box_new()
3676 : {
3677 5978 : ISOM_DECL_BOX_ALLOC(GF_MovieBox, GF_ISOM_BOX_TYPE_MOOV);
3678 2989 : tmp->trackList = gf_list_new();
3679 2989 : if (!tmp->trackList) {
3680 0 : gf_free(tmp);
3681 0 : return NULL;
3682 : }
3683 : return (GF_Box *)tmp;
3684 : }
3685 :
3686 :
3687 :
3688 : #ifndef GPAC_DISABLE_ISOM_WRITE
3689 :
3690 :
3691 1373 : GF_Err moov_box_write(GF_Box *s, GF_BitStream *bs)
3692 : {
3693 1373 : return gf_isom_box_write_header(s, bs);
3694 : }
3695 :
3696 3377 : GF_Err moov_box_size(GF_Box *s)
3697 : {
3698 3377 : u32 pos=0;
3699 : GF_MovieBox *ptr = (GF_MovieBox *)s;
3700 :
3701 3377 : gf_isom_check_position(s, (GF_Box *) ptr->mvhd, &pos);
3702 3377 : gf_isom_check_position(s, (GF_Box *) ptr->iods, &pos);
3703 3377 : gf_isom_check_position(s, (GF_Box *) ptr->meta, &pos);
3704 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
3705 3377 : if (ptr->mvex && !ptr->mvex_after_traks) {
3706 346 : gf_isom_check_position(s, (GF_Box *) ptr->mvex, &pos);
3707 : }
3708 : #endif
3709 3377 : gf_isom_check_position_list(s, ptr->trackList, &pos);
3710 :
3711 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
3712 3377 : if (ptr->mvex && ptr->mvex_after_traks) {
3713 0 : gf_isom_check_position(s, (GF_Box *) ptr->mvex, &pos);
3714 : }
3715 : #endif
3716 3377 : return GF_OK;
3717 : }
3718 :
3719 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
3720 :
3721 1298 : void audio_sample_entry_box_del(GF_Box *s)
3722 : {
3723 : GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
3724 1298 : if (ptr == NULL) return;
3725 1298 : gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
3726 1298 : if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
3727 1298 : gf_free(ptr);
3728 : }
3729 :
3730 1336 : GF_Err audio_sample_entry_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
3731 : {
3732 : GF_UnknownBox *wave = NULL;
3733 : Bool drop_wave=GF_FALSE;
3734 : GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
3735 :
3736 1336 : switch (a->type) {
3737 679 : case GF_ISOM_BOX_TYPE_ESDS:
3738 679 : BOX_FIELD_ASSIGN(esd, GF_ESDBox)
3739 679 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
3740 679 : break;
3741 :
3742 31 : case GF_ISOM_BOX_TYPE_DAMR:
3743 : case GF_ISOM_BOX_TYPE_DEVC:
3744 : case GF_ISOM_BOX_TYPE_DQCP:
3745 : case GF_ISOM_BOX_TYPE_DSMV:
3746 31 : BOX_FIELD_ASSIGN(cfg_3gpp, GF_3GPPConfigBox)
3747 : /*for 3GP config, remember sample entry type in config*/
3748 31 : ptr->cfg_3gpp->cfg.type = ptr->type;
3749 31 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
3750 31 : break;
3751 :
3752 5 : case GF_ISOM_BOX_TYPE_DOPS:
3753 5 : BOX_FIELD_ASSIGN(cfg_opus, GF_OpusSpecificBox)
3754 5 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
3755 5 : break;
3756 15 : case GF_ISOM_BOX_TYPE_DAC3:
3757 15 : BOX_FIELD_ASSIGN(cfg_ac3, GF_AC3ConfigBox)
3758 15 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
3759 15 : break;
3760 5 : case GF_ISOM_BOX_TYPE_DEC3:
3761 5 : BOX_FIELD_ASSIGN(cfg_ac3, GF_AC3ConfigBox)
3762 5 : break;
3763 5 : case GF_ISOM_BOX_TYPE_DMLP:
3764 5 : BOX_FIELD_ASSIGN(cfg_mlp, GF_TrueHDConfigBox)
3765 5 : break;
3766 0 : case GF_ISOM_BOX_TYPE_MHAC:
3767 0 : BOX_FIELD_ASSIGN(cfg_mha, GF_MHAConfigBox)
3768 0 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
3769 0 : break;
3770 5 : case GF_ISOM_BOX_TYPE_DFLA:
3771 5 : BOX_FIELD_ASSIGN(cfg_flac, GF_FLACConfigBox)
3772 5 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
3773 5 : break;
3774 :
3775 0 : case GF_ISOM_BOX_TYPE_UNKNOWN:
3776 : wave = (GF_UnknownBox *)a;
3777 : /*HACK for QT files: get the esds box from the track*/
3778 0 : if (s->type == GF_ISOM_BOX_TYPE_MP4A) {
3779 0 : if (is_rem) {
3780 : return GF_OK;
3781 : }
3782 0 : if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
3783 : //wave subboxes may have been properly parsed
3784 0 : if ((wave->original_4cc == GF_QT_BOX_TYPE_WAVE) && gf_list_count(wave->child_boxes)) {
3785 : u32 i;
3786 0 : for (i =0; i<gf_list_count(wave->child_boxes); i++) {
3787 0 : GF_Box *inner_box = (GF_Box *)gf_list_get(wave->child_boxes, i);
3788 0 : if (inner_box->type == GF_ISOM_BOX_TYPE_ESDS) {
3789 0 : ptr->esd = (GF_ESDBox *)inner_box;
3790 0 : if (ptr->qtff_mode & GF_ISOM_AUDIO_QTFF_CONVERT_FLAG) {
3791 0 : gf_list_rem(a->child_boxes, i);
3792 : drop_wave=GF_TRUE;
3793 0 : ptr->compression_id = 0;
3794 0 : gf_list_add(ptr->child_boxes, inner_box);
3795 : }
3796 : }
3797 : }
3798 0 : if (drop_wave) {
3799 0 : gf_isom_box_del_parent(&ptr->child_boxes, a);
3800 0 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
3801 0 : ptr->version = 0;
3802 0 : return GF_OK;
3803 : }
3804 0 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID;
3805 0 : return GF_OK;
3806 : }
3807 0 : gf_isom_box_del_parent(&ptr->child_boxes, a);
3808 0 : return GF_ISOM_INVALID_MEDIA;
3809 :
3810 : }
3811 0 : ptr->qtff_mode &= ~GF_ISOM_AUDIO_QTFF_CONVERT_FLAG;
3812 :
3813 0 : if ((wave->original_4cc == GF_QT_BOX_TYPE_WAVE) && gf_list_count(wave->child_boxes)) {
3814 0 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_NOEXT;
3815 : }
3816 : return GF_OK;
3817 89 : case GF_QT_BOX_TYPE_WAVE:
3818 : {
3819 : u32 subtype = 0;
3820 : GF_Box **cfg_ptr = NULL;
3821 89 : if (s->type == GF_ISOM_BOX_TYPE_MP4A) {
3822 1 : cfg_ptr = (GF_Box **) &ptr->esd;
3823 : subtype = GF_ISOM_BOX_TYPE_ESDS;
3824 : }
3825 88 : else if (s->type == GF_ISOM_BOX_TYPE_AC3) {
3826 0 : cfg_ptr = (GF_Box **) &ptr->cfg_ac3;
3827 : subtype = GF_ISOM_BOX_TYPE_DAC3;
3828 : }
3829 88 : else if (s->type == GF_ISOM_BOX_TYPE_EC3) {
3830 0 : cfg_ptr = (GF_Box **) &ptr->cfg_ac3;
3831 : subtype = GF_ISOM_BOX_TYPE_DEC3;
3832 : }
3833 88 : else if (s->type == GF_ISOM_BOX_TYPE_OPUS) {
3834 0 : cfg_ptr = (GF_Box **) &ptr->cfg_opus;
3835 : subtype = GF_ISOM_BOX_TYPE_DOPS;
3836 : }
3837 88 : else if ((s->type == GF_ISOM_BOX_TYPE_MHA1)
3838 : || (s->type == GF_ISOM_BOX_TYPE_MHA2)
3839 88 : || (s->type == GF_ISOM_BOX_TYPE_MHM1)
3840 88 : || (s->type == GF_ISOM_BOX_TYPE_MHM2)
3841 : ) {
3842 0 : cfg_ptr = (GF_Box **) &ptr->cfg_mha;
3843 0 : subtype = GF_ISOM_BOX_TYPE_MHAC;
3844 : }
3845 88 : else if (s->type == GF_ISOM_BOX_TYPE_MLPA) {
3846 0 : cfg_ptr = (GF_Box **) &ptr->cfg_mlp;
3847 : subtype = GF_ISOM_BOX_TYPE_DMLP;
3848 : }
3849 :
3850 : if (cfg_ptr) {
3851 1 : if (is_rem) {
3852 0 : *cfg_ptr = NULL;
3853 0 : return GF_OK;
3854 : }
3855 1 : if (*cfg_ptr) ERROR_ON_DUPLICATED_BOX(a, ptr)
3856 :
3857 : //wave subboxes may have been properly parsed
3858 1 : if (gf_list_count(a->child_boxes)) {
3859 : u32 i;
3860 1 : for (i =0; i<gf_list_count(a->child_boxes); i++) {
3861 2 : GF_Box *inner_box = (GF_Box *)gf_list_get(a->child_boxes, i);
3862 2 : if (inner_box->type == subtype) {
3863 1 : *cfg_ptr = inner_box;
3864 1 : if (ptr->qtff_mode & GF_ISOM_AUDIO_QTFF_CONVERT_FLAG) {
3865 0 : gf_list_rem(a->child_boxes, i);
3866 : drop_wave=GF_TRUE;
3867 0 : gf_list_add(ptr->child_boxes, inner_box);
3868 : }
3869 : break;
3870 : }
3871 : }
3872 : if (drop_wave) {
3873 0 : gf_isom_box_del_parent(&ptr->child_boxes, a);
3874 0 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
3875 0 : ptr->compression_id = 0;
3876 0 : ptr->version = 0;
3877 0 : return GF_OK;
3878 : }
3879 1 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID;
3880 1 : return GF_OK;
3881 : }
3882 : }
3883 : }
3884 88 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID;
3885 88 : return GF_OK;
3886 : }
3887 : return GF_OK;
3888 : }
3889 974 : GF_Err audio_sample_entry_box_read(GF_Box *s, GF_BitStream *bs)
3890 : {
3891 : GF_MPEGAudioSampleEntryBox *ptr;
3892 : char *data;
3893 : u8 a, b, c, d;
3894 : u32 i, size, v, nb_alnum;
3895 : GF_Err e;
3896 : u64 pos, start;
3897 :
3898 : ptr = (GF_MPEGAudioSampleEntryBox *)s;
3899 :
3900 974 : start = gf_bs_get_position(bs);
3901 974 : gf_bs_seek(bs, start + 8);
3902 974 : v = gf_bs_read_u16(bs);
3903 974 : if (v)
3904 95 : ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_NOEXT;
3905 :
3906 : //try to disambiguate QTFF v1 and MP4 v1 audio sample entries ...
3907 974 : if (v==1) {
3908 : //go to end of ISOM audio sample entry, skip 4 byte (box size field), read 4 bytes (box type) and check if this looks like a box
3909 95 : gf_bs_seek(bs, start + 8 + 20 + 4);
3910 95 : a = gf_bs_read_u8(bs);
3911 95 : b = gf_bs_read_u8(bs);
3912 95 : c = gf_bs_read_u8(bs);
3913 95 : d = gf_bs_read_u8(bs);
3914 : nb_alnum = 0;
3915 95 : if (isalnum(a)) nb_alnum++;
3916 95 : if (isalnum(b)) nb_alnum++;
3917 95 : if (isalnum(c)) nb_alnum++;
3918 95 : if (isalnum(d)) nb_alnum++;
3919 95 : if (nb_alnum>2) ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
3920 : }
3921 :
3922 974 : gf_bs_seek(bs, start);
3923 974 : e = gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox*)s, bs);
3924 974 : if (e) return e;
3925 974 : pos = gf_bs_get_position(bs);
3926 974 : size = (u32) s->size;
3927 :
3928 : //when cookie is set on bs, always convert qtff-style mp4a to isobmff-style
3929 : //since the conversion is done in addBox and we don't have the bitstream there (arg...), flag the box
3930 974 : if (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_QT_CONV) {
3931 5 : ptr->qtff_mode |= GF_ISOM_AUDIO_QTFF_CONVERT_FLAG;
3932 : }
3933 :
3934 974 : e = gf_isom_box_array_read(s, bs);
3935 974 : if (!e) {
3936 974 : if (s->type==GF_ISOM_BOX_TYPE_ENCA) {
3937 184 : GF_ProtectionSchemeInfoBox *sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_SINF);
3938 :
3939 184 : if (sinf && sinf->original_format) {
3940 183 : u32 type = sinf->original_format->data_format;
3941 183 : switch (type) {
3942 0 : case GF_ISOM_SUBTYPE_3GP_AMR:
3943 : case GF_ISOM_SUBTYPE_3GP_AMR_WB:
3944 : case GF_ISOM_SUBTYPE_3GP_EVRC:
3945 : case GF_ISOM_SUBTYPE_3GP_QCELP:
3946 : case GF_ISOM_SUBTYPE_3GP_SMV:
3947 0 : if (ptr->cfg_3gpp) ptr->cfg_3gpp->cfg.type = type;
3948 : break;
3949 : }
3950 : }
3951 : }
3952 : return GF_OK;
3953 : }
3954 0 : if (size<8) return GF_ISOM_INVALID_FILE;
3955 :
3956 :
3957 : /*hack for some weird files (possibly recorded with live.com tools, needs further investigations)*/
3958 0 : gf_bs_seek(bs, pos);
3959 0 : data = (char*)gf_malloc(sizeof(char) * size);
3960 0 : if (!data) return GF_OUT_OF_MEM;
3961 :
3962 0 : gf_bs_read_data(bs, data, size);
3963 0 : for (i=0; i<size-8; i++) {
3964 0 : if (GF_4CC((u32)data[i+4], (u8)data[i+5], (u8)data[i+6], (u8)data[i+7]) == GF_ISOM_BOX_TYPE_ESDS) {
3965 0 : GF_BitStream *mybs = gf_bs_new(data + i, size - i, GF_BITSTREAM_READ);
3966 0 : if (ptr->esd) gf_isom_box_del_parent(&ptr->child_boxes, (GF_Box *)ptr->esd);
3967 0 : ptr->esd = NULL;
3968 0 : e = gf_isom_box_parse((GF_Box **)&ptr->esd, mybs);
3969 0 : gf_bs_del(mybs);
3970 0 : if (e==GF_OK) {
3971 0 : if (!ptr->child_boxes) ptr->child_boxes = gf_list_new();
3972 0 : gf_list_add(ptr->child_boxes, ptr->esd);
3973 0 : } else if (ptr->esd) {
3974 0 : gf_isom_box_del((GF_Box *)ptr->esd);
3975 0 : ptr->esd = NULL;
3976 : }
3977 : break;
3978 : }
3979 : }
3980 0 : gf_free(data);
3981 0 : return e;
3982 : }
3983 :
3984 1298 : GF_Box *audio_sample_entry_box_new()
3985 : {
3986 2596 : ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_MP4A);
3987 1298 : gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
3988 1298 : return (GF_Box *)tmp;
3989 : }
3990 :
3991 0 : GF_Box *enca_box_new()
3992 : {
3993 0 : ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_ENCA);
3994 0 : gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
3995 0 : return (GF_Box *)tmp;
3996 : }
3997 :
3998 :
3999 : #ifndef GPAC_DISABLE_ISOM_WRITE
4000 :
4001 741 : GF_Err audio_sample_entry_box_write(GF_Box *s, GF_BitStream *bs)
4002 : {
4003 : GF_Err e;
4004 741 : e = gf_isom_box_write_header(s, bs);
4005 741 : if (e) return e;
4006 741 : gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs);
4007 741 : return GF_OK;
4008 : }
4009 :
4010 1327 : GF_Err audio_sample_entry_box_size(GF_Box *s)
4011 : {
4012 1327 : u32 pos=0;
4013 : GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
4014 1327 : gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox*)s);
4015 1327 : if (ptr->qtff_mode)
4016 : return GF_OK;
4017 :
4018 1212 : gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos);
4019 1212 : gf_isom_check_position(s, (GF_Box *)ptr->cfg_3gpp, &pos);
4020 1212 : gf_isom_check_position(s, (GF_Box *)ptr->cfg_opus, &pos);
4021 1212 : gf_isom_check_position(s, (GF_Box *)ptr->cfg_ac3, &pos);
4022 1212 : gf_isom_check_position(s, (GF_Box *)ptr->cfg_flac, &pos);
4023 1212 : gf_isom_check_position(s, (GF_Box *)ptr->cfg_mlp, &pos);
4024 1212 : return GF_OK;
4025 : }
4026 :
4027 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4028 :
4029 :
4030 14 : void gen_sample_entry_box_del(GF_Box *s)
4031 : {
4032 : GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
4033 14 : if (ptr == NULL) return;
4034 14 : gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
4035 14 : gf_free(ptr);
4036 : }
4037 :
4038 :
4039 12 : GF_Err gen_sample_entry_box_read(GF_Box *s, GF_BitStream *bs)
4040 : {
4041 12 : GF_Err e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)s, bs);
4042 12 : if (e) return e;
4043 12 : ISOM_DECREASE_SIZE(s, 8);
4044 12 : return gf_isom_box_array_read(s, bs);
4045 : }
4046 :
4047 14 : GF_Box *gen_sample_entry_box_new()
4048 : {
4049 28 : ISOM_DECL_BOX_ALLOC(GF_SampleEntryBox, GF_QT_SUBTYPE_C608);//type will be overriten
4050 14 : gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
4051 14 : return (GF_Box *)tmp;
4052 : }
4053 :
4054 :
4055 : #ifndef GPAC_DISABLE_ISOM_WRITE
4056 :
4057 9 : GF_Err gen_sample_entry_box_write(GF_Box *s, GF_BitStream *bs)
4058 : {
4059 : GF_Err e;
4060 : GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
4061 9 : e = gf_isom_box_write_header(s, bs);
4062 9 : if (e) return e;
4063 :
4064 9 : gf_bs_write_data(bs, ptr->reserved, 6);
4065 9 : gf_bs_write_u16(bs, ptr->dataReferenceIndex);
4066 9 : return GF_OK;
4067 : }
4068 :
4069 15 : GF_Err gen_sample_entry_box_size(GF_Box *s)
4070 : {
4071 : GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
4072 15 : ptr->size += 8;
4073 15 : return GF_OK;
4074 : }
4075 :
4076 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4077 :
4078 313 : void mp4s_box_del(GF_Box *s)
4079 : {
4080 : GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
4081 313 : if (ptr == NULL) return;
4082 313 : gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
4083 313 : if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
4084 313 : gf_free(ptr);
4085 : }
4086 :
4087 178 : GF_Err mp4s_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
4088 : {
4089 : GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
4090 178 : switch (a->type) {
4091 178 : case GF_ISOM_BOX_TYPE_ESDS:
4092 178 : BOX_FIELD_ASSIGN(esd, GF_ESDBox)
4093 178 : break;
4094 : }
4095 : return GF_OK;
4096 : }
4097 :
4098 183 : GF_Err mp4s_box_read(GF_Box *s, GF_BitStream *bs)
4099 : {
4100 : GF_Err e;
4101 : GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
4102 :
4103 183 : e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
4104 183 : if (e) return e;
4105 :
4106 183 : ISOM_DECREASE_SIZE(ptr, 8);
4107 183 : return gf_isom_box_array_read(s, bs);
4108 : }
4109 :
4110 313 : GF_Box *mp4s_box_new()
4111 : {
4112 626 : ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_MP4S);
4113 313 : gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
4114 313 : return (GF_Box *)tmp;
4115 : }
4116 :
4117 0 : GF_Box *encs_box_new()
4118 : {
4119 0 : ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_ENCS);
4120 0 : gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
4121 0 : return (GF_Box *)tmp;
4122 : }
4123 :
4124 :
4125 : #ifndef GPAC_DISABLE_ISOM_WRITE
4126 :
4127 169 : GF_Err mp4s_box_write(GF_Box *s, GF_BitStream *bs)
4128 : {
4129 : GF_Err e;
4130 : GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
4131 :
4132 169 : e = gf_isom_box_write_header(s, bs);
4133 169 : if (e) return e;
4134 169 : gf_bs_write_data(bs, ptr->reserved, 6);
4135 169 : gf_bs_write_u16(bs, ptr->dataReferenceIndex);
4136 169 : return GF_OK;
4137 : }
4138 :
4139 431 : GF_Err mp4s_box_size(GF_Box *s)
4140 : {
4141 431 : u32 pos=0;
4142 : GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
4143 431 : s->size += 8;
4144 431 : gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos);
4145 431 : return GF_OK;
4146 : }
4147 :
4148 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4149 :
4150 3304 : void video_sample_entry_box_del(GF_Box *s)
4151 : {
4152 : GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
4153 3304 : if (ptr == NULL) return;
4154 3304 : gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
4155 :
4156 3304 : if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
4157 : /*for publishing*/
4158 3304 : if (ptr->emul_esd) gf_odf_desc_del((GF_Descriptor *)ptr->emul_esd);
4159 3304 : gf_free(ptr);
4160 : }
4161 :
4162 5020 : GF_Err video_sample_entry_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
4163 : {
4164 : GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
4165 5020 : switch (a->type) {
4166 191 : case GF_ISOM_BOX_TYPE_ESDS:
4167 191 : BOX_FIELD_ASSIGN(esd, GF_ESDBox)
4168 191 : break;
4169 0 : case GF_ISOM_BOX_TYPE_RINF:
4170 0 : BOX_FIELD_ASSIGN(rinf, GF_RestrictedSchemeInfoBox)
4171 0 : break;
4172 922 : case GF_ISOM_BOX_TYPE_AVCC:
4173 922 : BOX_FIELD_ASSIGN(avc_config, GF_AVCConfigurationBox)
4174 922 : break;
4175 332 : case GF_ISOM_BOX_TYPE_HVCC:
4176 332 : BOX_FIELD_ASSIGN(hevc_config, GF_HEVCConfigurationBox)
4177 332 : break;
4178 0 : case GF_ISOM_BOX_TYPE_VVCC:
4179 0 : BOX_FIELD_ASSIGN(vvc_config, GF_VVCConfigurationBox)
4180 0 : break;
4181 21 : case GF_ISOM_BOX_TYPE_SVCC:
4182 21 : BOX_FIELD_ASSIGN(svc_config, GF_AVCConfigurationBox)
4183 21 : break;
4184 0 : case GF_ISOM_BOX_TYPE_MVCC:
4185 0 : BOX_FIELD_ASSIGN(mvc_config, GF_AVCConfigurationBox)
4186 0 : break;
4187 11 : case GF_ISOM_BOX_TYPE_LHVC:
4188 11 : BOX_FIELD_ASSIGN(lhvc_config, GF_HEVCConfigurationBox)
4189 11 : break;
4190 329 : case GF_ISOM_BOX_TYPE_AV1C:
4191 329 : BOX_FIELD_ASSIGN(av1_config, GF_AV1ConfigurationBox)
4192 329 : break;
4193 176 : case GF_ISOM_BOX_TYPE_VPCC:
4194 176 : BOX_FIELD_ASSIGN(vp_config, GF_VPConfigurationBox)
4195 176 : break;
4196 3 : case GF_ISOM_BOX_TYPE_DVCC:
4197 3 : BOX_FIELD_ASSIGN(dovi_config, GF_DOVIConfigurationBox)
4198 3 : break;
4199 4 : case GF_ISOM_BOX_TYPE_UUID:
4200 4 : if (! memcmp(((GF_UnknownUUIDBox*)a)->uuid, GF_ISOM_IPOD_EXT, 16)) {
4201 1 : BOX_FIELD_ASSIGN(ipod_ext, GF_UnknownUUIDBox)
4202 : } else {
4203 : return GF_OK;
4204 : }
4205 1 : break;
4206 9 : case GF_ISOM_BOX_TYPE_D263:
4207 9 : BOX_FIELD_ASSIGN(cfg_3gpp, GF_3GPPConfigBox)
4208 : /*for 3GP config, remember sample entry type in config*/
4209 : if (ptr->cfg_3gpp)
4210 9 : ptr->cfg_3gpp->cfg.type = ptr->type;
4211 : break;
4212 :
4213 19 : case GF_ISOM_BOX_TYPE_JP2H:
4214 19 : BOX_FIELD_ASSIGN(jp2h, GF_J2KHeaderBox)
4215 19 : return GF_OK;
4216 :
4217 416 : case GF_ISOM_BOX_TYPE_PASP:
4218 : case GF_ISOM_BOX_TYPE_CLAP:
4219 : case GF_ISOM_BOX_TYPE_COLR:
4220 : case GF_ISOM_BOX_TYPE_MDCV:
4221 : case GF_ISOM_BOX_TYPE_CLLI:
4222 : case GF_ISOM_BOX_TYPE_CCST:
4223 : case GF_ISOM_BOX_TYPE_AUXI:
4224 : case GF_ISOM_BOX_TYPE_RVCC:
4225 : case GF_ISOM_BOX_TYPE_M4DS:
4226 416 : if (!is_rem && !gf_isom_box_check_unique(s->child_boxes, a)) {
4227 0 : ERROR_ON_DUPLICATED_BOX(a, ptr)
4228 : }
4229 : return GF_OK;
4230 : }
4231 : return GF_OK;
4232 : }
4233 :
4234 2233 : GF_Err video_sample_entry_box_read(GF_Box *s, GF_BitStream *bs)
4235 : {
4236 : GF_MPEGVisualSampleEntryBox *mp4v = (GF_MPEGVisualSampleEntryBox*)s;
4237 : GF_Err e;
4238 2233 : e = gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *)s, bs);
4239 2233 : if (e) return e;
4240 2233 : e = gf_isom_box_array_read(s, bs);
4241 2233 : if (e) return e;
4242 : /*this is an AVC sample desc*/
4243 2233 : if (mp4v->avc_config || mp4v->svc_config || mp4v->mvc_config)
4244 936 : AVC_RewriteESDescriptor(mp4v);
4245 : /*this is an HEVC sample desc*/
4246 2233 : if (mp4v->hevc_config || mp4v->lhvc_config || (mp4v->type==GF_ISOM_BOX_TYPE_HVT1))
4247 483 : HEVC_RewriteESDescriptor(mp4v);
4248 : /*this is an AV1 sample desc*/
4249 2233 : if (mp4v->av1_config)
4250 329 : AV1_RewriteESDescriptor(mp4v);
4251 : /*this is a VP8-9 sample desc*/
4252 2233 : if (mp4v->vp_config)
4253 176 : VP9_RewriteESDescriptor(mp4v);
4254 :
4255 2233 : if (s->type==GF_ISOM_BOX_TYPE_ENCV) {
4256 671 : GF_ProtectionSchemeInfoBox *sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_SINF);
4257 :
4258 671 : if (sinf && sinf->original_format) {
4259 670 : u32 type = sinf->original_format->data_format;
4260 670 : switch (type) {
4261 0 : case GF_ISOM_SUBTYPE_3GP_H263:
4262 0 : if (mp4v->cfg_3gpp) mp4v->cfg_3gpp->cfg.type = type;
4263 : break;
4264 : }
4265 : }
4266 : }
4267 : return GF_OK;
4268 : }
4269 :
4270 3304 : GF_Box *video_sample_entry_box_new()
4271 : {
4272 : GF_MPEGVisualSampleEntryBox *tmp;
4273 3304 : GF_SAFEALLOC(tmp, GF_MPEGVisualSampleEntryBox);
4274 3304 : if (tmp == NULL) return NULL;
4275 :
4276 3304 : gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox *)tmp);
4277 3304 : return (GF_Box *)tmp;
4278 : }
4279 :
4280 :
4281 : #ifndef GPAC_DISABLE_ISOM_WRITE
4282 :
4283 1996 : GF_Err video_sample_entry_box_write(GF_Box *s, GF_BitStream *bs)
4284 : {
4285 : GF_Err e;
4286 1996 : e = gf_isom_box_write_header(s, bs);
4287 1996 : if (e) return e;
4288 1996 : gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)s, bs);
4289 1996 : return GF_OK;
4290 : }
4291 :
4292 3463 : GF_Err video_sample_entry_box_size(GF_Box *s)
4293 : {
4294 : GF_Box *b;
4295 3463 : u32 pos=0;
4296 : GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
4297 3463 : gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);
4298 :
4299 : /*make sure we write the config box first, we don't care about the rest*/
4300 :
4301 : /*mp4v*/
4302 3463 : gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos);
4303 3463 : gf_isom_check_position(s, (GF_Box *)ptr->cfg_3gpp, &pos);
4304 : /*avc / SVC + MVC*/
4305 3463 : gf_isom_check_position(s, (GF_Box *)ptr->avc_config, &pos);
4306 3463 : gf_isom_check_position(s, (GF_Box *)ptr->svc_config, &pos);
4307 3463 : if (ptr->mvc_config) {
4308 0 : gf_isom_check_position(s, gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_VWID), &pos);
4309 0 : gf_isom_check_position(s, (GF_Box *)ptr->mvc_config, &pos);
4310 : }
4311 :
4312 : /*HEVC*/
4313 3463 : gf_isom_check_position(s, (GF_Box *)ptr->hevc_config, &pos);
4314 3463 : gf_isom_check_position(s, (GF_Box *)ptr->lhvc_config, &pos);
4315 :
4316 : /*VVC*/
4317 3463 : gf_isom_check_position(s, (GF_Box *)ptr->vvc_config, &pos);
4318 :
4319 : /*AV1*/
4320 3463 : gf_isom_check_position(s, (GF_Box *)ptr->av1_config, &pos);
4321 :
4322 : /*VPx*/
4323 3463 : gf_isom_check_position(s, (GF_Box *)ptr->vp_config, &pos);
4324 :
4325 : /*JP2H*/
4326 3463 : gf_isom_check_position(s, (GF_Box *)ptr->jp2h, &pos);
4327 :
4328 : /*DolbyVision*/
4329 3463 : gf_isom_check_position(s, (GF_Box *)ptr->dovi_config, &pos);
4330 :
4331 3463 : b = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_ST3D);
4332 3463 : if (b) gf_isom_check_position(s, b, &pos);
4333 :
4334 3463 : b = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_SV3D);
4335 3463 : if (b) gf_isom_check_position(s, b, &pos);
4336 3463 : return GF_OK;
4337 : }
4338 :
4339 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4340 :
4341 :
4342 :
4343 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
4344 :
4345 602 : void mvex_box_del(GF_Box *s)
4346 : {
4347 : GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
4348 602 : if (ptr == NULL) return;
4349 602 : gf_list_del(ptr->TrackExList);
4350 602 : gf_list_del(ptr->TrackExPropList);
4351 602 : gf_free(ptr);
4352 : }
4353 :
4354 :
4355 960 : GF_Err mvex_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
4356 : {
4357 : GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
4358 :
4359 960 : switch (a->type) {
4360 722 : case GF_ISOM_BOX_TYPE_TREX:
4361 722 : BOX_FIELD_LIST_ASSIGN(TrackExList)
4362 : return GF_OK;
4363 0 : case GF_ISOM_BOX_TYPE_TREP:
4364 0 : BOX_FIELD_LIST_ASSIGN(TrackExPropList)
4365 : return GF_OK;
4366 238 : case GF_ISOM_BOX_TYPE_MEHD:
4367 238 : BOX_FIELD_ASSIGN(mehd, GF_MovieExtendsHeaderBox)
4368 238 : return GF_OK;
4369 : }
4370 : return GF_OK;
4371 : }
4372 :
4373 :
4374 :
4375 253 : GF_Err mvex_box_read(GF_Box *s, GF_BitStream *bs)
4376 : {
4377 253 : return gf_isom_box_array_read(s, bs);
4378 : }
4379 :
4380 602 : GF_Box *mvex_box_new()
4381 : {
4382 1204 : ISOM_DECL_BOX_ALLOC(GF_MovieExtendsBox, GF_ISOM_BOX_TYPE_MVEX);
4383 602 : tmp->TrackExList = gf_list_new();
4384 602 : if (!tmp->TrackExList) {
4385 0 : gf_free(tmp);
4386 0 : return NULL;
4387 : }
4388 602 : tmp->TrackExPropList = gf_list_new();
4389 602 : if (!tmp->TrackExPropList) {
4390 0 : gf_list_del(tmp->TrackExList);
4391 0 : gf_free(tmp);
4392 0 : return NULL;
4393 : }
4394 : return (GF_Box *)tmp;
4395 : }
4396 :
4397 :
4398 :
4399 : #ifndef GPAC_DISABLE_ISOM_WRITE
4400 :
4401 :
4402 342 : GF_Err mvex_box_write(GF_Box *s, GF_BitStream *bs)
4403 : {
4404 342 : return gf_isom_box_write_header(s, bs);
4405 : }
4406 :
4407 347 : GF_Err mvex_box_size(GF_Box *s)
4408 : {
4409 347 : u32 pos=0;
4410 : GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *) s;
4411 347 : gf_isom_check_position(s, (GF_Box *)ptr->mehd, &pos);
4412 347 : gf_isom_check_position_list(s, ptr->TrackExList, &pos);
4413 347 : gf_isom_check_position_list(s, ptr->TrackExPropList, &pos);
4414 347 : return GF_OK;
4415 : }
4416 :
4417 :
4418 :
4419 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4420 :
4421 583 : GF_Box *mehd_box_new()
4422 : {
4423 1166 : ISOM_DECL_BOX_ALLOC(GF_MovieExtendsHeaderBox, GF_ISOM_BOX_TYPE_MEHD);
4424 583 : return (GF_Box *)tmp;
4425 : }
4426 583 : void mehd_box_del(GF_Box *s)
4427 : {
4428 583 : gf_free(s);
4429 583 : }
4430 239 : GF_Err mehd_box_read(GF_Box *s, GF_BitStream *bs)
4431 : {
4432 : GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
4433 :
4434 239 : if (ptr->version==1) {
4435 3 : ISOM_DECREASE_SIZE(ptr, 8);
4436 3 : ptr->fragment_duration = gf_bs_read_u64(bs);
4437 : } else {
4438 236 : ISOM_DECREASE_SIZE(ptr, 4);
4439 236 : ptr->fragment_duration = (u64) gf_bs_read_u32(bs);
4440 : }
4441 : return GF_OK;
4442 : }
4443 : #ifndef GPAC_DISABLE_ISOM_WRITE
4444 342 : GF_Err mehd_box_write(GF_Box *s, GF_BitStream *bs)
4445 : {
4446 : GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
4447 342 : GF_Err e = gf_isom_full_box_write(s, bs);
4448 342 : if (e) return e;
4449 342 : if (ptr->version == 1) {
4450 0 : gf_bs_write_u64(bs, ptr->fragment_duration);
4451 : } else {
4452 342 : gf_bs_write_u32(bs, (u32) ptr->fragment_duration);
4453 : }
4454 : return GF_OK;
4455 : }
4456 347 : GF_Err mehd_box_size(GF_Box *s)
4457 : {
4458 : GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
4459 347 : ptr->version = (ptr->fragment_duration>0xFFFFFFFF) ? 1 : 0;
4460 347 : s->size += (ptr->version == 1) ? 8 : 4;
4461 347 : return GF_OK;
4462 : }
4463 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4464 :
4465 : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
4466 :
4467 :
4468 2961 : void mvhd_box_del(GF_Box *s)
4469 : {
4470 : GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
4471 2961 : if (ptr == NULL) return;
4472 2961 : gf_free(ptr);
4473 : }
4474 :
4475 :
4476 1666 : GF_Err mvhd_box_read(GF_Box *s, GF_BitStream *bs)
4477 : {
4478 : GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
4479 1666 : if (ptr == NULL) return GF_BAD_PARAM;
4480 1666 : if (ptr->version == 1) {
4481 0 : ISOM_DECREASE_SIZE(ptr, 28);
4482 0 : ptr->creationTime = gf_bs_read_u64(bs);
4483 0 : ptr->modificationTime = gf_bs_read_u64(bs);
4484 0 : ptr->timeScale = gf_bs_read_u32(bs);
4485 0 : ptr->duration = gf_bs_read_u64(bs);
4486 : } else {
4487 1666 : ISOM_DECREASE_SIZE(ptr, 16);
4488 1666 : ptr->creationTime = gf_bs_read_u32(bs);
4489 1666 : ptr->modificationTime = gf_bs_read_u32(bs);
4490 1666 : ptr->timeScale = gf_bs_read_u32(bs);
4491 1666 : ptr->duration = gf_bs_read_u32(bs);
4492 : }
4493 1666 : if (!ptr->timeScale) {
4494 1 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Movie header timescale is invalid (0) - defaulting to 600\n" ));
4495 1 : ptr->timeScale = 600;
4496 : }
4497 1666 : ISOM_DECREASE_SIZE(ptr, 80);
4498 1666 : ptr->preferredRate = gf_bs_read_u32(bs);
4499 1666 : ptr->preferredVolume = gf_bs_read_u16(bs);
4500 1666 : gf_bs_read_data(bs, ptr->reserved, 10);
4501 1666 : ptr->matrixA = gf_bs_read_u32(bs);
4502 1666 : ptr->matrixB = gf_bs_read_u32(bs);
4503 1666 : ptr->matrixU = gf_bs_read_u32(bs);
4504 1666 : ptr->matrixC = gf_bs_read_u32(bs);
4505 1666 : ptr->matrixD = gf_bs_read_u32(bs);
4506 1666 : ptr->matrixV = gf_bs_read_u32(bs);
4507 1666 : ptr->matrixX = gf_bs_read_u32(bs);
4508 1666 : ptr->matrixY = gf_bs_read_u32(bs);
4509 1666 : ptr->matrixW = gf_bs_read_u32(bs);
4510 1666 : ptr->previewTime = gf_bs_read_u32(bs);
4511 1666 : ptr->previewDuration = gf_bs_read_u32(bs);
4512 1666 : ptr->posterTime = gf_bs_read_u32(bs);
4513 1666 : ptr->selectionTime = gf_bs_read_u32(bs);
4514 1666 : ptr->selectionDuration = gf_bs_read_u32(bs);
4515 1666 : ptr->currentTime = gf_bs_read_u32(bs);
4516 1666 : ptr->nextTrackID = gf_bs_read_u32(bs);
4517 1666 : ptr->original_duration = ptr->duration;
4518 1666 : return GF_OK;
4519 : }
4520 :
4521 2961 : GF_Box *mvhd_box_new()
4522 : {
4523 5922 : ISOM_DECL_BOX_ALLOC(GF_MovieHeaderBox, GF_ISOM_BOX_TYPE_MVHD);
4524 :
4525 2961 : tmp->preferredRate = (1<<16);
4526 2961 : tmp->preferredVolume = (1<<8);
4527 :
4528 2961 : tmp->matrixA = (1<<16);
4529 2961 : tmp->matrixD = (1<<16);
4530 2961 : tmp->matrixW = (1<<30);
4531 :
4532 2961 : tmp->nextTrackID = 1;
4533 :
4534 2961 : return (GF_Box *)tmp;
4535 : }
4536 :
4537 :
4538 : #ifndef GPAC_DISABLE_ISOM_WRITE
4539 :
4540 1373 : GF_Err mvhd_box_write(GF_Box *s, GF_BitStream *bs)
4541 : {
4542 : GF_Err e;
4543 : GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
4544 1373 : e = gf_isom_full_box_write(s, bs);
4545 1373 : if (e) return e;
4546 1373 : if (ptr->version == 1) {
4547 0 : gf_bs_write_u64(bs, ptr->creationTime);
4548 0 : gf_bs_write_u64(bs, ptr->modificationTime);
4549 0 : gf_bs_write_u32(bs, ptr->timeScale);
4550 0 : gf_bs_write_u64(bs, ptr->duration);
4551 : } else {
4552 1373 : gf_bs_write_u32(bs, (u32) ptr->creationTime);
4553 1373 : gf_bs_write_u32(bs, (u32) ptr->modificationTime);
4554 1373 : gf_bs_write_u32(bs, ptr->timeScale);
4555 1373 : gf_bs_write_u32(bs, (u32) ptr->duration);
4556 : }
4557 1373 : gf_bs_write_u32(bs, ptr->preferredRate);
4558 1373 : gf_bs_write_u16(bs, ptr->preferredVolume);
4559 1373 : gf_bs_write_data(bs, ptr->reserved, 10);
4560 1373 : gf_bs_write_u32(bs, ptr->matrixA);
4561 1373 : gf_bs_write_u32(bs, ptr->matrixB);
4562 1373 : gf_bs_write_u32(bs, ptr->matrixU);
4563 1373 : gf_bs_write_u32(bs, ptr->matrixC);
4564 1373 : gf_bs_write_u32(bs, ptr->matrixD);
4565 1373 : gf_bs_write_u32(bs, ptr->matrixV);
4566 1373 : gf_bs_write_u32(bs, ptr->matrixX);
4567 1373 : gf_bs_write_u32(bs, ptr->matrixY);
4568 1373 : gf_bs_write_u32(bs, ptr->matrixW);
4569 1373 : gf_bs_write_u32(bs, ptr->previewTime);
4570 1373 : gf_bs_write_u32(bs, ptr->previewDuration);
4571 1373 : gf_bs_write_u32(bs, ptr->posterTime);
4572 1373 : gf_bs_write_u32(bs, ptr->selectionTime);
4573 1373 : gf_bs_write_u32(bs, ptr->selectionDuration);
4574 1373 : gf_bs_write_u32(bs, ptr->currentTime);
4575 1373 : gf_bs_write_u32(bs, ptr->nextTrackID);
4576 1373 : return GF_OK;
4577 : }
4578 :
4579 3377 : GF_Err mvhd_box_size(GF_Box *s)
4580 : {
4581 : GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
4582 3377 : if (ptr->duration==(u64) -1) ptr->version = 0;
4583 3377 : else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
4584 :
4585 3377 : ptr->size += (ptr->version == 1) ? 28 : 16;
4586 3377 : ptr->size += 80;
4587 3377 : return GF_OK;
4588 : }
4589 :
4590 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4591 :
4592 :
4593 643 : void nmhd_box_del(GF_Box *s)
4594 : {
4595 : GF_MPEGMediaHeaderBox *ptr = (GF_MPEGMediaHeaderBox *)s;
4596 643 : if (ptr == NULL) return;
4597 643 : gf_free(ptr);
4598 : }
4599 :
4600 :
4601 :
4602 420 : GF_Err nmhd_box_read(GF_Box *s, GF_BitStream *bs)
4603 : {
4604 420 : return GF_OK;
4605 : }
4606 :
4607 643 : GF_Box *nmhd_box_new()
4608 : {
4609 1286 : ISOM_DECL_BOX_ALLOC(GF_MPEGMediaHeaderBox, GF_ISOM_BOX_TYPE_NMHD);
4610 643 : return (GF_Box *)tmp;
4611 : }
4612 :
4613 :
4614 : #ifndef GPAC_DISABLE_ISOM_WRITE
4615 :
4616 417 : GF_Err nmhd_box_write(GF_Box *s, GF_BitStream *bs)
4617 : {
4618 417 : return gf_isom_full_box_write(s, bs);
4619 : }
4620 :
4621 999 : GF_Err nmhd_box_size(GF_Box *s)
4622 : {
4623 999 : return GF_OK;
4624 : }
4625 :
4626 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4627 :
4628 :
4629 :
4630 3 : void padb_box_del(GF_Box *s)
4631 : {
4632 : GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *) s;
4633 3 : if (ptr == NULL) return;
4634 3 : if (ptr->padbits) gf_free(ptr->padbits);
4635 3 : gf_free(ptr);
4636 : }
4637 :
4638 :
4639 1 : GF_Err padb_box_read(GF_Box *s,GF_BitStream *bs)
4640 : {
4641 : u32 i;
4642 : GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;
4643 :
4644 1 : ISOM_DECREASE_SIZE(ptr, 4);
4645 1 : ptr->SampleCount = gf_bs_read_u32(bs);
4646 1 : if (ptr->size < ptr->SampleCount/2) //half byte per sample
4647 : return GF_ISOM_INVALID_FILE;
4648 :
4649 1 : ptr->padbits = (u8 *)gf_malloc(sizeof(u8)*ptr->SampleCount);
4650 1 : if (!ptr->padbits) return GF_OUT_OF_MEM;
4651 :
4652 0 : for (i=0; i<ptr->SampleCount; i += 2) {
4653 0 : gf_bs_read_int(bs, 1);
4654 0 : if (i+1 < ptr->SampleCount) {
4655 0 : ptr->padbits[i+1] = gf_bs_read_int(bs, 3);
4656 : } else {
4657 0 : gf_bs_read_int(bs, 3);
4658 : }
4659 0 : gf_bs_read_int(bs, 1);
4660 0 : ptr->padbits[i] = gf_bs_read_int(bs, 3);
4661 : }
4662 : return GF_OK;
4663 : }
4664 :
4665 3 : GF_Box *padb_box_new()
4666 : {
4667 6 : ISOM_DECL_BOX_ALLOC(GF_PaddingBitsBox, GF_ISOM_BOX_TYPE_PADB);
4668 3 : return (GF_Box *)tmp;
4669 : }
4670 :
4671 :
4672 :
4673 : #ifndef GPAC_DISABLE_ISOM_WRITE
4674 :
4675 1 : GF_Err padb_box_write(GF_Box *s, GF_BitStream *bs)
4676 : {
4677 : u32 i;
4678 : GF_Err e;
4679 : GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *) s;
4680 :
4681 1 : e = gf_isom_full_box_write(s, bs);
4682 1 : if (e) return e;
4683 1 : gf_bs_write_int(bs, ptr->SampleCount, 32);
4684 :
4685 1 : for (i=0 ; i<ptr->SampleCount; i += 2) {
4686 0 : gf_bs_write_int(bs, 0, 1);
4687 0 : if (i+1 < ptr->SampleCount) {
4688 0 : gf_bs_write_int(bs, ptr->padbits[i+1], 3);
4689 : } else {
4690 0 : gf_bs_write_int(bs, 0, 3);
4691 : }
4692 0 : gf_bs_write_int(bs, 0, 1);
4693 0 : gf_bs_write_int(bs, ptr->padbits[i], 3);
4694 : }
4695 : return GF_OK;
4696 : }
4697 :
4698 1 : GF_Err padb_box_size(GF_Box *s)
4699 : {
4700 : GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;
4701 1 : ptr->size += 4;
4702 1 : if (ptr->SampleCount) ptr->size += (ptr->SampleCount + 1) / 2;
4703 :
4704 1 : return GF_OK;
4705 : }
4706 :
4707 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4708 :
4709 :
4710 3 : void rely_box_del(GF_Box *s)
4711 : {
4712 : GF_RelyHintBox *rely = (GF_RelyHintBox *)s;
4713 3 : gf_free(rely);
4714 3 : }
4715 :
4716 1 : GF_Err rely_box_read(GF_Box *s, GF_BitStream *bs)
4717 : {
4718 : GF_RelyHintBox *ptr = (GF_RelyHintBox *)s;
4719 1 : ISOM_DECREASE_SIZE(ptr, 1);
4720 1 : ptr->reserved = gf_bs_read_int(bs, 6);
4721 1 : ptr->preferred = gf_bs_read_int(bs, 1);
4722 1 : ptr->required = gf_bs_read_int(bs, 1);
4723 1 : return GF_OK;
4724 : }
4725 :
4726 3 : GF_Box *rely_box_new()
4727 : {
4728 6 : ISOM_DECL_BOX_ALLOC(GF_RelyHintBox, GF_ISOM_BOX_TYPE_RELY);
4729 3 : return (GF_Box *)tmp;
4730 : }
4731 :
4732 :
4733 : #ifndef GPAC_DISABLE_ISOM_WRITE
4734 1 : GF_Err rely_box_write(GF_Box *s, GF_BitStream *bs)
4735 : {
4736 : GF_Err e;
4737 : GF_RelyHintBox *ptr = (GF_RelyHintBox *)s;
4738 1 : if (ptr == NULL) return GF_BAD_PARAM;
4739 1 : e = gf_isom_box_write_header(s, bs);
4740 1 : if (e) return e;
4741 1 : gf_bs_write_int(bs, ptr->reserved, 6);
4742 1 : gf_bs_write_int(bs, ptr->preferred, 1);
4743 1 : gf_bs_write_int(bs, ptr->required, 1);
4744 1 : return GF_OK;
4745 : }
4746 :
4747 1 : GF_Err rely_box_size(GF_Box *s)
4748 : {
4749 1 : s->size += 1;
4750 1 : return GF_OK;
4751 : }
4752 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4753 :
4754 :
4755 9740 : void rtpo_box_del(GF_Box *s)
4756 : {
4757 : GF_RTPOBox *rtpo = (GF_RTPOBox *)s;
4758 9740 : gf_free(rtpo);
4759 9740 : }
4760 :
4761 1 : GF_Err rtpo_box_read(GF_Box *s, GF_BitStream *bs)
4762 : {
4763 : GF_RTPOBox *ptr = (GF_RTPOBox *)s;
4764 1 : ISOM_DECREASE_SIZE(ptr, 4);
4765 1 : ptr->timeOffset = gf_bs_read_u32(bs);
4766 1 : return GF_OK;
4767 : }
4768 :
4769 9740 : GF_Box *rtpo_box_new()
4770 : {
4771 19480 : ISOM_DECL_BOX_ALLOC(GF_RTPOBox, GF_ISOM_BOX_TYPE_RTPO);
4772 9740 : return (GF_Box *)tmp;
4773 : }
4774 : #ifndef GPAC_DISABLE_ISOM_WRITE
4775 9738 : GF_Err rtpo_box_write(GF_Box *s, GF_BitStream *bs)
4776 : {
4777 : GF_Err e;
4778 : GF_RTPOBox *ptr = (GF_RTPOBox *)s;
4779 9738 : if (ptr == NULL) return GF_BAD_PARAM;
4780 :
4781 : //here we have no pb, just remembed that some entries will have to
4782 : //be 4-bytes aligned ...
4783 9738 : e = gf_isom_box_write_header(s, bs);
4784 9738 : if (e) return e;
4785 9738 : gf_bs_write_u32(bs, ptr->timeOffset);
4786 9738 : return GF_OK;
4787 : }
4788 :
4789 19475 : GF_Err rtpo_box_size(GF_Box *s)
4790 : {
4791 19475 : s->size += 4;
4792 19475 : return GF_OK;
4793 : }
4794 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4795 :
4796 980 : void smhd_box_del(GF_Box *s)
4797 : {
4798 : GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
4799 980 : if (ptr == NULL ) return;
4800 980 : gf_free(ptr);
4801 : }
4802 :
4803 :
4804 799 : GF_Err smhd_box_read(GF_Box *s, GF_BitStream *bs)
4805 : {
4806 : GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
4807 799 : ISOM_DECREASE_SIZE(ptr, 4);
4808 799 : ptr->balance = gf_bs_read_u16(bs);
4809 799 : ptr->reserved = gf_bs_read_u16(bs);
4810 799 : return GF_OK;
4811 : }
4812 :
4813 980 : GF_Box *smhd_box_new()
4814 : {
4815 1960 : ISOM_DECL_BOX_ALLOC(GF_SoundMediaHeaderBox, GF_ISOM_BOX_TYPE_SMHD);
4816 980 : return (GF_Box *)tmp;
4817 : }
4818 :
4819 :
4820 : #ifndef GPAC_DISABLE_ISOM_WRITE
4821 :
4822 772 : GF_Err smhd_box_write(GF_Box *s, GF_BitStream *bs)
4823 : {
4824 : GF_Err e;
4825 : GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
4826 772 : e = gf_isom_full_box_write(s, bs);
4827 772 : if (e) return e;
4828 772 : gf_bs_write_u16(bs, ptr->balance);
4829 772 : gf_bs_write_u16(bs, ptr->reserved);
4830 772 : return GF_OK;
4831 : }
4832 :
4833 1484 : GF_Err smhd_box_size(GF_Box *s)
4834 : {
4835 : GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
4836 :
4837 1484 : ptr->reserved = 0;
4838 1484 : ptr->size += 4;
4839 1484 : return GF_OK;
4840 : }
4841 :
4842 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4843 :
4844 :
4845 :
4846 4 : void snro_box_del(GF_Box *s)
4847 : {
4848 : GF_SeqOffHintEntryBox *snro = (GF_SeqOffHintEntryBox *)s;
4849 4 : gf_free(snro);
4850 4 : }
4851 :
4852 1 : GF_Err snro_box_read(GF_Box *s, GF_BitStream *bs)
4853 : {
4854 : GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s;
4855 1 : ISOM_DECREASE_SIZE(ptr, 4);
4856 1 : ptr->SeqOffset = gf_bs_read_u32(bs);
4857 1 : return GF_OK;
4858 : }
4859 :
4860 4 : GF_Box *snro_box_new()
4861 : {
4862 8 : ISOM_DECL_BOX_ALLOC(GF_SeqOffHintEntryBox, GF_ISOM_BOX_TYPE_SNRO);
4863 4 : return (GF_Box *)tmp;
4864 : }
4865 :
4866 :
4867 : #ifndef GPAC_DISABLE_ISOM_WRITE
4868 2 : GF_Err snro_box_write(GF_Box *s, GF_BitStream *bs)
4869 : {
4870 : GF_Err e;
4871 : GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s;
4872 2 : if (ptr == NULL) return GF_BAD_PARAM;
4873 :
4874 2 : e = gf_isom_box_write_header(s, bs);
4875 2 : if (e) return e;
4876 2 : gf_bs_write_u32(bs, ptr->SeqOffset);
4877 2 : return GF_OK;
4878 : }
4879 :
4880 4 : GF_Err snro_box_size(GF_Box *s)
4881 : {
4882 4 : s->size += 4;
4883 4 : return GF_OK;
4884 : }
4885 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
4886 :
4887 :
4888 5368 : void stbl_box_del(GF_Box *s)
4889 : {
4890 : GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
4891 5368 : if (ptr == NULL) return;
4892 :
4893 5368 : if (ptr->sub_samples) gf_list_del(ptr->sub_samples);
4894 5368 : if (ptr->sampleGroups) gf_list_del(ptr->sampleGroups);
4895 5368 : if (ptr->sampleGroupsDescription) gf_list_del(ptr->sampleGroupsDescription);
4896 5368 : if (ptr->sai_sizes) gf_list_del(ptr->sai_sizes);
4897 5368 : if (ptr->sai_offsets) gf_list_del(ptr->sai_offsets);
4898 5368 : if (ptr->traf_map) {
4899 36 : if (ptr->traf_map->frag_starts) {
4900 : u32 i;
4901 117 : for (i=0; i<ptr->traf_map->nb_entries; i++) {
4902 117 : if (ptr->traf_map->frag_starts[i].moof_template)
4903 36 : gf_free(ptr->traf_map->frag_starts[i].moof_template);
4904 : }
4905 36 : gf_free(ptr->traf_map->frag_starts);
4906 : }
4907 36 : gf_free(ptr->traf_map);
4908 : }
4909 5368 : gf_free(ptr);
4910 : }
4911 :
4912 15435 : GF_Err stbl_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
4913 : {
4914 : GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
4915 15435 : if (!a) return GF_OK;
4916 15435 : switch (a->type) {
4917 2385 : case GF_ISOM_BOX_TYPE_STTS:
4918 2385 : BOX_FIELD_ASSIGN(TimeToSample, GF_TimeToSampleBox)
4919 2385 : break;
4920 476 : case GF_ISOM_BOX_TYPE_CTTS:
4921 476 : BOX_FIELD_ASSIGN(CompositionOffset, GF_CompositionOffsetBox)
4922 476 : break;
4923 12 : case GF_ISOM_BOX_TYPE_CSLG:
4924 12 : BOX_FIELD_ASSIGN(CompositionToDecode, GF_CompositionToDecodeBox)
4925 12 : break;
4926 1071 : case GF_ISOM_BOX_TYPE_STSS:
4927 1071 : BOX_FIELD_ASSIGN(SyncSample, GF_SyncSampleBox)
4928 1071 : break;
4929 3105 : case GF_ISOM_BOX_TYPE_STSD:
4930 3105 : BOX_FIELD_ASSIGN(SampleDescription, GF_SampleDescriptionBox)
4931 3105 : break;
4932 2385 : case GF_ISOM_BOX_TYPE_STZ2:
4933 : case GF_ISOM_BOX_TYPE_STSZ:
4934 2385 : BOX_FIELD_ASSIGN(SampleSize, GF_SampleSizeBox)
4935 2385 : break;
4936 2385 : case GF_ISOM_BOX_TYPE_STSC:
4937 2385 : BOX_FIELD_ASSIGN(SampleToChunk, GF_SampleToChunkBox)
4938 2385 : break;
4939 0 : case GF_ISOM_BOX_TYPE_PADB:
4940 0 : BOX_FIELD_ASSIGN(PaddingBits, GF_PaddingBitsBox)
4941 0 : break;
4942 :
4943 : //WARNING: AS THIS MAY CHANGE DYNAMICALLY DURING EDIT,
4944 2385 : case GF_ISOM_BOX_TYPE_CO64:
4945 : case GF_ISOM_BOX_TYPE_STCO:
4946 2385 : BOX_FIELD_ASSIGN(ChunkOffset, GF_Box)
4947 2385 : break;
4948 0 : case GF_ISOM_BOX_TYPE_STSH:
4949 0 : BOX_FIELD_ASSIGN(ShadowSync, GF_ShadowSyncBox)
4950 0 : break;
4951 0 : case GF_ISOM_BOX_TYPE_STDP:
4952 0 : BOX_FIELD_ASSIGN(DegradationPriority, GF_DegradationPriorityBox)
4953 0 : break;
4954 15 : case GF_ISOM_BOX_TYPE_SDTP:
4955 15 : BOX_FIELD_ASSIGN(SampleDep, GF_SampleDependencyTypeBox)
4956 15 : break;
4957 :
4958 3 : case GF_ISOM_BOX_TYPE_SUBS:
4959 3 : BOX_FIELD_LIST_ASSIGN(sub_samples)
4960 : //check subsample box
4961 3 : if (!is_rem) {
4962 : GF_SubSampleInformationBox *subs = (GF_SubSampleInformationBox *)a;
4963 3 : GF_SubSampleInfoEntry *ent = gf_list_get(subs->Samples, 0);
4964 3 : if (!ent) {
4965 0 : gf_list_rem(subs->Samples, 0);
4966 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] first entry in SubSample in track SampleTable is invalid\n"));
4967 : }
4968 3 : else if (ent->sample_delta==0) {
4969 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] first entry in SubSample in track SampleTable has sample_delta of 0, should be one. Fixing\n"));
4970 0 : ent->sample_delta = 1;
4971 : }
4972 : }
4973 : break;
4974 :
4975 82 : case GF_ISOM_BOX_TYPE_SBGP:
4976 : case GF_ISOM_BOX_TYPE_CSGP:
4977 82 : BOX_FIELD_LIST_ASSIGN(sampleGroups)
4978 : break;
4979 291 : case GF_ISOM_BOX_TYPE_SGPD:
4980 291 : BOX_FIELD_LIST_ASSIGN(sampleGroupsDescription)
4981 : break;
4982 420 : case GF_ISOM_BOX_TYPE_SAIZ:
4983 420 : BOX_FIELD_LIST_ASSIGN(sai_sizes)
4984 : break;
4985 420 : case GF_ISOM_BOX_TYPE_SAIO:
4986 420 : BOX_FIELD_LIST_ASSIGN(sai_offsets)
4987 : break;
4988 : }
4989 : return GF_OK;
4990 : }
4991 :
4992 :
4993 :
4994 :
4995 3106 : GF_Err stbl_box_read(GF_Box *s, GF_BitStream *bs)
4996 : {
4997 : GF_Err e;
4998 : //we need to parse DegPrior in a special way
4999 : GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
5000 :
5001 3106 : e = gf_isom_box_array_read(s, bs);
5002 3106 : if (e) return e;
5003 :
5004 3106 : if (!ptr->SyncSample)
5005 2035 : ptr->no_sync_found = 1;
5006 :
5007 3106 : ptr->nb_sgpd_in_stbl = gf_list_count(ptr->sampleGroupsDescription);
5008 3106 : ptr->nb_stbl_boxes = gf_list_count(ptr->child_boxes);
5009 :
5010 3106 : if (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_CLONE_TRACK)
5011 : return GF_OK;
5012 : // return GF_OK;
5013 :
5014 : //these boxes are mandatory !
5015 2386 : if (!ptr->SampleToChunk || !ptr->SampleSize || !ptr->ChunkOffset || !ptr->TimeToSample)
5016 : return GF_ISOM_INVALID_FILE;
5017 : //sanity check
5018 2385 : if (ptr->SampleSize->sampleCount) {
5019 2017 : if (!ptr->TimeToSample->nb_entries || !ptr->SampleToChunk->nb_entries)
5020 : return GF_ISOM_INVALID_FILE;
5021 : }
5022 2385 : return GF_OK;
5023 : }
5024 :
5025 5368 : GF_Box *stbl_box_new()
5026 : {
5027 10736 : ISOM_DECL_BOX_ALLOC(GF_SampleTableBox, GF_ISOM_BOX_TYPE_STBL);
5028 : //maxSamplePer chunk is 10 by default
5029 5368 : tmp->MaxSamplePerChunk = 10;
5030 5368 : tmp->groupID = 1;
5031 5368 : return (GF_Box *)tmp;
5032 : }
5033 :
5034 :
5035 :
5036 : #ifndef GPAC_DISABLE_ISOM_WRITE
5037 :
5038 3176 : GF_Err stbl_box_write(GF_Box *s, GF_BitStream *bs)
5039 : {
5040 3176 : return gf_isom_box_write_header(s, bs);
5041 : }
5042 :
5043 6125 : GF_Err stbl_box_size(GF_Box *s)
5044 : {
5045 6125 : u32 pos=0;
5046 : GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
5047 :
5048 6125 : gf_isom_check_position(s, (GF_Box *)ptr->SampleDescription, &pos);
5049 6125 : gf_isom_check_position(s, (GF_Box *)ptr->TimeToSample, &pos);
5050 6125 : gf_isom_check_position(s, (GF_Box *)ptr->CompositionOffset, &pos);
5051 6125 : gf_isom_check_position(s, (GF_Box *)ptr->CompositionToDecode, &pos);
5052 6125 : gf_isom_check_position(s, (GF_Box *)ptr->SyncSample, &pos);
5053 6125 : gf_isom_check_position(s, (GF_Box *)ptr->ShadowSync, &pos);
5054 6125 : gf_isom_check_position(s, (GF_Box *)ptr->SampleToChunk, &pos);
5055 6125 : gf_isom_check_position(s, (GF_Box *)ptr->SampleSize, &pos);
5056 6125 : gf_isom_check_position(s, (GF_Box *)ptr->ChunkOffset, &pos);
5057 6125 : gf_isom_check_position(s, (GF_Box *)ptr->DegradationPriority, &pos);
5058 6125 : gf_isom_check_position(s, (GF_Box *)ptr->SampleDep, &pos);
5059 6125 : gf_isom_check_position(s, (GF_Box *)ptr->PaddingBits, &pos);
5060 :
5061 6125 : if (ptr->sub_samples) {
5062 12 : gf_isom_check_position_list(s, ptr->sub_samples, &pos);
5063 : }
5064 6125 : if (ptr->sampleGroupsDescription) {
5065 441 : gf_isom_check_position_list(s, ptr->sampleGroupsDescription, &pos);
5066 : }
5067 6125 : if (ptr->sampleGroups) {
5068 129 : gf_isom_check_position_list(s, ptr->sampleGroups, &pos);
5069 : }
5070 6125 : if (ptr->sai_sizes) {
5071 291 : gf_isom_check_position_list(s, ptr->sai_sizes, &pos);
5072 : }
5073 6125 : if (ptr->sai_offsets) {
5074 291 : gf_isom_check_position_list(s, ptr->sai_offsets, &pos);
5075 : }
5076 6125 : return GF_OK;
5077 : }
5078 :
5079 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
5080 :
5081 :
5082 24434 : void stco_box_del(GF_Box *s)
5083 : {
5084 : GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
5085 24434 : if (ptr == NULL) return;
5086 24434 : if (ptr->offsets) gf_free(ptr->offsets);
5087 24434 : gf_free(ptr);
5088 : }
5089 :
5090 :
5091 2386 : GF_Err stco_box_read(GF_Box *s, GF_BitStream *bs)
5092 : {
5093 : u32 entries;
5094 : GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
5095 :
5096 2386 : ISOM_DECREASE_SIZE(ptr, 4);
5097 2386 : ptr->nb_entries = gf_bs_read_u32(bs);
5098 2386 : if (ptr->nb_entries > ptr->size / 4) {
5099 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stco\n", ptr->nb_entries));
5100 : return GF_ISOM_INVALID_FILE;
5101 : }
5102 :
5103 2386 : if (ptr->nb_entries) {
5104 2017 : ptr->offsets = (u32 *) gf_malloc(ptr->nb_entries * sizeof(u32) );
5105 2017 : if (ptr->offsets == NULL) return GF_OUT_OF_MEM;
5106 2017 : ptr->alloc_size = ptr->nb_entries;
5107 :
5108 85622 : for (entries = 0; entries < ptr->nb_entries; entries++) {
5109 83605 : ptr->offsets[entries] = gf_bs_read_u32(bs);
5110 : }
5111 : }
5112 : return GF_OK;
5113 : }
5114 :
5115 24434 : GF_Box *stco_box_new()
5116 : {
5117 48868 : ISOM_DECL_BOX_ALLOC(GF_ChunkOffsetBox, GF_ISOM_BOX_TYPE_STCO);
5118 24434 : return (GF_Box *)tmp;
5119 : }
5120 :
5121 :
5122 :
5123 : #ifndef GPAC_DISABLE_ISOM_WRITE
5124 :
5125 1932 : GF_Err stco_box_write(GF_Box *s, GF_BitStream *bs)
5126 : {
5127 : GF_Err e;
5128 : u32 i;
5129 : GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
5130 1932 : e = gf_isom_full_box_write(s, bs);
5131 1932 : if (e) return e;
5132 1932 : gf_bs_write_u32(bs, ptr->nb_entries);
5133 66733 : for (i = 0; i < ptr->nb_entries; i++) {
5134 64801 : gf_bs_write_u32(bs, ptr->offsets[i]);
5135 : }
5136 : return GF_OK;
5137 : }
5138 :
5139 :
5140 7727 : GF_Err stco_box_size(GF_Box *s)
5141 : {
5142 : GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
5143 :
5144 7727 : ptr->size += 4 + (4 * ptr->nb_entries);
5145 7727 : return GF_OK;
5146 : }
5147 :
5148 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
5149 :
5150 :
5151 :
5152 6 : void stdp_box_del(GF_Box *s)
5153 : {
5154 : GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
5155 6 : if (ptr == NULL ) return;
5156 6 : if (ptr->priorities) gf_free(ptr->priorities);
5157 6 : gf_free(ptr);
5158 : }
5159 :
5160 : //this is called through stbl_read...
5161 1 : GF_Err stdp_box_read(GF_Box *s, GF_BitStream *bs)
5162 : {
5163 : u32 entry;
5164 : GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
5165 :
5166 : /*out-of-order stdp, assume no padding at the end and take the entire remaining data for entries*/
5167 1 : if (!ptr->nb_entries) ptr->nb_entries = (u32) ptr->size / 2;
5168 0 : else if (ptr->nb_entries > ptr->size / 2) return GF_ISOM_INVALID_FILE;
5169 :
5170 1 : ptr->priorities = (u16 *) gf_malloc(ptr->nb_entries * sizeof(u16));
5171 1 : if (ptr->priorities == NULL) return GF_OUT_OF_MEM;
5172 0 : for (entry = 0; entry < ptr->nb_entries; entry++) {
5173 0 : ptr->priorities[entry] = gf_bs_read_u16(bs);
5174 : }
5175 1 : ISOM_DECREASE_SIZE(ptr, (2*ptr->nb_entries) );
5176 1 : return GF_OK;
5177 : }
5178 :
5179 6 : GF_Box *stdp_box_new()
5180 : {
5181 12 : ISOM_DECL_BOX_ALLOC(GF_DegradationPriorityBox, GF_ISOM_BOX_TYPE_STDP);
5182 6 : return (GF_Box *)tmp;
5183 : }
5184 :
5185 :
5186 : #ifndef GPAC_DISABLE_ISOM_WRITE
5187 :
5188 1 : GF_Err stdp_box_write(GF_Box *s, GF_BitStream *bs)
5189 : {
5190 : GF_Err e;
5191 : u32 i;
5192 : GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
5193 1 : e = gf_isom_full_box_write(s, bs);
5194 1 : if (e) return e;
5195 :
5196 0 : for (i = 0; i < ptr->nb_entries; i++) {
5197 0 : gf_bs_write_u16(bs, ptr->priorities[i]);
5198 : }
5199 : return GF_OK;
5200 : }
5201 :
5202 1 : GF_Err stdp_box_size(GF_Box *s)
5203 : {
5204 : GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
5205 :
5206 1 : ptr->size += (2 * ptr->nb_entries);
5207 1 : return GF_OK;
5208 : }
5209 :
5210 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
5211 :
5212 :
5213 25851 : void stsc_box_del(GF_Box *s)
5214 : {
5215 : GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
5216 25851 : if (ptr == NULL) return;
5217 25851 : if (ptr->entries) gf_free(ptr->entries);
5218 25851 : gf_free(ptr);
5219 : }
5220 :
5221 :
5222 2386 : GF_Err stsc_box_read(GF_Box *s, GF_BitStream *bs)
5223 : {
5224 : u32 i;
5225 : GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
5226 :
5227 2386 : ISOM_DECREASE_SIZE(ptr, 4);
5228 2386 : ptr->nb_entries = gf_bs_read_u32(bs);
5229 :
5230 2386 : if (ptr->nb_entries > ptr->size / 12) {
5231 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsc\n", ptr->nb_entries));
5232 : return GF_ISOM_INVALID_FILE;
5233 : }
5234 :
5235 2386 : ptr->alloc_size = ptr->nb_entries;
5236 2386 : ptr->entries = NULL;
5237 2386 : if (ptr->nb_entries) {
5238 2017 : ptr->entries = gf_malloc(sizeof(GF_StscEntry)*ptr->alloc_size);
5239 2017 : if (!ptr->entries) return GF_OUT_OF_MEM;
5240 : }
5241 :
5242 6608 : for (i = 0; i < ptr->nb_entries; i++) {
5243 6608 : ptr->entries[i].firstChunk = gf_bs_read_u32(bs);
5244 6608 : ptr->entries[i].samplesPerChunk = gf_bs_read_u32(bs);
5245 6608 : ptr->entries[i].sampleDescriptionIndex = gf_bs_read_u32(bs);
5246 6608 : ptr->entries[i].isEdited = 0;
5247 6608 : ptr->entries[i].nextChunk = 0;
5248 6608 : if (!ptr->entries[i].firstChunk) {
5249 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] invalid first chunk 0 in stsc entry\n", ptr->nb_entries));
5250 : return GF_ISOM_INVALID_FILE;
5251 : }
5252 :
5253 : //update the next chunk in the previous entry
5254 6608 : if (i) ptr->entries[i-1].nextChunk = ptr->entries[i].firstChunk;
5255 : }
5256 2386 : ptr->currentIndex = 0;
5257 2386 : ptr->firstSampleInCurrentChunk = 0;
5258 2386 : ptr->currentChunk = 0;
5259 2386 : ptr->ghostNumber = 0;
5260 2386 : return GF_OK;
5261 : }
5262 :
5263 25851 : GF_Box *stsc_box_new()
5264 : {
5265 51702 : ISOM_DECL_BOX_ALLOC(GF_SampleToChunkBox, GF_ISOM_BOX_TYPE_STSC);
5266 25851 : return (GF_Box *)tmp;
5267 : }
5268 :
5269 :
5270 : #ifndef GPAC_DISABLE_ISOM_WRITE
5271 :
5272 1933 : GF_Err stsc_box_write(GF_Box *s, GF_BitStream *bs)
5273 : {
5274 : GF_Err e;
5275 : u32 i;
5276 : GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
5277 :
5278 1933 : e = gf_isom_full_box_write(s, bs);
5279 1933 : if (e) return e;
5280 1933 : gf_bs_write_u32(bs, ptr->nb_entries);
5281 7233 : for (i=0; i<ptr->nb_entries; i++) {
5282 5300 : gf_bs_write_u32(bs, ptr->entries[i].firstChunk);
5283 5300 : gf_bs_write_u32(bs, ptr->entries[i].samplesPerChunk);
5284 5300 : gf_bs_write_u32(bs, ptr->entries[i].sampleDescriptionIndex);
5285 : }
5286 : return GF_OK;
5287 : }
5288 :
5289 7730 : GF_Err stsc_box_size(GF_Box *s)
5290 : {
5291 : GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
5292 :
5293 7730 : ptr->size += 4 + (12 * ptr->nb_entries);
5294 7730 : return GF_OK;
5295 : }
5296 :
5297 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
5298 :
5299 5263 : void stsd_box_del(GF_Box *s)
5300 : {
5301 : GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
5302 5263 : if (ptr == NULL) return;
5303 5263 : gf_free(ptr);
5304 : }
5305 :
5306 2995 : GF_Err stsd_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
5307 : {
5308 : GF_UnknownBox *def;
5309 2995 : if (!a) return GF_OK;
5310 :
5311 2995 : if (is_rem || gf_box_valid_in_parent(a, "stsd")) {
5312 : return GF_OK;
5313 : }
5314 6 : switch (a->type) {
5315 : //unknown sample description: we need a specific box to handle the data ref index
5316 : //rather than a default box ...
5317 6 : case GF_ISOM_BOX_TYPE_UNKNOWN:
5318 : def = (GF_UnknownBox *)a;
5319 : /*we need at least 8 bytes for unknown sample entries*/
5320 6 : if (def->dataSize < 8) {
5321 0 : gf_isom_box_del_parent(&s->child_boxes, a);
5322 0 : return GF_ISOM_INVALID_MEDIA;
5323 : }
5324 : return GF_OK;
5325 :
5326 0 : default:
5327 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Cannot process box of type %s\n", gf_4cc_to_str(a->type)));
5328 : return GF_ISOM_INVALID_FILE;
5329 : }
5330 : }
5331 :
5332 :
5333 3106 : GF_Err stsd_box_read(GF_Box *s, GF_BitStream *bs)
5334 : {
5335 3106 : ISOM_DECREASE_SIZE(s, 4)
5336 3106 : gf_bs_read_u32(bs);
5337 :
5338 3106 : return gf_isom_box_array_read_ex(s, bs, GF_ISOM_BOX_TYPE_STSD);
5339 : }
5340 :
5341 5263 : GF_Box *stsd_box_new()
5342 : {
5343 10526 : ISOM_DECL_BOX_ALLOC(GF_SampleDescriptionBox, GF_ISOM_BOX_TYPE_STSD);
5344 5263 : tmp->child_boxes = gf_list_new();
5345 5263 : return (GF_Box *)tmp;
5346 : }
5347 :
5348 :
5349 : #ifndef GPAC_DISABLE_ISOM_WRITE
5350 :
5351 3178 : GF_Err stsd_box_write(GF_Box *s, GF_BitStream *bs)
5352 : {
5353 : GF_Err e;
5354 : u32 nb_entries;
5355 : GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
5356 :
5357 3178 : e = gf_isom_full_box_write(s, bs);
5358 3178 : if (e) return e;
5359 3178 : nb_entries = gf_list_count(ptr->child_boxes);
5360 3178 : gf_bs_write_u32(bs, nb_entries);
5361 3178 : return GF_OK;
5362 : }
5363 :
5364 6127 : GF_Err stsd_box_size(GF_Box *s)
5365 : {
5366 : GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
5367 6127 : ptr->size += 4;
5368 6127 : return GF_OK;
5369 : }
5370 :
5371 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
5372 :
5373 :
5374 9 : void stsh_box_del(GF_Box *s)
5375 : {
5376 9 : u32 i = 0;
5377 : GF_StshEntry *ent;
5378 : GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
5379 9 : if (ptr == NULL) return;
5380 21 : while ( (ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i)) ) {
5381 12 : gf_free(ent);
5382 : }
5383 9 : gf_list_del(ptr->entries);
5384 9 : gf_free(ptr);
5385 : }
5386 :
5387 :
5388 :
5389 1 : GF_Err stsh_box_read(GF_Box *s, GF_BitStream *bs)
5390 : {
5391 : GF_Err e;
5392 : u32 count, i;
5393 : GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
5394 :
5395 1 : ISOM_DECREASE_SIZE(s, 4)
5396 1 : count = gf_bs_read_u32(bs);
5397 1 : if (ptr->size / 8 < count)
5398 : return GF_ISOM_INVALID_FILE;
5399 :
5400 0 : for (i = 0; i < count; i++) {
5401 0 : GF_StshEntry *ent = (GF_StshEntry *) gf_malloc(sizeof(GF_StshEntry));
5402 0 : if (!ent) return GF_OUT_OF_MEM;
5403 0 : ent->shadowedSampleNumber = gf_bs_read_u32(bs);
5404 0 : ent->syncSampleNumber = gf_bs_read_u32(bs);
5405 0 : e = gf_list_add(ptr->entries, ent);
5406 0 : if (e) return e;
5407 : }
5408 : return GF_OK;
5409 : }
5410 :
5411 9 : GF_Box *stsh_box_new()
5412 : {
5413 18 : ISOM_DECL_BOX_ALLOC(GF_ShadowSyncBox, GF_ISOM_BOX_TYPE_STSH);
5414 :
5415 9 : tmp->entries = gf_list_new();
5416 9 : if (!tmp->entries) {
5417 0 : gf_free(tmp);
5418 0 : return NULL;
5419 : }
5420 : return (GF_Box *)tmp;
5421 : }
5422 :
5423 :
5424 : #ifndef GPAC_DISABLE_ISOM_WRITE
5425 :
5426 7 : GF_Err stsh_box_write(GF_Box *s, GF_BitStream *bs)
5427 : {
5428 : GF_Err e;
5429 : u32 i;
5430 : GF_StshEntry *ent;
5431 : GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
5432 :
5433 7 : e = gf_isom_full_box_write(s, bs);
5434 7 : if (e) return e;
5435 7 : gf_bs_write_u32(bs, gf_list_count(ptr->entries));
5436 7 : i=0;
5437 26 : while ((ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i))) {
5438 12 : gf_bs_write_u32(bs, ent->shadowedSampleNumber);
5439 12 : gf_bs_write_u32(bs, ent->syncSampleNumber);
5440 : }
5441 : return GF_OK;
5442 : }
5443 :
5444 19 : GF_Err stsh_box_size(GF_Box *s)
5445 : {
5446 : GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
5447 19 : ptr->size += 4 + (8 * gf_list_count(ptr->entries));
5448 19 : return GF_OK;
5449 : }
5450 :
5451 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
5452 :
5453 :
5454 :
5455 18498 : void stss_box_del(GF_Box *s)
5456 : {
5457 : GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
5458 18498 : if (ptr == NULL) return;
5459 18498 : if (ptr->sampleNumbers) gf_free(ptr->sampleNumbers);
5460 18498 : gf_free(ptr);
5461 : }
5462 :
5463 1072 : GF_Err stss_box_read(GF_Box *s, GF_BitStream *bs)
5464 : {
5465 : u32 i;
5466 : GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
5467 :
5468 1072 : ISOM_DECREASE_SIZE(ptr, 4);
5469 1072 : ptr->nb_entries = gf_bs_read_u32(bs);
5470 1072 : if (ptr->size / 4 < ptr->nb_entries) {
5471 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stss\n", ptr->nb_entries));
5472 : return GF_ISOM_INVALID_FILE;
5473 : }
5474 :
5475 1072 : ptr->alloc_size = ptr->nb_entries;
5476 1072 : ptr->sampleNumbers = (u32 *) gf_malloc( ptr->alloc_size * sizeof(u32));
5477 1072 : if (ptr->sampleNumbers == NULL) return GF_OUT_OF_MEM;
5478 :
5479 19261 : for (i = 0; i < ptr->nb_entries; i++) {
5480 19261 : ptr->sampleNumbers[i] = gf_bs_read_u32(bs);
5481 : }
5482 : return GF_OK;
5483 : }
5484 :
5485 18498 : GF_Box *stss_box_new()
5486 : {
5487 36996 : ISOM_DECL_BOX_ALLOC(GF_SyncSampleBox, GF_ISOM_BOX_TYPE_STSS);
5488 18498 : return (GF_Box*)tmp;
5489 : }
5490 :
5491 :
5492 : #ifndef GPAC_DISABLE_ISOM_WRITE
5493 :
5494 784 : GF_Err stss_box_write(GF_Box *s, GF_BitStream *bs)
5495 : {
5496 : GF_Err e;
5497 : u32 i;
5498 : GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
5499 :
5500 784 : e = gf_isom_full_box_write(s, bs);
5501 784 : if (e) return e;
5502 784 : gf_bs_write_u32(bs, ptr->nb_entries);
5503 12231 : for (i = 0; i < ptr->nb_entries; i++) {
5504 11447 : gf_bs_write_u32(bs, ptr->sampleNumbers[i]);
5505 : }
5506 : return GF_OK;
5507 : }
5508 :
5509 2288 : GF_Err stss_box_size(GF_Box *s)
5510 : {
5511 : GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
5512 2288 : ptr->size += 4 + (4 * ptr->nb_entries);
5513 2288 : return GF_OK;
5514 : }
5515 :
5516 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
5517 :
5518 :
5519 22569 : void stsz_box_del(GF_Box *s)
5520 : {
5521 : GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
5522 22569 : if (ptr == NULL) return;
5523 22569 : if (ptr->sizes) gf_free(ptr->sizes);
5524 22569 : gf_free(ptr);
5525 : }
5526 :
5527 :
5528 2387 : GF_Err stsz_box_read(GF_Box *s, GF_BitStream *bs)
5529 : {
5530 : u32 i, estSize;
5531 : GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
5532 2387 : if (ptr == NULL) return GF_BAD_PARAM;
5533 :
5534 : //support for CompactSizes
5535 2387 : if (s->type == GF_ISOM_BOX_TYPE_STSZ) {
5536 2386 : ISOM_DECREASE_SIZE(ptr, 8);
5537 2386 : ptr->sampleSize = gf_bs_read_u32(bs);
5538 2386 : ptr->sampleCount = gf_bs_read_u32(bs);
5539 : } else {
5540 : //24-reserved
5541 1 : ISOM_DECREASE_SIZE(ptr, 8);
5542 1 : gf_bs_read_int(bs, 24);
5543 1 : i = gf_bs_read_u8(bs);
5544 1 : ptr->sampleCount = gf_bs_read_u32(bs);
5545 : switch (i) {
5546 0 : case 4:
5547 : case 8:
5548 : case 16:
5549 0 : ptr->sampleSize = i;
5550 0 : break;
5551 1 : default:
5552 : //try to fix the file
5553 : //no samples, no parsing pb
5554 1 : if (!ptr->sampleCount) {
5555 1 : ptr->sampleSize = 16;
5556 1 : return GF_OK;
5557 : }
5558 0 : estSize = (u32) (ptr->size) / ptr->sampleCount;
5559 0 : if (!estSize && ((ptr->sampleCount+1)/2 == (ptr->size)) ) {
5560 0 : ptr->sampleSize = 4;
5561 0 : break;
5562 0 : } else if (estSize == 1 || estSize == 2) {
5563 0 : ptr->sampleSize = 8 * estSize;
5564 : } else {
5565 : return GF_ISOM_INVALID_FILE;
5566 : }
5567 : }
5568 : }
5569 2386 : if (s->type == GF_ISOM_BOX_TYPE_STSZ) {
5570 2386 : if (! ptr->sampleSize && ptr->sampleCount) {
5571 1626 : if (ptr->sampleCount > ptr->size / 4) {
5572 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
5573 : return GF_ISOM_INVALID_FILE;
5574 : }
5575 1626 : ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32));
5576 1626 : if (! ptr->sizes) return GF_OUT_OF_MEM;
5577 1626 : ptr->alloc_size = ptr->sampleCount;
5578 880304 : for (i = 0; i < ptr->sampleCount; i++) {
5579 878678 : ptr->sizes[i] = gf_bs_read_u32(bs);
5580 878678 : if (ptr->max_size < ptr->sizes[i])
5581 7825 : ptr->max_size = ptr->sizes[i];
5582 878678 : ptr->total_size += ptr->sizes[i];
5583 878678 : ptr->total_samples++;
5584 : }
5585 : }
5586 : } else {
5587 0 : if (ptr->sampleSize==4) {
5588 0 : if (ptr->sampleCount / 2 > ptr->size) {
5589 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
5590 : return GF_ISOM_INVALID_FILE;
5591 : }
5592 : } else {
5593 0 : if (ptr->sampleCount > ptr->size / (ptr->sampleSize/8)) {
5594 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
5595 : return GF_ISOM_INVALID_FILE;
5596 : }
5597 : }
5598 : //note we could optimize the mem usage by keeping the table compact
5599 : //in memory. But that would complicate both caching and editing
5600 : //we therefore keep all sizes as u32 and uncompress the table
5601 0 : ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32));
5602 0 : if (! ptr->sizes) return GF_OUT_OF_MEM;
5603 0 : ptr->alloc_size = ptr->sampleCount;
5604 :
5605 0 : for (i = 0; i < ptr->sampleCount; ) {
5606 0 : switch (ptr->sampleSize) {
5607 0 : case 4:
5608 0 : ptr->sizes[i] = gf_bs_read_int(bs, 4);
5609 0 : if (i+1 < ptr->sampleCount) {
5610 0 : ptr->sizes[i+1] = gf_bs_read_int(bs, 4);
5611 : } else {
5612 : //0 padding in odd sample count
5613 0 : gf_bs_read_int(bs, 4);
5614 : }
5615 0 : i += 2;
5616 0 : break;
5617 0 : default:
5618 0 : ptr->sizes[i] = gf_bs_read_int(bs, ptr->sampleSize);
5619 0 : i += 1;
5620 0 : break;
5621 : }
5622 0 : if (ptr->max_size < ptr->sizes[i])
5623 0 : ptr->max_size = ptr->sizes[i];
5624 0 : ptr->total_size += ptr->sizes[i];
5625 0 : ptr->total_samples++;
5626 : }
5627 : }
5628 : return GF_OK;
5629 : }
5630 :
5631 22569 : GF_Box *stsz_box_new()
5632 : {
5633 45138 : ISOM_DECL_BOX_ALLOC(GF_SampleSizeBox, 0);
5634 :
5635 : //type is unknown here, can be regular or compact table
5636 22569 : return (GF_Box *)tmp;
5637 : }
5638 :
5639 :
5640 : #ifndef GPAC_DISABLE_ISOM_WRITE
5641 :
5642 1934 : GF_Err stsz_box_write(GF_Box *s, GF_BitStream *bs)
5643 : {
5644 : GF_Err e;
5645 : u32 i;
5646 : GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
5647 :
5648 1934 : e = gf_isom_full_box_write(s, bs);
5649 1934 : if (e) return e;
5650 : //in both versions this is still valid
5651 1934 : if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
5652 1932 : gf_bs_write_u32(bs, ptr->sampleSize);
5653 : } else {
5654 2 : gf_bs_write_u24(bs, 0);
5655 2 : gf_bs_write_u8(bs, ptr->sampleSize);
5656 : }
5657 1934 : gf_bs_write_u32(bs, ptr->sampleCount);
5658 :
5659 1934 : if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
5660 1932 : if (! ptr->sampleSize) {
5661 533854 : for (i = 0; i < ptr->sampleCount; i++) {
5662 533854 : gf_bs_write_u32(bs, ptr->sizes ? ptr->sizes[i] : 0);
5663 : }
5664 : }
5665 : } else {
5666 13 : for (i = 0; i < ptr->sampleCount; ) {
5667 11 : switch (ptr->sampleSize) {
5668 0 : case 4:
5669 0 : gf_bs_write_int(bs, ptr->sizes[i], 4);
5670 0 : if (i+1 < ptr->sampleCount) {
5671 0 : gf_bs_write_int(bs, ptr->sizes[i+1], 4);
5672 : } else {
5673 : //0 padding in odd sample count
5674 0 : gf_bs_write_int(bs, 0, 4);
5675 : }
5676 0 : i += 2;
5677 0 : break;
5678 11 : default:
5679 11 : gf_bs_write_int(bs, ptr->sizes[i], ptr->sampleSize);
5680 11 : i += 1;
5681 11 : break;
5682 : }
5683 : }
5684 : }
5685 : return GF_OK;
5686 : }
5687 :
5688 4883 : GF_Err stsz_box_size(GF_Box *s)
5689 : {
5690 : u32 i, fieldSize, size;
5691 : GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
5692 :
5693 4883 : ptr->size += 8;
5694 4883 : if (!ptr->sampleCount) return GF_OK;
5695 :
5696 : //regular table
5697 4419 : if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
5698 4416 : if (ptr->sampleSize) return GF_OK;
5699 3506 : ptr->size += (4 * ptr->sampleCount);
5700 3506 : return GF_OK;
5701 : }
5702 :
5703 : fieldSize = 4;
5704 3 : size = ptr->sizes[0];
5705 :
5706 36 : for (i=0; i < ptr->sampleCount; i++) {
5707 33 : if (ptr->sizes[i] <= 0xF) continue;
5708 : //switch to 8-bit table
5709 15 : else if (ptr->sizes[i] <= 0xFF) {
5710 : fieldSize = 8;
5711 : }
5712 : //switch to 16-bit table
5713 0 : else if (ptr->sizes[i] <= 0xFFFF) {
5714 : fieldSize = 16;
5715 : }
5716 : //switch to 32-bit table
5717 : else {
5718 : fieldSize = 32;
5719 : }
5720 :
5721 : //check the size
5722 15 : if (size != ptr->sizes[i]) size = 0;
5723 : }
5724 : //if all samples are of the same size, switch to regular (more compact)
5725 3 : if (size) {
5726 0 : ptr->type = GF_ISOM_BOX_TYPE_STSZ;
5727 0 : ptr->sampleSize = size;
5728 0 : gf_free(ptr->sizes);
5729 0 : ptr->sizes = NULL;
5730 : }
5731 :
5732 3 : if (fieldSize == 32) {
5733 : //oops, doesn't fit in a compact table
5734 0 : ptr->type = GF_ISOM_BOX_TYPE_STSZ;
5735 0 : ptr->size += (4 * ptr->sampleCount);
5736 0 : return GF_OK;
5737 : }
5738 :
5739 : //make sure we are a compact table (no need to change the mem representation)
5740 3 : ptr->type = GF_ISOM_BOX_TYPE_STZ2;
5741 3 : ptr->sampleSize = fieldSize;
5742 3 : if (fieldSize == 4) {
5743 : //do not forget the 0 padding field for odd count
5744 0 : ptr->size += (ptr->sampleCount + 1) / 2;
5745 : } else {
5746 3 : ptr->size += (ptr->sampleCount) * (fieldSize/8);
5747 : }
5748 : return GF_OK;
5749 : }
5750 :
5751 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
5752 :
5753 :
5754 22566 : void stts_box_del(GF_Box *s)
5755 : {
5756 : GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
5757 22566 : if (ptr->entries) gf_free(ptr->entries);
5758 22566 : gf_free(ptr);
5759 22566 : }
5760 :
5761 :
5762 2386 : GF_Err stts_box_read(GF_Box *s, GF_BitStream *bs)
5763 : {
5764 : u32 i;
5765 : GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
5766 :
5767 : #ifndef GPAC_DISABLE_ISOM_WRITE
5768 2386 : ptr->w_LastDTS = 0;
5769 : #endif
5770 :
5771 2386 : ISOM_DECREASE_SIZE(ptr, 4);
5772 2386 : ptr->nb_entries = gf_bs_read_u32(bs);
5773 2386 : if (ptr->size / 8 < ptr->nb_entries) {
5774 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stts\n", ptr->nb_entries));
5775 : return GF_ISOM_INVALID_FILE;
5776 : }
5777 :
5778 2386 : ptr->alloc_size = ptr->nb_entries;
5779 2386 : ptr->entries = gf_malloc(sizeof(GF_SttsEntry)*ptr->alloc_size);
5780 2386 : if (!ptr->entries) return GF_OUT_OF_MEM;
5781 :
5782 18723 : for (i=0; i<ptr->nb_entries; i++) {
5783 18723 : ptr->entries[i].sampleCount = gf_bs_read_u32(bs);
5784 18723 : ptr->entries[i].sampleDelta = gf_bs_read_u32(bs);
5785 : #ifndef GPAC_DISABLE_ISOM_WRITE
5786 18723 : ptr->w_currentSampleNum += ptr->entries[i].sampleCount;
5787 18723 : ptr->w_LastDTS += (u64)ptr->entries[i].sampleCount * ptr->entries[i].sampleDelta;
5788 : #endif
5789 18723 : if (ptr->max_ts_delta<ptr->entries[i].sampleDelta)
5790 2181 : ptr->max_ts_delta = ptr->entries[i].sampleDelta;
5791 :
5792 18723 : if (!ptr->entries[i].sampleDelta) {
5793 166 : if ((i+1<ptr->nb_entries) ) {
5794 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Found stts entry with sample_delta=0 - forbidden ! Fixing to 1\n" ));
5795 0 : ptr->entries[i].sampleDelta = 1;
5796 166 : } else if (ptr->entries[i].sampleCount>1) {
5797 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] more than one stts entry at the end of the track with sample_delta=0 - forbidden ! Fixing to 1\n" ));
5798 0 : ptr->entries[i].sampleDelta = 1;
5799 : }
5800 : }
5801 : //cf issue 1644: some media streams may have sample duration > 2^31 (ttml mostly), we cannot patch this
5802 : //for now we disable the check, one opt could be to have the check only for some media types, or only for the first entry
5803 : #if 0
5804 : else if ((s32) ptr->entries[i].sampleDelta < 0) {
5805 : 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 ));
5806 : ptr->entries[i].sampleDelta = 1;
5807 : }
5808 : #endif
5809 :
5810 : }
5811 2386 : ISOM_DECREASE_SIZE(ptr, ptr->nb_entries*8);
5812 :
5813 : //remove the last sample delta.
5814 : #ifndef GPAC_DISABLE_ISOM_WRITE
5815 2386 : if (ptr->nb_entries) ptr->w_LastDTS -= ptr->entries[ptr->nb_entries-1].sampleDelta;
5816 : #endif
5817 : return GF_OK;
5818 : }
5819 :
5820 22566 : GF_Box *stts_box_new()
5821 : {
5822 45132 : ISOM_DECL_BOX_ALLOC(GF_TimeToSampleBox, GF_ISOM_BOX_TYPE_STTS);
5823 22566 : return (GF_Box *)tmp;
5824 : }
5825 :
5826 :
5827 : #ifndef GPAC_DISABLE_ISOM_WRITE
5828 :
5829 1933 : GF_Err stts_box_write(GF_Box *s, GF_BitStream *bs)
5830 : {
5831 : GF_Err e;
5832 : u32 i;
5833 : GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
5834 :
5835 1933 : e = gf_isom_full_box_write(s, bs);
5836 1933 : if (e) return e;
5837 1933 : gf_bs_write_u32(bs, ptr->nb_entries);
5838 15767 : for (i=0; i<ptr->nb_entries; i++) {
5839 13834 : gf_bs_write_u32(bs, ptr->entries[i].sampleCount);
5840 13834 : gf_bs_write_u32(bs, ptr->entries[i].sampleDelta);
5841 : }
5842 : return GF_OK;
5843 : }
5844 :
5845 4882 : GF_Err stts_box_size(GF_Box *s)
5846 : {
5847 : GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
5848 4882 : ptr->size += 4 + (8 * ptr->nb_entries);
5849 4882 : return GF_OK;
5850 : }
5851 :
5852 :
5853 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
5854 :
5855 :
5856 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
5857 :
5858 8829 : void tfhd_box_del(GF_Box *s)
5859 : {
5860 : GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
5861 8829 : if (ptr == NULL) return;
5862 8829 : gf_free(ptr);
5863 : }
5864 :
5865 4243 : GF_Err tfhd_box_read(GF_Box *s, GF_BitStream *bs)
5866 : {
5867 : GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
5868 :
5869 4243 : ISOM_DECREASE_SIZE(ptr, 4);
5870 4243 : ptr->trackID = gf_bs_read_u32(bs);
5871 :
5872 : //The rest depends on the flags
5873 4243 : if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) {
5874 51 : ISOM_DECREASE_SIZE(ptr, 8);
5875 51 : ptr->base_data_offset = gf_bs_read_u64(bs);
5876 : }
5877 4243 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) {
5878 199 : ISOM_DECREASE_SIZE(ptr, 4);
5879 199 : ptr->sample_desc_index = gf_bs_read_u32(bs);
5880 : }
5881 4243 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) {
5882 266 : ISOM_DECREASE_SIZE(ptr, 4);
5883 266 : ptr->def_sample_duration = gf_bs_read_u32(bs);
5884 : }
5885 4243 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) {
5886 174 : ISOM_DECREASE_SIZE(ptr, 4);
5887 174 : ptr->def_sample_size = gf_bs_read_u32(bs);
5888 : }
5889 4243 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) {
5890 421 : ISOM_DECREASE_SIZE(ptr, 4);
5891 421 : ptr->def_sample_flags = gf_bs_read_u32(bs);
5892 : }
5893 : return GF_OK;
5894 : }
5895 :
5896 8829 : GF_Box *tfhd_box_new()
5897 : {
5898 17658 : ISOM_DECL_BOX_ALLOC(GF_TrackFragmentHeaderBox, GF_ISOM_BOX_TYPE_TFHD);
5899 : //NO FLAGS SET BY DEFAULT
5900 8829 : return (GF_Box *)tmp;
5901 : }
5902 :
5903 :
5904 :
5905 : #ifndef GPAC_DISABLE_ISOM_WRITE
5906 :
5907 :
5908 3939 : GF_Err tfhd_box_write(GF_Box *s, GF_BitStream *bs)
5909 : {
5910 : GF_Err e;
5911 : GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *) s;
5912 3939 : if (!s) return GF_BAD_PARAM;
5913 :
5914 3939 : e = gf_isom_full_box_write(s, bs);
5915 3939 : if (e) return e;
5916 3939 : gf_bs_write_u32(bs, ptr->trackID);
5917 :
5918 : //The rest depends on the flags
5919 3939 : if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) {
5920 97 : gf_bs_write_u64(bs, ptr->base_data_offset);
5921 : }
5922 3939 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) {
5923 306 : gf_bs_write_u32(bs, ptr->sample_desc_index);
5924 : }
5925 3939 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) {
5926 374 : gf_bs_write_u32(bs, ptr->def_sample_duration);
5927 : }
5928 3939 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) {
5929 179 : gf_bs_write_u32(bs, ptr->def_sample_size);
5930 : }
5931 3939 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) {
5932 348 : gf_bs_write_u32(bs, ptr->def_sample_flags);
5933 : }
5934 : return GF_OK;
5935 : }
5936 :
5937 12092 : GF_Err tfhd_box_size(GF_Box *s)
5938 : {
5939 : GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
5940 12092 : ptr->size += 4;
5941 :
5942 : //The rest depends on the flags
5943 12092 : if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) ptr->size += 8;
5944 12092 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) ptr->size += 4;
5945 12092 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) ptr->size += 4;
5946 12092 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) ptr->size += 4;
5947 12092 : if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) ptr->size += 4;
5948 12092 : return GF_OK;
5949 : }
5950 :
5951 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
5952 :
5953 : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
5954 :
5955 :
5956 121 : void tims_box_del(GF_Box *s)
5957 : {
5958 : GF_TSHintEntryBox *tims = (GF_TSHintEntryBox *)s;
5959 121 : gf_free(tims);
5960 121 : }
5961 :
5962 46 : GF_Err tims_box_read(GF_Box *s, GF_BitStream *bs)
5963 : {
5964 : GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s;
5965 46 : ISOM_DECREASE_SIZE(ptr, 4);
5966 46 : ptr->timeScale = gf_bs_read_u32(bs);
5967 46 : return GF_OK;
5968 : }
5969 :
5970 121 : GF_Box *tims_box_new()
5971 : {
5972 242 : ISOM_DECL_BOX_ALLOC(GF_TSHintEntryBox, GF_ISOM_BOX_TYPE_TIMS);
5973 121 : return (GF_Box *)tmp;
5974 : }
5975 :
5976 : #ifndef GPAC_DISABLE_ISOM_WRITE
5977 :
5978 74 : GF_Err tims_box_write(GF_Box *s, GF_BitStream *bs)
5979 : {
5980 : GF_Err e;
5981 : GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s;
5982 74 : if (ptr == NULL) return GF_BAD_PARAM;
5983 74 : e = gf_isom_box_write_header(s, bs);
5984 74 : if (e) return e;
5985 74 : gf_bs_write_u32(bs, ptr->timeScale);
5986 74 : return GF_OK;
5987 : }
5988 :
5989 220 : GF_Err tims_box_size(GF_Box *s)
5990 : {
5991 220 : s->size += 4;
5992 220 : return GF_OK;
5993 : }
5994 :
5995 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
5996 :
5997 :
5998 4126 : void tkhd_box_del(GF_Box *s)
5999 : {
6000 : GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
6001 4126 : if (ptr == NULL) return;
6002 4126 : gf_free(ptr);
6003 4126 : return;
6004 : }
6005 :
6006 :
6007 3106 : GF_Err tkhd_box_read(GF_Box *s, GF_BitStream *bs)
6008 : {
6009 : GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
6010 :
6011 3106 : if (ptr->version == 1) {
6012 0 : ISOM_DECREASE_SIZE(ptr, 32);
6013 0 : ptr->creationTime = gf_bs_read_u64(bs);
6014 0 : ptr->modificationTime = gf_bs_read_u64(bs);
6015 0 : ptr->trackID = gf_bs_read_u32(bs);
6016 0 : ptr->reserved1 = gf_bs_read_u32(bs);
6017 0 : ptr->duration = gf_bs_read_u64(bs);
6018 : } else {
6019 3106 : ISOM_DECREASE_SIZE(ptr, 20);
6020 3106 : ptr->creationTime = gf_bs_read_u32(bs);
6021 3106 : ptr->modificationTime = gf_bs_read_u32(bs);
6022 3106 : ptr->trackID = gf_bs_read_u32(bs);
6023 3106 : ptr->reserved1 = gf_bs_read_u32(bs);
6024 3106 : ptr->duration = gf_bs_read_u32(bs);
6025 : }
6026 3106 : ptr->initial_duration = ptr->duration;
6027 :
6028 3106 : ISOM_DECREASE_SIZE(ptr, 60);
6029 3106 : ptr->reserved2[0] = gf_bs_read_u32(bs);
6030 3106 : ptr->reserved2[1] = gf_bs_read_u32(bs);
6031 3106 : ptr->layer = gf_bs_read_u16(bs);
6032 3106 : ptr->alternate_group = gf_bs_read_u16(bs);
6033 3106 : ptr->volume = gf_bs_read_u16(bs);
6034 3106 : ptr->reserved3 = gf_bs_read_u16(bs);
6035 3106 : ptr->matrix[0] = gf_bs_read_u32(bs);
6036 3106 : ptr->matrix[1] = gf_bs_read_u32(bs);
6037 3106 : ptr->matrix[2] = gf_bs_read_u32(bs);
6038 3106 : ptr->matrix[3] = gf_bs_read_u32(bs);
6039 3106 : ptr->matrix[4] = gf_bs_read_u32(bs);
6040 3106 : ptr->matrix[5] = gf_bs_read_u32(bs);
6041 3106 : ptr->matrix[6] = gf_bs_read_u32(bs);
6042 3106 : ptr->matrix[7] = gf_bs_read_u32(bs);
6043 3106 : ptr->matrix[8] = gf_bs_read_u32(bs);
6044 3106 : ptr->width = gf_bs_read_u32(bs);
6045 3106 : ptr->height = gf_bs_read_u32(bs);
6046 3106 : return GF_OK;
6047 : }
6048 :
6049 4126 : GF_Box *tkhd_box_new()
6050 : {
6051 8252 : ISOM_DECL_BOX_ALLOC(GF_TrackHeaderBox, GF_ISOM_BOX_TYPE_TKHD);
6052 4126 : tmp->matrix[0] = 0x00010000;
6053 4126 : tmp->matrix[4] = 0x00010000;
6054 4126 : tmp->matrix[8] = 0x40000000;
6055 4126 : return (GF_Box *)tmp;
6056 : }
6057 :
6058 :
6059 :
6060 : #ifndef GPAC_DISABLE_ISOM_WRITE
6061 :
6062 3176 : GF_Err tkhd_box_write(GF_Box *s, GF_BitStream *bs)
6063 : {
6064 : GF_Err e;
6065 : GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
6066 :
6067 3176 : e = gf_isom_full_box_write(s, bs);
6068 3176 : if (e) return e;
6069 3176 : if (ptr->version == 1) {
6070 0 : gf_bs_write_u64(bs, ptr->creationTime);
6071 0 : gf_bs_write_u64(bs, ptr->modificationTime);
6072 0 : gf_bs_write_u32(bs, ptr->trackID);
6073 0 : gf_bs_write_u32(bs, ptr->reserved1);
6074 0 : gf_bs_write_u64(bs, ptr->duration);
6075 : } else {
6076 3176 : gf_bs_write_u32(bs, (u32) ptr->creationTime);
6077 3176 : gf_bs_write_u32(bs, (u32) ptr->modificationTime);
6078 3176 : gf_bs_write_u32(bs, ptr->trackID);
6079 3176 : gf_bs_write_u32(bs, ptr->reserved1);
6080 3176 : gf_bs_write_u32(bs, (u32) ptr->duration);
6081 : }
6082 3176 : gf_bs_write_u32(bs, ptr->reserved2[0]);
6083 3176 : gf_bs_write_u32(bs, ptr->reserved2[1]);
6084 3176 : gf_bs_write_u16(bs, ptr->layer);
6085 3176 : gf_bs_write_u16(bs, ptr->alternate_group);
6086 3176 : gf_bs_write_u16(bs, ptr->volume);
6087 3176 : gf_bs_write_u16(bs, ptr->reserved3);
6088 3176 : gf_bs_write_u32(bs, ptr->matrix[0]);
6089 3176 : gf_bs_write_u32(bs, ptr->matrix[1]);
6090 3176 : gf_bs_write_u32(bs, ptr->matrix[2]);
6091 3176 : gf_bs_write_u32(bs, ptr->matrix[3]);
6092 3176 : gf_bs_write_u32(bs, ptr->matrix[4]);
6093 3176 : gf_bs_write_u32(bs, ptr->matrix[5]);
6094 3176 : gf_bs_write_u32(bs, ptr->matrix[6]);
6095 3176 : gf_bs_write_u32(bs, ptr->matrix[7]);
6096 3176 : gf_bs_write_u32(bs, ptr->matrix[8]);
6097 3176 : gf_bs_write_u32(bs, ptr->width);
6098 3176 : gf_bs_write_u32(bs, ptr->height);
6099 3176 : return GF_OK;
6100 : }
6101 :
6102 6125 : GF_Err tkhd_box_size(GF_Box *s)
6103 : {
6104 : GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
6105 :
6106 6125 : if (ptr->duration==(u64) -1) ptr->version = 0;
6107 6125 : else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
6108 6125 : ptr->size += (ptr->version == 1) ? 32 : 20;
6109 6125 : ptr->size += 60;
6110 6125 : return GF_OK;
6111 : }
6112 :
6113 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
6114 :
6115 :
6116 :
6117 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
6118 :
6119 8829 : void traf_box_del(GF_Box *s)
6120 : {
6121 : GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
6122 8829 : if (ptr == NULL) return;
6123 8829 : if (ptr->sub_samples) gf_list_del(ptr->sub_samples);
6124 8829 : gf_list_del(ptr->TrackRuns);
6125 8829 : if (ptr->sampleGroups) gf_list_del(ptr->sampleGroups);
6126 8829 : if (ptr->sampleGroupsDescription) gf_list_del(ptr->sampleGroupsDescription);
6127 8829 : if (ptr->sai_sizes) gf_list_del(ptr->sai_sizes);
6128 8829 : if (ptr->sai_offsets) gf_list_del(ptr->sai_offsets);
6129 8829 : gf_free(ptr);
6130 : }
6131 :
6132 13778 : GF_Err traf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
6133 : {
6134 : GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
6135 :
6136 13778 : switch (a->type) {
6137 4242 : case GF_ISOM_BOX_TYPE_TFHD:
6138 4242 : BOX_FIELD_ASSIGN(tfhd, GF_TrackFragmentHeaderBox)
6139 4242 : return GF_OK;
6140 4230 : case GF_ISOM_BOX_TYPE_TRUN:
6141 4230 : BOX_FIELD_LIST_ASSIGN(TrackRuns)
6142 : return GF_OK;
6143 31 : case GF_ISOM_BOX_TYPE_SDTP:
6144 31 : BOX_FIELD_ASSIGN(sdtp, GF_SampleDependencyTypeBox)
6145 31 : return GF_OK;
6146 4012 : case GF_ISOM_BOX_TYPE_TFDT:
6147 4012 : BOX_FIELD_ASSIGN(tfdt, GF_TFBaseMediaDecodeTimeBox)
6148 4012 : return GF_OK;
6149 0 : case GF_ISOM_BOX_TYPE_SUBS:
6150 0 : BOX_FIELD_LIST_ASSIGN(sub_samples)
6151 : return GF_OK;
6152 98 : case GF_ISOM_BOX_TYPE_SBGP:
6153 : case GF_ISOM_BOX_TYPE_CSGP:
6154 98 : BOX_FIELD_LIST_ASSIGN(sampleGroups)
6155 : return GF_OK;
6156 28 : case GF_ISOM_BOX_TYPE_SGPD:
6157 28 : BOX_FIELD_LIST_ASSIGN(sampleGroupsDescription)
6158 : return GF_OK;
6159 490 : case GF_ISOM_BOX_TYPE_SAIZ:
6160 490 : BOX_FIELD_LIST_ASSIGN(sai_sizes)
6161 : return GF_OK;
6162 490 : case GF_ISOM_BOX_TYPE_SAIO:
6163 490 : BOX_FIELD_LIST_ASSIGN(sai_offsets)
6164 : return GF_OK;
6165 : //we will throw an error if both PIFF_PSEC and SENC are found. Not such files seen yet
6166 12 : case GF_ISOM_BOX_TYPE_UUID:
6167 12 : if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_PSEC) {
6168 3 : BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
6169 : if (!is_rem)
6170 3 : ptr->sample_encryption->traf = ptr;
6171 3 : return GF_OK;
6172 9 : } else if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_TFXD) {
6173 9 : BOX_FIELD_ASSIGN(tfxd, GF_MSSTimeExtBox)
6174 9 : return GF_OK;
6175 0 : } else if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_TFRF) {
6176 0 : BOX_FIELD_ASSIGN(tfrf, GF_MSSTimeRefBox)
6177 0 : return GF_OK;
6178 : } else {
6179 : return GF_OK;
6180 : }
6181 145 : case GF_ISOM_BOX_TYPE_SENC:
6182 145 : BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
6183 : if (!is_rem)
6184 145 : ptr->sample_encryption->traf = ptr;
6185 145 : return GF_OK;
6186 : }
6187 : return GF_OK;
6188 : }
6189 :
6190 :
6191 4243 : GF_Err traf_box_read(GF_Box *s, GF_BitStream *bs)
6192 : {
6193 : GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
6194 4243 : GF_Err e = gf_isom_box_array_read(s, bs);
6195 4243 : if (e) return e;
6196 :
6197 4243 : if (!ptr->tfhd) {
6198 1 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing TrackFragmentHeaderBox \n"));
6199 : return GF_ISOM_INVALID_FILE;
6200 : }
6201 : return GF_OK;
6202 : }
6203 :
6204 8829 : GF_Box *traf_box_new()
6205 : {
6206 17658 : ISOM_DECL_BOX_ALLOC(GF_TrackFragmentBox, GF_ISOM_BOX_TYPE_TRAF);
6207 8829 : tmp->TrackRuns = gf_list_new();
6208 8829 : return (GF_Box *)tmp;
6209 : }
6210 :
6211 :
6212 : #ifndef GPAC_DISABLE_ISOM_WRITE
6213 :
6214 3939 : GF_Err traf_box_write(GF_Box *s, GF_BitStream *bs)
6215 : {
6216 3939 : return gf_isom_box_write_header(s, bs);
6217 : }
6218 :
6219 12092 : GF_Err traf_box_size(GF_Box *s)
6220 : {
6221 12092 : u32 pos=0;
6222 : GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *) s;
6223 :
6224 : //Header first
6225 12092 : gf_isom_check_position(s, (GF_Box *)ptr->tfhd, &pos);
6226 12092 : gf_isom_check_position_list(s, ptr->sub_samples, &pos);
6227 :
6228 12092 : gf_isom_check_position(s, (GF_Box *)ptr->tfdt, &pos);
6229 :
6230 : //cmaf-like
6231 12092 : if (ptr->truns_first) {
6232 0 : gf_isom_check_position_list(s, ptr->TrackRuns, &pos);
6233 0 : gf_isom_check_position(s, (GF_Box *)ptr->sample_encryption, &pos);
6234 0 : gf_isom_check_position_list(s, ptr->sai_sizes, &pos);
6235 0 : gf_isom_check_position_list(s, ptr->sai_offsets, &pos);
6236 0 : gf_isom_check_position_list(s, ptr->sampleGroupsDescription, &pos);
6237 0 : gf_isom_check_position_list(s, ptr->sampleGroups, &pos);
6238 : //subsamples will be last
6239 : } else {
6240 12092 : gf_isom_check_position_list(s, ptr->sampleGroupsDescription, &pos);
6241 12092 : gf_isom_check_position_list(s, ptr->sampleGroups, &pos);
6242 12092 : gf_isom_check_position_list(s, ptr->sai_sizes, &pos);
6243 12092 : gf_isom_check_position_list(s, ptr->sai_offsets, &pos);
6244 12092 : gf_isom_check_position(s, (GF_Box *)ptr->sample_encryption, &pos);
6245 12092 : gf_isom_check_position_list(s, ptr->TrackRuns, &pos);
6246 : }
6247 :
6248 : //when sdtp is present (smooth-like) write it after the trun box
6249 12092 : gf_isom_check_position(s, (GF_Box *)ptr->sdtp, &pos);
6250 :
6251 : //tfxd should be last ...
6252 12092 : if (ptr->tfxd)
6253 0 : gf_isom_check_position(s, (GF_Box *)ptr->tfxd, &pos);
6254 12092 : return GF_OK;
6255 : }
6256 :
6257 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
6258 :
6259 :
6260 12 : GF_Box *tfxd_box_new()
6261 : {
6262 24 : ISOM_DECL_BOX_ALLOC(GF_MSSTimeExtBox, GF_ISOM_BOX_TYPE_UUID);
6263 12 : tmp->internal_4cc = GF_ISOM_BOX_UUID_TFXD;
6264 12 : return (GF_Box *)tmp;
6265 : }
6266 :
6267 12 : void tfxd_box_del(GF_Box *s)
6268 : {
6269 12 : gf_free(s);
6270 12 : }
6271 :
6272 :
6273 10 : GF_Err tfxd_box_read(GF_Box *s, GF_BitStream *bs)
6274 : {
6275 : GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox *)s;
6276 10 : ISOM_DECREASE_SIZE(ptr, 4);
6277 10 : ptr->version = gf_bs_read_u8(bs);
6278 10 : ptr->flags = gf_bs_read_u24(bs);
6279 :
6280 10 : if (ptr->version == 0x01) {
6281 9 : ISOM_DECREASE_SIZE(ptr, 16);
6282 9 : ptr->absolute_time_in_track_timescale = gf_bs_read_u64(bs);
6283 9 : ptr->fragment_duration_in_track_timescale = gf_bs_read_u64(bs);
6284 : } else {
6285 1 : ISOM_DECREASE_SIZE(ptr, 8);
6286 1 : ptr->absolute_time_in_track_timescale = gf_bs_read_u32(bs);
6287 1 : ptr->fragment_duration_in_track_timescale = gf_bs_read_u32(bs);
6288 : }
6289 :
6290 : return GF_OK;
6291 : }
6292 :
6293 : #ifndef GPAC_DISABLE_ISOM_WRITE
6294 :
6295 1 : GF_Err tfxd_box_write(GF_Box *s, GF_BitStream *bs)
6296 : {
6297 : GF_Err e;
6298 : GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox*)s;
6299 1 : e = gf_isom_box_write_header(s, bs);
6300 1 : if (e) return e;
6301 :
6302 1 : gf_bs_write_u8(bs, ptr->version);
6303 1 : gf_bs_write_u24(bs, 0);
6304 1 : if (ptr->version) {
6305 0 : gf_bs_write_u64(bs, ptr->absolute_time_in_track_timescale);
6306 0 : gf_bs_write_u64(bs, ptr->fragment_duration_in_track_timescale);
6307 : } else {
6308 1 : gf_bs_write_u32(bs, (u32) ptr->absolute_time_in_track_timescale);
6309 1 : gf_bs_write_u32(bs, (u32) ptr->fragment_duration_in_track_timescale);
6310 : }
6311 : return GF_OK;
6312 : }
6313 :
6314 1 : GF_Err tfxd_box_size(GF_Box *s)
6315 : {
6316 : GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox*)s;
6317 1 : s->size += 4 + (ptr->version ? 16 : 8);
6318 1 : return GF_OK;
6319 : }
6320 : #endif //GPAC_DISABLE_ISOM_WRITE
6321 :
6322 :
6323 :
6324 3 : GF_Box *tfrf_box_new()
6325 : {
6326 6 : ISOM_DECL_BOX_ALLOC(GF_MSSTimeRefBox, GF_ISOM_BOX_TYPE_UUID);
6327 3 : tmp->internal_4cc = GF_ISOM_BOX_UUID_TFRF;
6328 3 : return (GF_Box *)tmp;
6329 : }
6330 :
6331 3 : void tfrf_box_del(GF_Box *s)
6332 : {
6333 : GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox *)s;
6334 3 : if (ptr->frags) gf_free(ptr->frags);
6335 3 : gf_free(s);
6336 3 : }
6337 :
6338 :
6339 0 : GF_Err tfrf_box_read(GF_Box *s, GF_BitStream *bs)
6340 : {
6341 : u32 i;
6342 : GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox *)s;
6343 0 : ISOM_DECREASE_SIZE(ptr, 5);
6344 0 : ptr->version = gf_bs_read_u8(bs);
6345 0 : ptr->flags = gf_bs_read_u24(bs);
6346 0 : ptr->frags_count = gf_bs_read_u8(bs);
6347 0 : ptr->frags = gf_malloc(sizeof(GF_MSSTimeEntry) * ptr->frags_count);
6348 0 : if (!ptr->frags) return GF_OUT_OF_MEM;
6349 :
6350 0 : for (i=0; i<ptr->frags_count; i++) {
6351 0 : if (ptr->version == 0x01) {
6352 0 : ISOM_DECREASE_SIZE(ptr, 16);
6353 0 : ptr->frags[i].absolute_time_in_track_timescale = gf_bs_read_u64(bs);
6354 0 : ptr->frags[i].fragment_duration_in_track_timescale = gf_bs_read_u64(bs);
6355 : } else {
6356 0 : ISOM_DECREASE_SIZE(ptr, 8);
6357 0 : ptr->frags[i].absolute_time_in_track_timescale = gf_bs_read_u32(bs);
6358 0 : ptr->frags[i].fragment_duration_in_track_timescale = gf_bs_read_u32(bs);
6359 : }
6360 : }
6361 : return GF_OK;
6362 : }
6363 :
6364 : #ifndef GPAC_DISABLE_ISOM_WRITE
6365 :
6366 2 : GF_Err tfrf_box_write(GF_Box *s, GF_BitStream *bs)
6367 : {
6368 : GF_Err e;
6369 : u32 i;
6370 : GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox*)s;
6371 2 : e = gf_isom_box_write_header(s, bs);
6372 2 : if (e) return e;
6373 :
6374 2 : gf_bs_write_u8(bs, ptr->version);
6375 2 : gf_bs_write_u24(bs, 0);
6376 2 : gf_bs_write_u8(bs, ptr->frags_count);
6377 2 : for (i=0; i<ptr->frags_count; i++) {
6378 0 : if (ptr->version==0x01) {
6379 0 : gf_bs_write_u64(bs, ptr->frags[i].absolute_time_in_track_timescale);
6380 0 : gf_bs_write_u64(bs, ptr->frags[i].fragment_duration_in_track_timescale);
6381 : } else {
6382 0 : gf_bs_write_u32(bs, (u32) ptr->frags[i].absolute_time_in_track_timescale);
6383 0 : gf_bs_write_u32(bs, (u32) ptr->frags[i].fragment_duration_in_track_timescale);
6384 : }
6385 : }
6386 : return GF_OK;
6387 : }
6388 :
6389 2 : GF_Err tfrf_box_size(GF_Box *s)
6390 : {
6391 : GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox*)s;
6392 2 : s->size += 5;
6393 2 : if (ptr->version) s->size += 16 * ptr->frags_count;
6394 2 : else s->size += 8 * ptr->frags_count;
6395 2 : return GF_OK;
6396 : }
6397 : #endif //GPAC_DISABLE_ISOM_WRITE
6398 :
6399 : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
6400 :
6401 :
6402 4125 : void trak_box_del(GF_Box *s)
6403 : {
6404 : #ifndef GPAC_DISABLE_ISOM_WRITE
6405 : GF_TrackBox *ptr = (GF_TrackBox *)s;
6406 4125 : if (ptr->chunk_cache)
6407 0 : gf_bs_del(ptr->chunk_cache);
6408 : #endif
6409 4125 : gf_free(s);
6410 4125 : }
6411 :
6412 3106 : static void gf_isom_check_sample_desc(GF_TrackBox *trak)
6413 : {
6414 : GF_BitStream *bs;
6415 : GF_UnknownBox *a;
6416 : u32 i;
6417 : GF_Err e;
6418 : GF_SampleTableBox *stbl;
6419 :
6420 3106 : if (!trak->Media || !trak->Media->information) {
6421 1 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no media box !\n" ));
6422 1 : return;
6423 : }
6424 3105 : if (!trak->Media->information->sampleTable) {
6425 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample table !\n" ));
6426 0 : trak->Media->information->sampleTable = (GF_SampleTableBox *) gf_isom_box_new_parent(&trak->Media->information->child_boxes, GF_ISOM_BOX_TYPE_STBL);
6427 : }
6428 3105 : stbl = trak->Media->information->sampleTable;
6429 :
6430 3105 : if (!stbl->SampleDescription) {
6431 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample description box !\n" ));
6432 0 : stbl->SampleDescription = (GF_SampleDescriptionBox *) gf_isom_box_new_parent(&stbl->child_boxes, GF_ISOM_BOX_TYPE_STSD);
6433 : return;
6434 : }
6435 :
6436 3105 : i=0;
6437 5605 : while ((a = (GF_UnknownBox*)gf_list_enum(trak->Media->information->sampleTable->SampleDescription->child_boxes, &i))) {
6438 2500 : switch (a->type) {
6439 2461 : case GF_ISOM_BOX_TYPE_MP4S:
6440 : case GF_ISOM_BOX_TYPE_ENCS:
6441 : case GF_ISOM_BOX_TYPE_MP4A:
6442 : case GF_ISOM_BOX_TYPE_ENCA:
6443 : case GF_ISOM_BOX_TYPE_MP4V:
6444 : case GF_ISOM_BOX_TYPE_ENCV:
6445 : case GF_ISOM_BOX_TYPE_RESV:
6446 : case GF_ISOM_SUBTYPE_3GP_AMR:
6447 : case GF_ISOM_SUBTYPE_3GP_AMR_WB:
6448 : case GF_ISOM_SUBTYPE_3GP_EVRC:
6449 : case GF_ISOM_SUBTYPE_3GP_QCELP:
6450 : case GF_ISOM_SUBTYPE_3GP_SMV:
6451 : case GF_ISOM_SUBTYPE_3GP_H263:
6452 : case GF_ISOM_BOX_TYPE_GHNT:
6453 : case GF_ISOM_BOX_TYPE_RTP_STSD:
6454 : case GF_ISOM_BOX_TYPE_SRTP_STSD:
6455 : case GF_ISOM_BOX_TYPE_FDP_STSD:
6456 : case GF_ISOM_BOX_TYPE_RRTP_STSD:
6457 : case GF_ISOM_BOX_TYPE_RTCP_STSD:
6458 : case GF_ISOM_BOX_TYPE_METX:
6459 : case GF_ISOM_BOX_TYPE_METT:
6460 : case GF_ISOM_BOX_TYPE_STXT:
6461 : case GF_ISOM_BOX_TYPE_AVC1:
6462 : case GF_ISOM_BOX_TYPE_AVC2:
6463 : case GF_ISOM_BOX_TYPE_AVC3:
6464 : case GF_ISOM_BOX_TYPE_AVC4:
6465 : case GF_ISOM_BOX_TYPE_SVC1:
6466 : case GF_ISOM_BOX_TYPE_MVC1:
6467 : case GF_ISOM_BOX_TYPE_HVC1:
6468 : case GF_ISOM_BOX_TYPE_HEV1:
6469 : case GF_ISOM_BOX_TYPE_HVC2:
6470 : case GF_ISOM_BOX_TYPE_HEV2:
6471 : case GF_ISOM_BOX_TYPE_HVT1:
6472 : case GF_ISOM_BOX_TYPE_LHV1:
6473 : case GF_ISOM_BOX_TYPE_LHE1:
6474 : case GF_ISOM_BOX_TYPE_AV01:
6475 : case GF_ISOM_BOX_TYPE_VP08:
6476 : case GF_ISOM_BOX_TYPE_VP09:
6477 : case GF_ISOM_BOX_TYPE_AV1C:
6478 : case GF_ISOM_BOX_TYPE_TX3G:
6479 : case GF_ISOM_BOX_TYPE_TEXT:
6480 : case GF_ISOM_BOX_TYPE_ENCT:
6481 : case GF_ISOM_BOX_TYPE_DIMS:
6482 : case GF_ISOM_BOX_TYPE_OPUS:
6483 : case GF_ISOM_BOX_TYPE_AC3:
6484 : case GF_ISOM_BOX_TYPE_EC3:
6485 : case GF_ISOM_BOX_TYPE_LSR1:
6486 : case GF_ISOM_BOX_TYPE_WVTT:
6487 : case GF_ISOM_BOX_TYPE_STPP:
6488 : case GF_ISOM_BOX_TYPE_SBTT:
6489 : case GF_ISOM_BOX_TYPE_MP3:
6490 : case GF_ISOM_BOX_TYPE_JPEG:
6491 : case GF_ISOM_BOX_TYPE_PNG:
6492 : case GF_ISOM_BOX_TYPE_JP2K:
6493 : case GF_ISOM_BOX_TYPE_MHA1:
6494 : case GF_ISOM_BOX_TYPE_MHA2:
6495 : case GF_ISOM_BOX_TYPE_MHM1:
6496 : case GF_ISOM_BOX_TYPE_MHM2:
6497 : case GF_ISOM_BOX_TYPE_MJP2:
6498 : case GF_QT_SUBTYPE_RAW_AUD:
6499 : case GF_QT_SUBTYPE_TWOS:
6500 : case GF_QT_SUBTYPE_SOWT:
6501 : case GF_QT_SUBTYPE_FL32:
6502 : case GF_QT_SUBTYPE_FL64:
6503 : case GF_QT_SUBTYPE_IN24:
6504 : case GF_QT_SUBTYPE_IN32:
6505 : case GF_QT_SUBTYPE_ULAW:
6506 : case GF_QT_SUBTYPE_ALAW:
6507 : case GF_QT_SUBTYPE_ADPCM:
6508 : case GF_QT_SUBTYPE_IMA_ADPCM:
6509 : case GF_QT_SUBTYPE_DVCA:
6510 : case GF_QT_SUBTYPE_QDMC:
6511 : case GF_QT_SUBTYPE_QDMC2:
6512 : case GF_QT_SUBTYPE_QCELP:
6513 : case GF_QT_SUBTYPE_kMP3:
6514 : case GF_QT_SUBTYPE_APCH:
6515 : case GF_QT_SUBTYPE_APCO:
6516 : case GF_QT_SUBTYPE_APCN:
6517 : case GF_QT_SUBTYPE_APCS:
6518 : case GF_QT_SUBTYPE_AP4X:
6519 : case GF_QT_SUBTYPE_AP4H:
6520 : case GF_ISOM_BOX_TYPE_IPCM:
6521 : case GF_ISOM_BOX_TYPE_FPCM:
6522 : case GF_ISOM_BOX_TYPE_VVC1:
6523 : case GF_ISOM_BOX_TYPE_VVI1:
6524 : case GF_QT_SUBTYPE_RAW_VID:
6525 : case GF_QT_SUBTYPE_YUYV:
6526 : case GF_QT_SUBTYPE_UYVY:
6527 : case GF_QT_SUBTYPE_YUV444:
6528 : case GF_QT_SUBTYPE_YUVA444:
6529 : case GF_QT_SUBTYPE_YUV422_10:
6530 : case GF_QT_SUBTYPE_YUV444_10:
6531 : case GF_QT_SUBTYPE_YUV422_16:
6532 : case GF_QT_SUBTYPE_YUV420:
6533 : case GF_QT_SUBTYPE_I420:
6534 : case GF_QT_SUBTYPE_IYUV:
6535 : case GF_QT_SUBTYPE_YV12:
6536 : case GF_QT_SUBTYPE_YVYU:
6537 : case GF_QT_SUBTYPE_RGBA:
6538 : case GF_QT_SUBTYPE_ABGR:
6539 2461 : continue;
6540 :
6541 : case GF_ISOM_BOX_TYPE_UNKNOWN:
6542 : break;
6543 33 : default:
6544 33 : if (gf_box_valid_in_parent((GF_Box *) a, "stsd")) {
6545 33 : continue;
6546 : }
6547 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Unexpected box %s in stsd!\n", gf_4cc_to_str(a->type)));
6548 0 : continue;
6549 : }
6550 : //we are sure to have an unknown box here
6551 : assert(a->type==GF_ISOM_BOX_TYPE_UNKNOWN);
6552 :
6553 6 : if (!a->data || (a->dataSize<8) ) {
6554 0 : 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->original_4cc) ));
6555 0 : continue;
6556 : }
6557 6 : else if (a->dataSize > a->size) {
6558 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Sample description %s has wrong data size %d!\n", gf_4cc_to_str(a->original_4cc), a->dataSize));
6559 0 : continue;
6560 : }
6561 :
6562 : #define STSD_SWITCH_BOX(_box) \
6563 : if (gf_bs_available(bs)) { \
6564 : u64 pos = gf_bs_get_position(bs); \
6565 : u32 count_subb = 0; \
6566 : gf_bs_set_cookie(bs, GF_ISOM_BS_COOKIE_NO_LOGS);\
6567 : e = gf_isom_box_array_read((GF_Box *) _box, bs); \
6568 : count_subb = _box->child_boxes ? gf_list_count(_box->child_boxes) : 0; \
6569 : if (!count_subb || e) { \
6570 : gf_bs_seek(bs, pos); \
6571 : _box->data_size = (u32) gf_bs_available(bs); \
6572 : if (_box->data_size) { \
6573 : _box->data = a->data; \
6574 : a->data = NULL; \
6575 : memmove(_box->data, _box->data + pos, _box->data_size); \
6576 : } \
6577 : } else { \
6578 : _box->data_size = 0; \
6579 : } \
6580 : } \
6581 : gf_bs_del(bs); \
6582 : if (!_box->data_size && _box->data) { \
6583 : gf_free(_box->data); \
6584 : _box->data = NULL; \
6585 : } \
6586 : _box->size = 0; \
6587 : _box->EntryType = a->original_4cc; \
6588 : gf_list_rem(trak->Media->information->sampleTable->SampleDescription->child_boxes, i-1); \
6589 : gf_isom_box_del((GF_Box *)a); \
6590 : gf_list_insert(trak->Media->information->sampleTable->SampleDescription->child_boxes, _box, i-1); \
6591 :
6592 :
6593 : /*only process visual or audio
6594 : note: no need for new_box_parent here since we always store sample descriptions in child_boxes*/
6595 6 : switch (trak->Media->handler->handlerType) {
6596 0 : case GF_ISOM_MEDIA_VISUAL:
6597 : case GF_ISOM_MEDIA_AUXV:
6598 : case GF_ISOM_MEDIA_PICT:
6599 : {
6600 0 : GF_GenericVisualSampleEntryBox *genv = (GF_GenericVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRV);
6601 0 : bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
6602 0 : genv->size = a->size-8;
6603 0 : gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *) genv, bs);
6604 :
6605 0 : STSD_SWITCH_BOX(genv)
6606 :
6607 : }
6608 : break;
6609 0 : case GF_ISOM_MEDIA_AUDIO:
6610 : {
6611 0 : GF_GenericAudioSampleEntryBox *gena = (GF_GenericAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRA);
6612 0 : gena->size = a->size-8;
6613 0 : bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
6614 0 : gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox *) gena, bs);
6615 :
6616 0 : STSD_SWITCH_BOX(gena)
6617 :
6618 : }
6619 : break;
6620 :
6621 6 : default:
6622 : {
6623 6 : GF_GenericSampleEntryBox *genm = (GF_GenericSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRM);
6624 6 : genm->size = a->size-8;
6625 6 : bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
6626 :
6627 6 : e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)genm, bs);
6628 6 : if (e) return;
6629 :
6630 6 : STSD_SWITCH_BOX(genm)
6631 : }
6632 : break;
6633 : }
6634 :
6635 : }
6636 : }
6637 :
6638 :
6639 10761 : GF_Err trak_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
6640 : {
6641 : GF_TrackBox *ptr = (GF_TrackBox *)s;
6642 10761 : if (!a) return GF_OK;
6643 10761 : switch(a->type) {
6644 4116 : case GF_ISOM_BOX_TYPE_TKHD:
6645 4116 : BOX_FIELD_ASSIGN(Header, GF_TrackHeaderBox)
6646 4116 : return GF_OK;
6647 1235 : case GF_ISOM_BOX_TYPE_EDTS:
6648 1235 : BOX_FIELD_ASSIGN(editBox, GF_EditBox)
6649 1235 : return GF_OK;
6650 382 : case GF_ISOM_BOX_TYPE_UDTA:
6651 382 : BOX_FIELD_ASSIGN(udta, GF_UserDataBox)
6652 382 : return GF_OK;
6653 89 : case GF_ISOM_BOX_TYPE_META:
6654 89 : BOX_FIELD_ASSIGN(meta, GF_MetaBox)
6655 89 : return GF_OK;
6656 538 : case GF_ISOM_BOX_TYPE_TREF:
6657 538 : BOX_FIELD_ASSIGN(References, GF_TrackReferenceBox)
6658 538 : return GF_OK;
6659 4116 : case GF_ISOM_BOX_TYPE_MDIA:
6660 4116 : BOX_FIELD_ASSIGN(Media, GF_MediaBox)
6661 : if (!is_rem)
6662 4116 : ((GF_MediaBox *)a)->mediaTrack = ptr;
6663 4116 : return GF_OK;
6664 19 : case GF_ISOM_BOX_TYPE_TRGR:
6665 19 : BOX_FIELD_ASSIGN(groups, GF_TrackGroupBox)
6666 19 : return GF_OK;
6667 11 : case GF_QT_BOX_TYPE_TAPT:
6668 11 : BOX_FIELD_ASSIGN(Aperture, GF_Box)
6669 11 : return GF_OK;
6670 233 : case GF_ISOM_BOX_TYPE_SENC:
6671 233 : BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
6672 233 : return GF_OK;
6673 20 : case GF_ISOM_BOX_TYPE_UUID:
6674 20 : if (((GF_UnknownUUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC) {
6675 18 : BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
6676 18 : return GF_OK;
6677 : }
6678 : }
6679 : return GF_OK;
6680 : }
6681 :
6682 :
6683 3106 : GF_Err trak_box_read(GF_Box *s, GF_BitStream *bs)
6684 : {
6685 : GF_Err e;
6686 : u32 i;
6687 : GF_TrackBox *ptr = (GF_TrackBox *)s;
6688 3106 : e = gf_isom_box_array_read(s, bs);
6689 3106 : if (e) return e;
6690 3106 : gf_isom_check_sample_desc(ptr);
6691 :
6692 3106 : if (!ptr->Header) {
6693 1 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing TrackHeaderBox\n"));
6694 : return GF_ISOM_INVALID_FILE;
6695 : }
6696 3105 : if (!ptr->Media) {
6697 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaBox\n"));
6698 : return GF_ISOM_INVALID_FILE;
6699 : }
6700 3105 : if (!ptr->Media->information || !ptr->Media->information->sampleTable) {
6701 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid MediaBox\n"));
6702 : return GF_ISOM_INVALID_FILE;
6703 : }
6704 3105 : if (!ptr->Media->information->sampleTable->SampleSize || (ptr->Media->information->sampleTable->SampleSize->sampleCount==0)) {
6705 1088 : if (ptr->Header->initial_duration) {
6706 689 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Track with no samples but duration defined, ignoring duration\n"));
6707 689 : ptr->Header->initial_duration = 0;
6708 : }
6709 : }
6710 :
6711 15103 : for (i=0; i<gf_list_count(ptr->Media->information->sampleTable->child_boxes); i++) {
6712 15103 : GF_Box *a = gf_list_get(ptr->Media->information->sampleTable->child_boxes, i);
6713 15103 : if ((a->type ==GF_ISOM_BOX_TYPE_UUID) && (((GF_UUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC)) {
6714 0 : ptr->sample_encryption = (struct __sample_encryption_box *) a;
6715 0 : break;
6716 : }
6717 15103 : else if (a->type == GF_ISOM_BOX_TYPE_SENC) {
6718 0 : ptr->sample_encryption = (struct __sample_encryption_box *)a;
6719 0 : break;
6720 : }
6721 : }
6722 : return e;
6723 : }
6724 :
6725 4125 : GF_Box *trak_box_new()
6726 : {
6727 8250 : ISOM_DECL_BOX_ALLOC(GF_TrackBox, GF_ISOM_BOX_TYPE_TRAK);
6728 4125 : return (GF_Box *)tmp;
6729 : }
6730 :
6731 :
6732 : #ifndef GPAC_DISABLE_ISOM_WRITE
6733 :
6734 3176 : GF_Err trak_box_write(GF_Box *s, GF_BitStream *bs)
6735 : {
6736 3176 : return gf_isom_box_write_header(s, bs);
6737 : }
6738 :
6739 6125 : GF_Err trak_box_size(GF_Box *s)
6740 : {
6741 6125 : u32 pos=0;
6742 : GF_TrackBox *ptr = (GF_TrackBox *)s;
6743 :
6744 6125 : if (ptr->sample_encryption && ptr->sample_encryption->load_needed) {
6745 0 : if (!ptr->moov || !!ptr->moov->mov || !ptr->moov->mov->movieFileMap)
6746 : return GF_ISOM_INVALID_FILE;
6747 0 : GF_Err e = senc_Parse(ptr->moov->mov->movieFileMap->bs, ptr, NULL, ptr->sample_encryption);
6748 0 : if (e) return e;
6749 : }
6750 :
6751 6125 : gf_isom_check_position(s, (GF_Box *)ptr->Header, &pos);
6752 6125 : gf_isom_check_position(s, (GF_Box *)ptr->Aperture, &pos);
6753 6125 : gf_isom_check_position(s, (GF_Box *)ptr->References, &pos);
6754 6125 : gf_isom_check_position(s, (GF_Box *)ptr->editBox, &pos);
6755 6125 : gf_isom_check_position(s, (GF_Box *)ptr->Media, &pos);
6756 6125 : gf_isom_check_position(s, (GF_Box *)ptr->meta, &pos);
6757 6125 : gf_isom_check_position(s, (GF_Box *)ptr->groups, &pos);
6758 6125 : gf_isom_check_position(s, (GF_Box *)ptr->udta, &pos);
6759 6125 : return GF_OK;
6760 : }
6761 :
6762 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
6763 :
6764 3 : void stri_box_del(GF_Box *s)
6765 : {
6766 : GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
6767 3 : if (ptr == NULL) return;
6768 3 : if (ptr->attribute_list) gf_free(ptr->attribute_list);
6769 3 : gf_free(ptr);
6770 : }
6771 :
6772 1 : GF_Err stri_box_read(GF_Box *s, GF_BitStream *bs)
6773 : {
6774 : size_t i;
6775 : GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
6776 1 : ISOM_DECREASE_SIZE(ptr, 8)
6777 1 : ptr->switch_group = gf_bs_read_u16(bs);
6778 1 : ptr->alternate_group = gf_bs_read_u16(bs);
6779 1 : ptr->sub_track_id = gf_bs_read_u32(bs);
6780 1 : ptr->attribute_count = ptr->size / 4;
6781 1 : GF_SAFE_ALLOC_N(ptr->attribute_list, (size_t)ptr->attribute_count, u32);
6782 1 : if (!ptr->attribute_list) return GF_OUT_OF_MEM;
6783 0 : for (i = 0; i < ptr->attribute_count; i++) {
6784 0 : ISOM_DECREASE_SIZE(ptr, 4)
6785 0 : ptr->attribute_list[i] = gf_bs_read_u32(bs);
6786 : }
6787 : return GF_OK;
6788 : }
6789 :
6790 3 : GF_Box *stri_box_new()
6791 : {
6792 6 : ISOM_DECL_BOX_ALLOC(GF_SubTrackInformationBox, GF_ISOM_BOX_TYPE_STRI);
6793 3 : return (GF_Box *)tmp;
6794 : }
6795 :
6796 :
6797 : #ifndef GPAC_DISABLE_ISOM_WRITE
6798 :
6799 1 : GF_Err stri_box_write(GF_Box *s, GF_BitStream *bs)
6800 : {
6801 : GF_Err e;
6802 : u32 i;
6803 : GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
6804 1 : e = gf_isom_full_box_write(s, bs);
6805 1 : if (e) return e;
6806 :
6807 1 : gf_bs_write_u16(bs, ptr->switch_group);
6808 1 : gf_bs_write_u16(bs, ptr->alternate_group);
6809 1 : gf_bs_write_u32(bs, ptr->sub_track_id);
6810 1 : for (i = 0; i < ptr->attribute_count; i++) {
6811 0 : gf_bs_write_u32(bs, ptr->attribute_list[i]);
6812 : }
6813 : return GF_OK;
6814 : }
6815 :
6816 1 : GF_Err stri_box_size(GF_Box *s)
6817 : {
6818 : GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
6819 :
6820 1 : ptr->size += 8 + 4 * ptr->attribute_count;
6821 1 : return GF_OK;
6822 : }
6823 :
6824 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
6825 :
6826 3 : void stsg_box_del(GF_Box *s)
6827 : {
6828 : GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
6829 3 : if (ptr == NULL) return;
6830 3 : if (ptr->group_description_index) gf_free(ptr->group_description_index);
6831 3 : gf_free(ptr);
6832 : }
6833 :
6834 1 : GF_Err stsg_box_read(GF_Box *s, GF_BitStream *bs)
6835 : {
6836 : u32 i;
6837 : GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
6838 1 : ISOM_DECREASE_SIZE(s, 6);
6839 1 : ptr->grouping_type = gf_bs_read_u32(bs);
6840 1 : ptr->nb_groups = gf_bs_read_u16(bs);
6841 1 : ISOM_DECREASE_SIZE(s, ptr->nb_groups*4);
6842 1 : GF_SAFE_ALLOC_N(ptr->group_description_index, ptr->nb_groups, u32);
6843 1 : if (!ptr->group_description_index) return GF_OUT_OF_MEM;
6844 0 : for (i = 0; i < ptr->nb_groups; i++) {
6845 0 : ptr->group_description_index[i] = gf_bs_read_u32(bs);
6846 : }
6847 : return GF_OK;
6848 : }
6849 :
6850 3 : GF_Box *stsg_box_new()
6851 : {
6852 6 : ISOM_DECL_BOX_ALLOC(GF_SubTrackSampleGroupBox, GF_ISOM_BOX_TYPE_STSG);
6853 3 : return (GF_Box *)tmp;
6854 : }
6855 :
6856 :
6857 : #ifndef GPAC_DISABLE_ISOM_WRITE
6858 :
6859 1 : GF_Err stsg_box_write(GF_Box *s, GF_BitStream *bs)
6860 : {
6861 : GF_Err e;
6862 : u32 i;
6863 : GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
6864 1 : e = gf_isom_full_box_write(s, bs);
6865 1 : if (e) return e;
6866 :
6867 1 : gf_bs_write_u32(bs, ptr->grouping_type);
6868 1 : gf_bs_write_u16(bs, ptr->nb_groups);
6869 1 : for (i = 0; i < ptr->nb_groups; i++) {
6870 0 : gf_bs_write_u32(bs, ptr->group_description_index[i]);
6871 : }
6872 : return GF_OK;
6873 : }
6874 :
6875 1 : GF_Err stsg_box_size(GF_Box *s)
6876 : {
6877 : GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
6878 1 : ptr->size += 6 + 4 * ptr->nb_groups;
6879 1 : return GF_OK;
6880 : }
6881 :
6882 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
6883 :
6884 :
6885 3 : void strk_box_del(GF_Box *s)
6886 : {
6887 3 : gf_free(s);
6888 3 : }
6889 :
6890 0 : GF_Err strk_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
6891 : {
6892 : GF_SubTrackBox *ptr = (GF_SubTrackBox *)s;
6893 0 : if (!a) return GF_OK;
6894 0 : switch (a->type) {
6895 0 : case GF_ISOM_BOX_TYPE_STRI:
6896 0 : BOX_FIELD_ASSIGN(info, GF_SubTrackInformationBox)
6897 0 : return GF_OK;
6898 0 : case GF_ISOM_BOX_TYPE_STRD:
6899 0 : BOX_FIELD_ASSIGN(strd, GF_Box)
6900 0 : return GF_OK;
6901 : }
6902 : return GF_OK;
6903 : }
6904 :
6905 :
6906 1 : GF_Err strk_box_read(GF_Box *s, GF_BitStream *bs)
6907 : {
6908 : GF_Err e;
6909 : GF_SubTrackBox *ptr = (GF_SubTrackBox *)s;
6910 1 : e = gf_isom_box_array_read(s, bs);
6911 1 : if (e) return e;
6912 :
6913 1 : if (!ptr->info) {
6914 1 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing SubTrackInformationBox\n"));
6915 : return GF_ISOM_INVALID_FILE;
6916 : }
6917 : return GF_OK;
6918 : }
6919 :
6920 3 : GF_Box *strk_box_new()
6921 : {
6922 6 : ISOM_DECL_BOX_ALLOC(GF_SubTrackBox, GF_ISOM_BOX_TYPE_STRK);
6923 3 : return (GF_Box *)tmp;
6924 : }
6925 :
6926 :
6927 : #ifndef GPAC_DISABLE_ISOM_WRITE
6928 :
6929 1 : GF_Err strk_box_write(GF_Box *s, GF_BitStream *bs)
6930 : {
6931 1 : return gf_isom_box_write_header(s, bs);
6932 : }
6933 :
6934 1 : GF_Err strk_box_size(GF_Box *s)
6935 : {
6936 1 : return GF_OK;
6937 : }
6938 :
6939 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
6940 :
6941 541 : void tref_box_del(GF_Box *s)
6942 : {
6943 : GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
6944 541 : if (ptr == NULL) return;
6945 541 : gf_free(ptr);
6946 : }
6947 :
6948 :
6949 326 : GF_Err tref_box_read(GF_Box *s, GF_BitStream *bs)
6950 : {
6951 326 : return gf_isom_box_array_read_ex(s, bs, s->type);
6952 : }
6953 :
6954 541 : GF_Box *tref_box_new()
6955 : {
6956 1082 : ISOM_DECL_BOX_ALLOC(GF_TrackReferenceBox, GF_ISOM_BOX_TYPE_TREF);
6957 541 : return (GF_Box *)tmp;
6958 : }
6959 :
6960 : #ifndef GPAC_DISABLE_ISOM_WRITE
6961 :
6962 430 : GF_Err tref_box_write(GF_Box *s, GF_BitStream *bs)
6963 : {
6964 : // GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
6965 430 : return gf_isom_box_write_header(s, bs);
6966 : }
6967 :
6968 845 : GF_Err tref_box_size(GF_Box *s)
6969 : {
6970 845 : return GF_OK;
6971 : }
6972 :
6973 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
6974 :
6975 702 : void reftype_box_del(GF_Box *s)
6976 : {
6977 : GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
6978 702 : if (!ptr) return;
6979 702 : if (ptr->trackIDs) gf_free(ptr->trackIDs);
6980 702 : gf_free(ptr);
6981 : }
6982 :
6983 :
6984 354 : GF_Err reftype_box_read(GF_Box *s, GF_BitStream *bs)
6985 : {
6986 : u32 bytesToRead;
6987 : u32 i;
6988 : GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
6989 :
6990 354 : bytesToRead = (u32) (ptr->size);
6991 354 : if (!bytesToRead) return GF_OK;
6992 :
6993 351 : ptr->trackIDCount = (u32) (bytesToRead) / sizeof(u32);
6994 351 : ptr->trackIDs = (GF_ISOTrackID *) gf_malloc(ptr->trackIDCount * sizeof(GF_ISOTrackID));
6995 351 : if (!ptr->trackIDs) return GF_OUT_OF_MEM;
6996 :
6997 539 : for (i = 0; i < ptr->trackIDCount; i++) {
6998 539 : ptr->trackIDs[i] = gf_bs_read_u32(bs);
6999 : }
7000 : return GF_OK;
7001 : }
7002 :
7003 702 : GF_Box *reftype_box_new()
7004 : {
7005 1404 : ISOM_DECL_BOX_ALLOC(GF_TrackReferenceTypeBox, GF_ISOM_BOX_TYPE_REFT);
7006 702 : return (GF_Box *)tmp;
7007 : }
7008 :
7009 :
7010 75730 : GF_Err reftype_AddRefTrack(GF_TrackReferenceTypeBox *ref, GF_ISOTrackID trackID, u16 *outRefIndex)
7011 : {
7012 : u32 i;
7013 75730 : if (!ref || !trackID) return GF_BAD_PARAM;
7014 :
7015 75730 : if (outRefIndex) *outRefIndex = 0;
7016 : //don't add a dep if already here !!
7017 76587 : for (i = 0; i < ref->trackIDCount; i++) {
7018 76181 : if (ref->trackIDs[i] == trackID) {
7019 75324 : if (outRefIndex) *outRefIndex = i+1;
7020 : return GF_OK;
7021 : }
7022 : }
7023 :
7024 406 : ref->trackIDs = (GF_ISOTrackID *) gf_realloc(ref->trackIDs, (ref->trackIDCount + 1) * sizeof(GF_ISOTrackID) );
7025 406 : if (!ref->trackIDs) return GF_OUT_OF_MEM;
7026 406 : ref->trackIDs[ref->trackIDCount] = trackID;
7027 406 : ref->trackIDCount++;
7028 406 : if (outRefIndex) *outRefIndex = ref->trackIDCount;
7029 : return GF_OK;
7030 : }
7031 :
7032 :
7033 :
7034 : #ifndef GPAC_DISABLE_ISOM_WRITE
7035 :
7036 502 : GF_Err reftype_box_write(GF_Box *s, GF_BitStream *bs)
7037 : {
7038 : GF_Err e;
7039 : u32 i;
7040 : GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
7041 502 : ptr->type = ptr->reference_type;
7042 502 : e = gf_isom_box_write_header(s, bs);
7043 502 : ptr->type = GF_ISOM_BOX_TYPE_REFT;
7044 502 : if (e) return e;
7045 696 : for (i = 0; i < ptr->trackIDCount; i++) {
7046 696 : gf_bs_write_u32(bs, ptr->trackIDs[i]);
7047 : }
7048 : return GF_OK;
7049 : }
7050 :
7051 :
7052 977 : GF_Err reftype_box_size(GF_Box *s)
7053 : {
7054 : GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
7055 977 : if (ptr->trackIDCount)
7056 935 : ptr->size += (ptr->trackIDCount * sizeof(u32));
7057 977 : return GF_OK;
7058 : }
7059 :
7060 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
7061 :
7062 :
7063 :
7064 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
7065 :
7066 731 : void trex_box_del(GF_Box *s)
7067 : {
7068 : GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
7069 731 : if (ptr == NULL) return;
7070 731 : gf_free(ptr);
7071 : }
7072 :
7073 :
7074 334 : GF_Err trex_box_read(GF_Box *s, GF_BitStream *bs)
7075 : {
7076 : GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
7077 :
7078 334 : ISOM_DECREASE_SIZE(ptr, 20);
7079 334 : ptr->trackID = gf_bs_read_u32(bs);
7080 334 : ptr->def_sample_desc_index = gf_bs_read_u32(bs);
7081 334 : ptr->def_sample_duration = gf_bs_read_u32(bs);
7082 334 : ptr->def_sample_size = gf_bs_read_u32(bs);
7083 334 : ptr->def_sample_flags = gf_bs_read_u32(bs);
7084 334 : return GF_OK;
7085 : }
7086 :
7087 731 : GF_Box *trex_box_new()
7088 : {
7089 1462 : ISOM_DECL_BOX_ALLOC(GF_TrackExtendsBox, GF_ISOM_BOX_TYPE_TREX);
7090 731 : return (GF_Box *)tmp;
7091 : }
7092 :
7093 :
7094 :
7095 : #ifndef GPAC_DISABLE_ISOM_WRITE
7096 :
7097 :
7098 656 : GF_Err trex_box_write(GF_Box *s, GF_BitStream *bs)
7099 : {
7100 : GF_Err e;
7101 : GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *) s;
7102 656 : if (!s) return GF_BAD_PARAM;
7103 656 : e = gf_isom_full_box_write(s, bs);
7104 656 : if (e) return e;
7105 :
7106 656 : gf_bs_write_u32(bs, ptr->trackID);
7107 : //we always write 1 in trex default sample desc as using 0 breaks chrome/opera/...
7108 656 : gf_bs_write_u32(bs, ptr->def_sample_desc_index ? ptr->def_sample_desc_index : 1);
7109 656 : gf_bs_write_u32(bs, ptr->def_sample_duration);
7110 656 : gf_bs_write_u32(bs, ptr->def_sample_size);
7111 656 : gf_bs_write_u32(bs, ptr->def_sample_flags);
7112 656 : return GF_OK;
7113 : }
7114 :
7115 661 : GF_Err trex_box_size(GF_Box *s)
7116 : {
7117 : GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
7118 661 : ptr->size += 20;
7119 661 : return GF_OK;
7120 : }
7121 :
7122 :
7123 :
7124 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
7125 :
7126 :
7127 :
7128 3 : void trep_box_del(GF_Box *s)
7129 : {
7130 : GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
7131 3 : if (ptr == NULL) return;
7132 3 : gf_free(ptr);
7133 : }
7134 :
7135 :
7136 1 : GF_Err trep_box_read(GF_Box *s, GF_BitStream *bs)
7137 : {
7138 : GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
7139 :
7140 1 : ISOM_DECREASE_SIZE(ptr, 4);
7141 1 : ptr->trackID = gf_bs_read_u32(bs);
7142 :
7143 1 : return gf_isom_box_array_read(s, bs);
7144 : }
7145 :
7146 3 : GF_Box *trep_box_new()
7147 : {
7148 6 : ISOM_DECL_BOX_ALLOC(GF_TrackExtensionPropertiesBox, GF_ISOM_BOX_TYPE_TREP);
7149 3 : tmp->child_boxes = gf_list_new();
7150 3 : return (GF_Box *)tmp;
7151 : }
7152 :
7153 :
7154 :
7155 : #ifndef GPAC_DISABLE_ISOM_WRITE
7156 :
7157 :
7158 1 : GF_Err trep_box_write(GF_Box *s, GF_BitStream *bs)
7159 : {
7160 : GF_Err e;
7161 : GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *) s;
7162 1 : if (!s) return GF_BAD_PARAM;
7163 1 : e = gf_isom_full_box_write(s, bs);
7164 1 : if (e) return e;
7165 :
7166 1 : gf_bs_write_u32(bs, ptr->trackID);
7167 1 : return GF_OK;
7168 : }
7169 :
7170 1 : GF_Err trep_box_size(GF_Box *s)
7171 : {
7172 : GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
7173 1 : ptr->size += 4;
7174 1 : return GF_OK;
7175 : }
7176 :
7177 :
7178 :
7179 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
7180 :
7181 : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
7182 :
7183 :
7184 :
7185 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
7186 :
7187 8008 : void trun_box_del(GF_Box *s)
7188 : {
7189 : GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
7190 8008 : if (ptr == NULL) return;
7191 :
7192 8008 : if (ptr->samples) gf_free(ptr->samples);
7193 8008 : if (ptr->cache) gf_bs_del(ptr->cache);
7194 8008 : if (ptr->sample_order) gf_free(ptr->sample_order);
7195 8008 : gf_free(ptr);
7196 : }
7197 :
7198 : #ifdef GF_ENABLE_CTRN
7199 :
7200 : static u32 ctrn_field_size(u32 field_idx)
7201 : {
7202 : if (field_idx==3) return 4;
7203 : return field_idx;
7204 : }
7205 :
7206 : u32 gf_isom_ctrn_field_size_bits(u32 field_idx)
7207 : {
7208 : if (field_idx==3) return 32;
7209 : return field_idx*8;
7210 : }
7211 : static u32 ctrn_read_flags(GF_BitStream *bs, u32 nbbits)
7212 : {
7213 : u32 val = gf_bs_read_int(bs, nbbits);
7214 : if (nbbits==16) val <<= 16;
7215 : else if (nbbits==8) val <<= 24;
7216 : return val;
7217 : }
7218 :
7219 : static GF_Err ctrn_box_read(GF_Box *s, GF_BitStream *bs)
7220 : {
7221 : u32 i, count, flags, first_idx=0;
7222 : Bool inherit_dur, inherit_size, inherit_flags, inherit_ctso;
7223 : GF_TrunEntry *ent;
7224 : GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
7225 : flags = ptr->flags;
7226 : ptr->ctrn_flags = flags;
7227 : ptr->flags = 0;
7228 :
7229 : ptr->sample_count = gf_bs_read_u16(bs);
7230 : ISOM_DECREASE_SIZE(ptr, 2);
7231 :
7232 : if (flags & GF_ISOM_TRUN_DATA_OFFSET) {
7233 : if (flags & GF_ISOM_CTRN_DATAOFFSET_16) {
7234 : ptr->data_offset = gf_bs_read_u16(bs);
7235 : ISOM_DECREASE_SIZE(ptr, 2);
7236 : } else {
7237 : ptr->data_offset = gf_bs_read_u32(bs);
7238 : ISOM_DECREASE_SIZE(ptr, 4);
7239 : }
7240 : ptr->flags |= GF_ISOM_TRUN_DATA_OFFSET;
7241 : }
7242 : if (flags & GF_ISOM_CTRN_CTSO_MULTIPLIER) {
7243 : ptr->ctso_multiplier = gf_bs_read_u16(bs);
7244 : ISOM_DECREASE_SIZE(ptr, 2);
7245 : }
7246 : /*no sample dur/sample_flag/size/ctso for first or following, create a pack sample */
7247 : if (! (flags & 0x00FFFF00)) {
7248 : GF_SAFEALLOC(ent, GF_TrunEntry);
7249 : if (!ent) return GF_OUT_OF_MEM;
7250 : ent->nb_pack = ptr->sample_count;
7251 : gf_list_add(ptr->entries, ent);
7252 : return GF_OK;
7253 : }
7254 : /*allocate all entries*/
7255 : for (i=0; i<ptr->sample_count; i++) {
7256 : GF_SAFEALLOC(ent, GF_TrunEntry);
7257 : if (!ent) return GF_OUT_OF_MEM;
7258 : gf_list_add(ptr->entries, ent);
7259 : }
7260 : //unpack flags
7261 : ptr->ctrn_first_dur = (flags>>22) & 0x3;
7262 : ptr->ctrn_first_size = (flags>>20) & 0x3;
7263 : ptr->ctrn_first_sample_flags = (flags>>18) & 0x3;
7264 : ptr->ctrn_first_ctts = (flags>>16) & 0x3;
7265 : ptr->ctrn_dur = (flags>>14) & 0x3;
7266 : ptr->ctrn_size = (flags>>12) & 0x3;
7267 : ptr->ctrn_sample_flags = (flags>>10) & 0x3;
7268 : ptr->ctrn_ctts = (flags>>8) & 0x3;
7269 :
7270 : inherit_dur = flags & GF_ISOM_CTRN_INHERIT_DUR;
7271 : inherit_size = flags & GF_ISOM_CTRN_INHERIT_SIZE;
7272 : inherit_flags = flags & GF_ISOM_CTRN_INHERIT_FLAGS;
7273 : inherit_ctso = flags & GF_ISOM_CTRN_INHERIT_CTSO;
7274 :
7275 : if (flags & GF_ISOM_CTRN_FIRST_SAMPLE) {
7276 : ent = gf_list_get(ptr->entries, 0);
7277 : first_idx = 1;
7278 : if (!inherit_dur && ptr->ctrn_first_dur) {
7279 : ent->Duration = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_dur) );
7280 : ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_dur) );
7281 : }
7282 : if (!inherit_size && ptr->ctrn_first_size) {
7283 : ent->size = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_size) );
7284 : ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_size) );
7285 : }
7286 : if (!inherit_flags && ptr->ctrn_first_sample_flags) {
7287 : ent->flags = ctrn_read_flags(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_sample_flags) );
7288 : ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_sample_flags) );
7289 : }
7290 : if (!inherit_ctso && ptr->ctrn_first_ctts) {
7291 : ent->CTS_Offset = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_ctts) );
7292 : ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_ctts) );
7293 : if (ptr->ctso_multiplier)
7294 : ent->CTS_Offset *= (s32) ptr->ctso_multiplier;
7295 : }
7296 : }
7297 : count = ptr->sample_count - first_idx;
7298 : if (!inherit_dur && ptr->ctrn_dur) {
7299 : u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_dur);
7300 : ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
7301 : for (i=first_idx; i<ptr->sample_count; i++) {
7302 : ent = gf_list_get(ptr->entries, i);
7303 : ent->Duration = gf_bs_read_int(bs, nbbits);
7304 : }
7305 : }
7306 : if (!inherit_size && ptr->ctrn_size) {
7307 : u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_size);
7308 : ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
7309 : for (i=first_idx; i<ptr->sample_count; i++) {
7310 : ent = gf_list_get(ptr->entries, i);
7311 : ent->size = gf_bs_read_int(bs, nbbits);
7312 : }
7313 : }
7314 : if (!inherit_flags && ptr->ctrn_sample_flags) {
7315 : u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_sample_flags);
7316 : ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
7317 : for (i=first_idx; i<ptr->sample_count; i++) {
7318 : ent = gf_list_get(ptr->entries, i);
7319 : ent->flags = ctrn_read_flags(bs, nbbits);
7320 : }
7321 : }
7322 : if (!inherit_ctso && ptr->ctrn_ctts) {
7323 : u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_ctts);
7324 : ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
7325 : for (i=first_idx; i<ptr->sample_count; i++) {
7326 : ent = gf_list_get(ptr->entries, i);
7327 : ent->CTS_Offset = gf_bs_read_int(bs, nbbits);
7328 : if (ptr->ctso_multiplier)
7329 : ent->CTS_Offset *= (s32) ptr->ctso_multiplier;
7330 : }
7331 : }
7332 :
7333 : return GF_OK;
7334 : }
7335 : #endif
7336 :
7337 4231 : GF_Err trun_box_read(GF_Box *s, GF_BitStream *bs)
7338 : {
7339 : u32 i;
7340 : GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
7341 :
7342 : #ifdef GF_ENABLE_CTRN
7343 : if (ptr->type == GF_ISOM_BOX_TYPE_CTRN) {
7344 : ptr->type = GF_ISOM_BOX_TYPE_TRUN;
7345 : ptr->use_ctrn = GF_TRUE;
7346 : return ctrn_box_read(s, bs);
7347 : }
7348 : #endif
7349 :
7350 : //check this is a good file
7351 4231 : if ((ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) && (ptr->flags & GF_ISOM_TRUN_FLAGS))
7352 : return GF_ISOM_INVALID_FILE;
7353 :
7354 4231 : ISOM_DECREASE_SIZE(ptr, 4);
7355 4231 : ptr->sample_count = gf_bs_read_u32(bs);
7356 :
7357 : //The rest depends on the flags
7358 4231 : if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) {
7359 4189 : ISOM_DECREASE_SIZE(ptr, 4);
7360 4189 : ptr->data_offset = gf_bs_read_u32(bs);
7361 : }
7362 4231 : if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) {
7363 3208 : ISOM_DECREASE_SIZE(ptr, 4);
7364 3208 : ptr->first_sample_flags = gf_bs_read_u32(bs);
7365 : }
7366 4231 : if (! (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) ) ) {
7367 188 : ptr->samples = gf_malloc(sizeof(GF_TrunEntry));
7368 188 : if (!ptr->samples) return GF_OUT_OF_MEM;
7369 : //memset to 0 !!
7370 : memset(ptr->samples, 0, sizeof(GF_TrunEntry));
7371 188 : ptr->sample_alloc = ptr->nb_samples = 1;
7372 188 : ptr->samples[0].nb_pack = ptr->sample_count;
7373 : } else {
7374 : //if we get here, at least one flag (so at least 4 bytes) is set, check size
7375 4043 : if (ptr->sample_count * 4 > ptr->size) {
7376 0 : ISOM_DECREASE_SIZE(ptr, ptr->sample_count*4);
7377 : }
7378 4043 : ptr->samples = gf_malloc(sizeof(GF_TrunEntry) * ptr->sample_count);
7379 4043 : if (!ptr->samples) return GF_OUT_OF_MEM;
7380 4043 : ptr->sample_alloc = ptr->nb_samples = ptr->sample_count;
7381 : //memset to 0 upfront
7382 4043 : memset(ptr->samples, 0, ptr->sample_count * sizeof(GF_TrunEntry));
7383 :
7384 : //read each entry (even though nothing may be written)
7385 116893 : for (i=0; i<ptr->sample_count; i++) {
7386 : u32 trun_size = 0;
7387 112850 : GF_TrunEntry *p = &ptr->samples[i];
7388 :
7389 112850 : if (ptr->flags & GF_ISOM_TRUN_DURATION) {
7390 5361 : p->Duration = gf_bs_read_u32(bs);
7391 : trun_size += 4;
7392 : }
7393 112850 : if (ptr->flags & GF_ISOM_TRUN_SIZE) {
7394 112850 : p->size = gf_bs_read_u32(bs);
7395 112850 : trun_size += 4;
7396 : }
7397 : //SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
7398 112850 : if (ptr->flags & GF_ISOM_TRUN_FLAGS) {
7399 6550 : p->flags = gf_bs_read_u32(bs);
7400 6550 : trun_size += 4;
7401 : }
7402 112850 : if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) {
7403 5385 : if (ptr->version==0) {
7404 4422 : p->CTS_Offset = (u32) gf_bs_read_u32(bs);
7405 : } else {
7406 963 : p->CTS_Offset = (s32) gf_bs_read_u32(bs);
7407 : }
7408 5385 : trun_size += 4;
7409 : }
7410 112850 : ISOM_DECREASE_SIZE(ptr, trun_size);
7411 : }
7412 : }
7413 : /*todo parse sample reorder*/
7414 4231 : if (ptr->size) {
7415 0 : gf_bs_skip_bytes(bs, ptr->size);
7416 0 : ptr->size = 0;
7417 : }
7418 : return GF_OK;
7419 : }
7420 :
7421 8008 : GF_Box *trun_box_new()
7422 : {
7423 16016 : ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRunBox, GF_ISOM_BOX_TYPE_TRUN);
7424 : //NO FLAGS SET BY DEFAULT
7425 8008 : return (GF_Box *)tmp;
7426 : }
7427 :
7428 : #ifndef GPAC_DISABLE_ISOM_WRITE
7429 :
7430 : #ifdef GF_ENABLE_CTRN
7431 : static void ctrn_write_sample_flags(GF_BitStream *bs, u32 flags, u32 field_size)
7432 : {
7433 : if (!field_size) return;
7434 :
7435 : if (field_size==8) flags = flags>>24;
7436 : else if (field_size==16) flags = flags>>16;
7437 : gf_bs_write_int(bs, flags, field_size);
7438 : }
7439 :
7440 :
7441 : static void ctrn_write_ctso(GF_TrackFragmentRunBox *ctrn, GF_BitStream *bs, u32 ctso, u32 field_size)
7442 : {
7443 : if (!field_size) return;
7444 :
7445 : if (ctrn->ctso_multiplier) {
7446 : gf_bs_write_int(bs, ctso / ctrn->ctso_multiplier, field_size);
7447 : } else {
7448 : gf_bs_write_int(bs, ctso, field_size);
7449 : }
7450 : }
7451 :
7452 : GF_Err ctrn_box_write(GF_Box *s, GF_BitStream *bs)
7453 : {
7454 : GF_Err e;
7455 : u32 i, count, flags;
7456 : GF_TrunEntry *ent;
7457 : GF_TrackFragmentRunBox *ctrn = (GF_TrackFragmentRunBox *) s;
7458 : if (!s) return GF_BAD_PARAM;
7459 : flags = ctrn->flags;
7460 : ctrn->flags = ctrn->ctrn_flags;
7461 : ctrn->type = GF_ISOM_BOX_TYPE_CTRN;
7462 :
7463 : e = gf_isom_full_box_write(s, bs);
7464 : if (e) return e;
7465 : ctrn->flags = flags;
7466 : ctrn->type = GF_ISOM_BOX_TYPE_TRUN;
7467 :
7468 : gf_bs_write_u16(bs, ctrn->sample_count);
7469 : if (ctrn->flags & GF_ISOM_TRUN_DATA_OFFSET) {
7470 : if (ctrn->ctrn_flags & GF_ISOM_CTRN_DATAOFFSET_16) {
7471 : gf_bs_write_u16(bs, ctrn->data_offset);
7472 : } else {
7473 : gf_bs_write_u32(bs, ctrn->data_offset);
7474 : }
7475 : }
7476 : if (ctrn->ctso_multiplier) {
7477 : gf_bs_write_u16(bs, ctrn->ctso_multiplier);
7478 : }
7479 : /*we always write first sample using first flags*/
7480 : ent = gf_list_get(ctrn->entries, 0);
7481 : gf_bs_write_int(bs, ent->Duration, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_dur) );
7482 : gf_bs_write_int(bs, ent->size, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_size) );
7483 : ctrn_write_sample_flags(bs, ent->flags, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_sample_flags) );
7484 : ctrn_write_ctso(ctrn,bs, ent->CTS_Offset, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_ctts) );
7485 :
7486 : count = gf_list_count(ctrn->entries);
7487 : if (ctrn->ctrn_dur) {
7488 : u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_dur);
7489 : for (i=1; i<count; i++) {
7490 : GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
7491 : gf_bs_write_int(bs, a_ent->Duration, nbbits);
7492 : }
7493 : }
7494 : if (ctrn->ctrn_size) {
7495 : u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_size);
7496 : for (i=1; i<count; i++) {
7497 : GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
7498 : gf_bs_write_int(bs, a_ent->size, nbbits);
7499 : }
7500 : }
7501 : if (ctrn->ctrn_sample_flags) {
7502 : u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_sample_flags);
7503 : for (i=1; i<count; i++) {
7504 : GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
7505 : ctrn_write_sample_flags(bs, a_ent->flags, nbbits);
7506 : }
7507 : }
7508 : if (ctrn->ctrn_ctts) {
7509 : u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_ctts);
7510 : for (i=1; i<count; i++) {
7511 : GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
7512 : ctrn_write_ctso(ctrn, bs, a_ent->CTS_Offset, nbbits);
7513 : }
7514 : }
7515 :
7516 : return GF_OK;
7517 : }
7518 : #endif
7519 :
7520 3863 : GF_Err trun_box_write(GF_Box *s, GF_BitStream *bs)
7521 : {
7522 : GF_Err e;
7523 : u32 i;
7524 : GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *) s;
7525 3863 : if (!s) return GF_BAD_PARAM;
7526 :
7527 : #ifdef GF_ENABLE_CTRN
7528 : if (ptr->use_ctrn)
7529 : return ctrn_box_write(s, bs);
7530 : #endif
7531 :
7532 3863 : e = gf_isom_full_box_write(s, bs);
7533 3863 : if (e) return e;
7534 :
7535 3863 : gf_bs_write_u32(bs, ptr->sample_count);
7536 :
7537 : //The rest depends on the flags
7538 3863 : if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) {
7539 3796 : gf_bs_write_u32(bs, ptr->data_offset);
7540 : }
7541 3863 : if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) {
7542 2425 : gf_bs_write_u32(bs, ptr->first_sample_flags);
7543 : }
7544 :
7545 3863 : if (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) ) {
7546 112658 : for (i=0; i<ptr->nb_samples; i++) {
7547 112658 : GF_TrunEntry *p = &ptr->samples[i];
7548 :
7549 112658 : if (ptr->flags & GF_ISOM_TRUN_DURATION) {
7550 3477 : gf_bs_write_u32(bs, p->Duration);
7551 : }
7552 112658 : if (ptr->flags & GF_ISOM_TRUN_SIZE) {
7553 112518 : gf_bs_write_u32(bs, p->size);
7554 : }
7555 : //SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
7556 112658 : if (ptr->flags & GF_ISOM_TRUN_FLAGS) {
7557 10242 : gf_bs_write_u32(bs, p->flags);
7558 : }
7559 112658 : if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) {
7560 16490 : if (ptr->version==0) {
7561 12411 : gf_bs_write_u32(bs, p->CTS_Offset);
7562 : } else {
7563 4079 : gf_bs_write_u32(bs, (u32) p->CTS_Offset);
7564 : }
7565 : }
7566 : }
7567 : }
7568 :
7569 3863 : if (ptr->sample_order) {
7570 : u32 nb_bits = 8;
7571 0 : if (ptr->sample_count>0xFFFFFF) nb_bits = 32;
7572 0 : else if (ptr->sample_count>0xFFFF) nb_bits = 24;
7573 0 : else if (ptr->sample_count>0xFF) nb_bits = 16;
7574 :
7575 0 : for (i=0; i<ptr->sample_count; i++) {
7576 0 : gf_bs_write_int(bs, ptr->sample_order[i], nb_bits);
7577 : }
7578 : }
7579 : return GF_OK;
7580 : }
7581 :
7582 : #ifdef GF_ENABLE_CTRN
7583 : static u32 ctrn_sample_flags_to_index(u32 val)
7584 : {
7585 : if (!val) return 0;
7586 : if (val & 0x0000FFFF)
7587 : return 3;
7588 : if (val & 0x00FF0000)
7589 : return 2;
7590 : return 1;
7591 : }
7592 : static u32 ctrn_u32_to_index(u32 val)
7593 : {
7594 : if (!val) return 0;
7595 : if (val<=255) return 1;
7596 : if (val<=65535) return 2;
7597 : return 3;
7598 : }
7599 : static u32 ctrn_s32_to_index(s32 val)
7600 : {
7601 : if (!val) return 0;
7602 : if (ABS(val)<=127) return 1;
7603 : if (ABS(val)<=32767) return 2;
7604 : return 3;
7605 : }
7606 : static u32 ctrn_ctts_to_index(GF_TrackFragmentRunBox *ctrn, s32 ctts)
7607 : {
7608 : if (!(ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET))
7609 : return 0;
7610 :
7611 : if (!ctts) return 0;
7612 :
7613 : if (ctrn->version) {
7614 : if (ctrn->ctso_multiplier) return ctrn_s32_to_index(ctts / ctrn->ctso_multiplier);
7615 : return ctrn_s32_to_index(ctts);
7616 : }
7617 : assert(ctts>0);
7618 : if (ctrn->ctso_multiplier) return ctrn_u32_to_index((u32)ctts / ctrn->ctso_multiplier);
7619 : return ctrn_s32_to_index((u32)ctts);
7620 : }
7621 :
7622 : static GF_Err ctrn_box_size(GF_TrackFragmentRunBox *ctrn)
7623 : {
7624 : Bool use_ctso_multi = GF_TRUE;
7625 : u32 i, count;
7626 : GF_TrunEntry *ent;
7627 :
7628 : ctrn->ctrn_flags = 0;
7629 : ctrn->ctrn_first_dur = ctrn->ctrn_first_size = ctrn->ctrn_first_sample_flags = ctrn->ctrn_first_ctts = 0;
7630 : ctrn->ctrn_dur = ctrn->ctrn_size = ctrn->ctrn_sample_flags = ctrn->ctrn_ctts = 0;
7631 :
7632 : ctrn->size += 2; //16 bits for sample count
7633 : if (ctrn->flags & GF_ISOM_TRUN_DATA_OFFSET) {
7634 : ctrn->ctrn_flags |= GF_ISOM_TRUN_DATA_OFFSET;
7635 : if (ABS(ctrn->data_offset) < 32767) {
7636 : ctrn->size += 2;
7637 : ctrn->ctrn_flags |= GF_ISOM_CTRN_DATAOFFSET_16;
7638 : } else
7639 : ctrn->size += 4;
7640 : }
7641 :
7642 : count = gf_list_count(ctrn->entries);
7643 : if (ctrn->ctso_multiplier && (ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET) && (ctrn->ctso_multiplier<=0xFFFF) ) {
7644 : for (i=0; i<count; i++) {
7645 : GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
7646 : if (a_ent->CTS_Offset % ctrn->ctso_multiplier) {
7647 : use_ctso_multi = GF_FALSE;
7648 : break;
7649 : }
7650 : }
7651 : } else {
7652 : use_ctso_multi = GF_FALSE;
7653 : }
7654 : if (ctrn->use_inherit) {
7655 : use_ctso_multi = GF_FALSE;
7656 : ctrn->ctrn_flags |= 0xB0; //duration=1,size=0,flags=1,cts=1 << 4
7657 : }
7658 :
7659 : if (use_ctso_multi) {
7660 : ctrn->size += 2;
7661 : ctrn->ctrn_flags |= GF_ISOM_CTRN_CTSO_MULTIPLIER;
7662 : } else {
7663 : ctrn->ctso_multiplier = 0;
7664 : }
7665 :
7666 : /*we always write first sample using first flags*/
7667 : ent = gf_list_get(ctrn->entries, 0);
7668 : ctrn->ctrn_flags |= GF_ISOM_CTRN_FIRST_SAMPLE;
7669 :
7670 : if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_DURATION)) {
7671 : ctrn->ctrn_first_dur = ctrn_u32_to_index(ent->Duration);
7672 : if (ctrn->ctrn_first_dur) {
7673 : ctrn->size += ctrn_field_size(ctrn->ctrn_first_dur);
7674 : ctrn->ctrn_flags |= ctrn->ctrn_first_dur<<22;
7675 : }
7676 : }
7677 :
7678 : if (ctrn->flags & GF_ISOM_TRUN_SIZE) {
7679 : ctrn->ctrn_first_size = ctrn_u32_to_index(ent->size);
7680 : if (ctrn->ctrn_first_size) {
7681 : ctrn->size += ctrn_field_size(ctrn->ctrn_first_size);
7682 : ctrn->ctrn_flags |= ctrn->ctrn_first_size<<20;
7683 : }
7684 : }
7685 :
7686 : if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_FLAGS)) {
7687 : ctrn->ctrn_first_sample_flags = ctrn_sample_flags_to_index(ent->flags);
7688 : if (ctrn->ctrn_first_sample_flags) {
7689 : ctrn->size += ctrn_field_size(ctrn->ctrn_first_sample_flags);
7690 : ctrn->ctrn_flags |= ctrn->ctrn_first_sample_flags<<18;
7691 : }
7692 : }
7693 : if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET)) {
7694 : ctrn->ctrn_first_ctts = ctrn_ctts_to_index(ctrn, ent->CTS_Offset);
7695 : if (ctrn->ctrn_first_ctts) {
7696 : ctrn->size += ctrn_field_size(ctrn->ctrn_first_ctts);
7697 : ctrn->ctrn_flags |= ctrn->ctrn_first_ctts<<16;
7698 : }
7699 : }
7700 :
7701 : for (i=1; i<count; i++) {
7702 : u8 field_idx;
7703 : GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
7704 :
7705 : if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_DURATION)) {
7706 : field_idx = ctrn_u32_to_index(a_ent->Duration);
7707 : if (ctrn->ctrn_dur < field_idx)
7708 : ctrn->ctrn_dur = field_idx;
7709 : }
7710 : if (ctrn->flags & GF_ISOM_TRUN_SIZE) {
7711 : field_idx = ctrn_u32_to_index(a_ent->size);
7712 : if (ctrn->ctrn_size < field_idx)
7713 : ctrn->ctrn_size = field_idx;
7714 : }
7715 : if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_FLAGS)) {
7716 : field_idx = ctrn_sample_flags_to_index(a_ent->flags);
7717 : if (ctrn->ctrn_sample_flags < field_idx)
7718 : ctrn->ctrn_sample_flags = field_idx;
7719 : }
7720 : if (!ctrn->use_inherit) {
7721 : field_idx = ctrn_ctts_to_index(ctrn, a_ent->CTS_Offset);
7722 : if (ctrn->ctrn_ctts < field_idx)
7723 : ctrn->ctrn_ctts = field_idx;
7724 : }
7725 : }
7726 : count-=1;
7727 : if (ctrn->ctrn_dur) {
7728 : ctrn->size += count * ctrn_field_size(ctrn->ctrn_dur);
7729 : ctrn->ctrn_flags |= ctrn->ctrn_dur<<14;
7730 : }
7731 : if (ctrn->ctrn_size) {
7732 : ctrn->size += count * ctrn_field_size(ctrn->ctrn_size);
7733 : ctrn->ctrn_flags |= ctrn->ctrn_size<<12;
7734 : }
7735 : if (ctrn->ctrn_sample_flags) {
7736 : ctrn->size += count * ctrn_field_size(ctrn->ctrn_sample_flags);
7737 : ctrn->ctrn_flags |= ctrn->ctrn_sample_flags<<10;
7738 : }
7739 : if (ctrn->ctrn_ctts) {
7740 : ctrn->size += count * ctrn_field_size(ctrn->ctrn_ctts);
7741 : ctrn->ctrn_flags |= ctrn->ctrn_ctts<<8;
7742 : }
7743 : return GF_OK;
7744 : }
7745 : #endif
7746 :
7747 11217 : GF_Err trun_box_size(GF_Box *s)
7748 : {
7749 : GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
7750 :
7751 : #ifdef GF_ENABLE_CTRN
7752 : if (ptr->use_ctrn)
7753 : return ctrn_box_size(ptr);
7754 : #endif
7755 :
7756 11217 : ptr->size += 4;
7757 : //The rest depends on the flags
7758 11217 : if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) ptr->size += 4;
7759 11217 : if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) ptr->size += 4;
7760 :
7761 11217 : if (ptr->sample_order) {
7762 : u32 nb_bytes = 1;
7763 0 : if (ptr->sample_count>0xFFFFFF) nb_bytes = 4;
7764 0 : else if (ptr->sample_count>0xFFFF) nb_bytes = 3;
7765 0 : else if (ptr->sample_count>0xFF) nb_bytes = 2;
7766 0 : ptr->size += ptr->sample_count*nb_bytes;
7767 : }
7768 :
7769 11217 : if (! (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) ) ) {
7770 : return GF_OK;
7771 : }
7772 :
7773 : //if nothing to do, this will be skipped automatically
7774 7208 : if (ptr->flags & GF_ISOM_TRUN_DURATION) ptr->size += 4*ptr->nb_samples;
7775 7208 : if (ptr->flags & GF_ISOM_TRUN_SIZE) ptr->size += 4*ptr->nb_samples;
7776 : //SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
7777 7208 : if (ptr->flags & GF_ISOM_TRUN_FLAGS) ptr->size += 4*ptr->nb_samples;
7778 7208 : if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) ptr->size += 4*ptr->nb_samples;
7779 :
7780 : return GF_OK;
7781 : }
7782 :
7783 :
7784 :
7785 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
7786 :
7787 : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
7788 :
7789 :
7790 4 : void tsro_box_del(GF_Box *s)
7791 : {
7792 : GF_TimeOffHintEntryBox *tsro = (GF_TimeOffHintEntryBox *)s;
7793 4 : gf_free(tsro);
7794 4 : }
7795 :
7796 1 : GF_Err tsro_box_read(GF_Box *s, GF_BitStream *bs)
7797 : {
7798 : GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s;
7799 1 : ISOM_DECREASE_SIZE(ptr, 4);
7800 1 : ptr->TimeOffset = gf_bs_read_u32(bs);
7801 1 : return GF_OK;
7802 : }
7803 :
7804 4 : GF_Box *tsro_box_new()
7805 : {
7806 8 : ISOM_DECL_BOX_ALLOC(GF_TimeOffHintEntryBox, GF_ISOM_BOX_TYPE_TSRO);
7807 4 : return (GF_Box *)tmp;
7808 : }
7809 :
7810 :
7811 : #ifndef GPAC_DISABLE_ISOM_WRITE
7812 2 : GF_Err tsro_box_write(GF_Box *s, GF_BitStream *bs)
7813 : {
7814 : GF_Err e;
7815 : GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s;
7816 2 : if (ptr == NULL) return GF_BAD_PARAM;
7817 :
7818 2 : e = gf_isom_box_write_header(s, bs);
7819 2 : if (e) return e;
7820 2 : gf_bs_write_u32(bs, ptr->TimeOffset);
7821 2 : return GF_OK;
7822 : }
7823 :
7824 4 : GF_Err tsro_box_size(GF_Box *s)
7825 : {
7826 4 : s->size += 4;
7827 4 : return GF_OK;
7828 : }
7829 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
7830 :
7831 :
7832 527 : void udta_box_del(GF_Box *s)
7833 : {
7834 : u32 i;
7835 : GF_UserDataMap *map;
7836 : GF_UserDataBox *ptr = (GF_UserDataBox *)s;
7837 527 : if (ptr == NULL) return;
7838 527 : i=0;
7839 1540 : while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
7840 486 : gf_isom_box_array_del(map->boxes);
7841 486 : gf_free(map);
7842 : }
7843 527 : gf_list_del(ptr->recordList);
7844 527 : gf_free(ptr);
7845 : }
7846 :
7847 1350 : GF_UserDataMap *udta_getEntry(GF_UserDataBox *ptr, u32 box_type, bin128 *uuid)
7848 : {
7849 : u32 i;
7850 : GF_UserDataMap *map;
7851 1350 : if (ptr == NULL) return NULL;
7852 1350 : i=0;
7853 2736 : while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
7854 750 : if (map->boxType == box_type) {
7855 714 : if ((box_type != GF_ISOM_BOX_TYPE_UUID) || !uuid) return map;
7856 0 : if (!memcmp(map->uuid, *uuid, 16)) return map;
7857 : }
7858 : }
7859 : return NULL;
7860 : }
7861 :
7862 533 : GF_Err udta_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
7863 : {
7864 : GF_Err e;
7865 : u32 box_type;
7866 : GF_UserDataMap *map;
7867 : GF_UserDataBox *ptr = (GF_UserDataBox *)s;
7868 533 : if (!ptr) return GF_BAD_PARAM;
7869 533 : if (!a) return GF_OK;
7870 :
7871 : //detach from parent list if any
7872 533 : gf_list_del_item(ptr->child_boxes, a);
7873 :
7874 : /* for unknown udta boxes, we reference them by their original box type */
7875 533 : box_type = a->type;
7876 533 : if (box_type == GF_ISOM_BOX_TYPE_UNKNOWN) {
7877 : GF_UnknownBox* unkn = (GF_UnknownBox *)a;
7878 121 : box_type = unkn->original_4cc;
7879 : }
7880 :
7881 533 : map = udta_getEntry(ptr, box_type, (a->type==GF_ISOM_BOX_TYPE_UUID) ? & ((GF_UUIDBox *)a)->uuid : NULL);
7882 533 : if (map == NULL) {
7883 491 : if (is_rem) return GF_OK;
7884 :
7885 491 : map = (GF_UserDataMap *) gf_malloc(sizeof(GF_UserDataMap));
7886 491 : if (map == NULL) return GF_OUT_OF_MEM;
7887 : memset(map, 0, sizeof(GF_UserDataMap));
7888 :
7889 491 : map->boxType = box_type;
7890 491 : if (a->type == GF_ISOM_BOX_TYPE_UUID)
7891 0 : memcpy(map->uuid, ((GF_UUIDBox *)a)->uuid, 16);
7892 491 : map->boxes = gf_list_new();
7893 491 : if (!map->boxes) {
7894 0 : gf_free(map);
7895 0 : return GF_OUT_OF_MEM;
7896 : }
7897 491 : e = gf_list_add(ptr->recordList, map);
7898 491 : if (e) return e;
7899 : }
7900 533 : if (is_rem) {
7901 0 : gf_list_del_item(map->boxes, a);
7902 0 : return GF_OK;
7903 : }
7904 533 : return gf_list_add(map->boxes, a);
7905 : }
7906 :
7907 :
7908 343 : GF_Err udta_box_read(GF_Box *s, GF_BitStream *bs)
7909 : {
7910 343 : GF_Err e = gf_isom_box_array_read(s, bs);
7911 343 : if (e) return e;
7912 343 : if (s->size==4) {
7913 7 : u32 val = gf_bs_read_u32(bs);
7914 7 : s->size = 0;
7915 7 : if (val) {
7916 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] udta has 4 remaining bytes set to %08X but they should be 0\n", val));
7917 : }
7918 : }
7919 : return GF_OK;
7920 : }
7921 :
7922 527 : GF_Box *udta_box_new()
7923 : {
7924 1054 : ISOM_DECL_BOX_ALLOC(GF_UserDataBox, GF_ISOM_BOX_TYPE_UDTA);
7925 527 : tmp->recordList = gf_list_new();
7926 527 : if (!tmp->recordList) {
7927 0 : gf_free(tmp);
7928 0 : return NULL;
7929 : }
7930 : return (GF_Box *)tmp;
7931 : }
7932 :
7933 :
7934 : #ifndef GPAC_DISABLE_ISOM_WRITE
7935 :
7936 414 : GF_Err udta_box_write(GF_Box *s, GF_BitStream *bs)
7937 : {
7938 : GF_Err e;
7939 : u32 i;
7940 : GF_UserDataMap *map;
7941 : GF_UserDataBox *ptr = (GF_UserDataBox *)s;
7942 :
7943 414 : e = gf_isom_box_write_header(s, bs);
7944 414 : if (e) return e;
7945 414 : i=0;
7946 1213 : while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
7947 : //warning: here we are not passing the actual "parent" of the list
7948 : //but the UDTA box. The parent itself is not an box, we don't care about it
7949 385 : e = gf_isom_box_array_write(s, map->boxes, bs);
7950 385 : if (e) return e;
7951 : }
7952 : return GF_OK;
7953 : }
7954 :
7955 986 : GF_Err udta_box_size(GF_Box *s)
7956 : {
7957 : GF_Err e;
7958 : u32 i;
7959 : GF_UserDataMap *map;
7960 : GF_UserDataBox *ptr = (GF_UserDataBox *)s;
7961 :
7962 986 : i=0;
7963 2923 : while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
7964 : //warning: here we are not passing the actual "parent" of the list
7965 : //but the UDTA box. The parent itself is not an box, we don't care about it
7966 951 : e = gf_isom_box_array_size(s, map->boxes);
7967 951 : if (e) return e;
7968 : }
7969 : return GF_OK;
7970 : }
7971 :
7972 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
7973 :
7974 :
7975 2349 : void vmhd_box_del(GF_Box *s)
7976 : {
7977 : GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
7978 2349 : if (ptr == NULL) return;
7979 2349 : gf_free(ptr);
7980 : }
7981 :
7982 :
7983 1810 : GF_Err vmhd_box_read(GF_Box *s, GF_BitStream *bs)
7984 : {
7985 : GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
7986 :
7987 1810 : ISOM_DECREASE_SIZE(ptr, 8);
7988 1810 : ptr->reserved = gf_bs_read_u64(bs);
7989 1810 : return GF_OK;
7990 : }
7991 :
7992 2349 : GF_Box *vmhd_box_new()
7993 : {
7994 4698 : ISOM_DECL_BOX_ALLOC(GF_VideoMediaHeaderBox, GF_ISOM_BOX_TYPE_VMHD);
7995 2349 : tmp->flags = 1;
7996 2349 : return (GF_Box *)tmp;
7997 : }
7998 :
7999 :
8000 :
8001 : #ifndef GPAC_DISABLE_ISOM_WRITE
8002 :
8003 1888 : GF_Err vmhd_box_write(GF_Box *s, GF_BitStream *bs)
8004 : {
8005 : GF_Err e;
8006 : GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
8007 :
8008 1888 : e = gf_isom_full_box_write(s, bs);
8009 1888 : if (e) return e;
8010 1888 : gf_bs_write_u64(bs, ptr->reserved);
8011 1888 : return GF_OK;
8012 : }
8013 :
8014 3375 : GF_Err vmhd_box_size(GF_Box *s)
8015 : {
8016 : GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
8017 3375 : ptr->size += 8;
8018 3375 : return GF_OK;
8019 : }
8020 :
8021 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8022 :
8023 2 : void void_box_del(GF_Box *s)
8024 : {
8025 2 : gf_free(s);
8026 2 : }
8027 :
8028 :
8029 0 : GF_Err void_box_read(GF_Box *s, GF_BitStream *bs)
8030 : {
8031 0 : if (s->size) return GF_ISOM_INVALID_FILE;
8032 0 : return GF_OK;
8033 : }
8034 :
8035 2 : GF_Box *void_box_new()
8036 : {
8037 4 : ISOM_DECL_BOX_ALLOC(GF_Box, GF_ISOM_BOX_TYPE_VOID);
8038 2 : return tmp;
8039 : }
8040 :
8041 :
8042 : #ifndef GPAC_DISABLE_ISOM_WRITE
8043 :
8044 1 : GF_Err void_box_write(GF_Box *s, GF_BitStream *bs)
8045 : {
8046 1 : gf_bs_write_u32(bs, 0);
8047 1 : return GF_OK;
8048 : }
8049 :
8050 1 : GF_Err void_box_size(GF_Box *s)
8051 : {
8052 1 : s->size = 4;
8053 1 : return GF_OK;
8054 : }
8055 :
8056 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8057 :
8058 :
8059 :
8060 3 : GF_Box *pdin_box_new()
8061 : {
8062 6 : ISOM_DECL_BOX_ALLOC(GF_ProgressiveDownloadBox, GF_ISOM_BOX_TYPE_PDIN);
8063 3 : return (GF_Box *)tmp;
8064 : }
8065 :
8066 :
8067 3 : void pdin_box_del(GF_Box *s)
8068 : {
8069 : GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s;
8070 3 : if (ptr == NULL) return;
8071 3 : if (ptr->rates) gf_free(ptr->rates);
8072 3 : if (ptr->times) gf_free(ptr->times);
8073 3 : gf_free(ptr);
8074 : }
8075 :
8076 :
8077 1 : GF_Err pdin_box_read(GF_Box *s, GF_BitStream *bs)
8078 : {
8079 : u32 i;
8080 : GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s;
8081 :
8082 1 : ptr->count = (u32) (ptr->size) / 8;
8083 1 : ptr->rates = (u32*)gf_malloc(sizeof(u32)*ptr->count);
8084 1 : if (!ptr->rates) return GF_OUT_OF_MEM;
8085 1 : ptr->times = (u32*)gf_malloc(sizeof(u32)*ptr->count);
8086 1 : if (!ptr->times) return GF_OUT_OF_MEM;
8087 0 : for (i=0; i<ptr->count; i++) {
8088 0 : ptr->rates[i] = gf_bs_read_u32(bs);
8089 0 : ptr->times[i] = gf_bs_read_u32(bs);
8090 : }
8091 : return GF_OK;
8092 : }
8093 :
8094 :
8095 : #ifndef GPAC_DISABLE_ISOM_WRITE
8096 :
8097 1 : GF_Err pdin_box_write(GF_Box *s, GF_BitStream *bs)
8098 : {
8099 : GF_Err e;
8100 : u32 i;
8101 : GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s;
8102 1 : e = gf_isom_full_box_write(s, bs);
8103 1 : if (e) return e;
8104 0 : for (i=0; i<ptr->count; i++) {
8105 0 : gf_bs_write_u32(bs, ptr->rates[i]);
8106 0 : gf_bs_write_u32(bs, ptr->times[i]);
8107 : }
8108 : return GF_OK;
8109 : }
8110 :
8111 1 : GF_Err pdin_box_size(GF_Box *s)
8112 : {
8113 : GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s;
8114 1 : ptr->size += 8*ptr->count;
8115 1 : return GF_OK;
8116 : }
8117 :
8118 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8119 :
8120 :
8121 :
8122 :
8123 17308 : GF_Box *sdtp_box_new()
8124 : {
8125 34616 : ISOM_DECL_BOX_ALLOC(GF_SampleDependencyTypeBox, GF_ISOM_BOX_TYPE_SDTP);
8126 17308 : return (GF_Box *)tmp;
8127 : }
8128 :
8129 :
8130 17308 : void sdtp_box_del(GF_Box *s)
8131 : {
8132 : GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s;
8133 17308 : if (ptr == NULL) return;
8134 17308 : if (ptr->sample_info) gf_free(ptr->sample_info);
8135 17308 : gf_free(ptr);
8136 : }
8137 :
8138 :
8139 47 : GF_Err sdtp_box_read(GF_Box *s, GF_BitStream *bs)
8140 : {
8141 : GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s;
8142 :
8143 : /*out-of-order sdtp, assume no padding at the end*/
8144 47 : if (!ptr->sampleCount) ptr->sampleCount = (u32) ptr->size;
8145 0 : else if (ptr->sampleCount > (u32) ptr->size) return GF_ISOM_INVALID_FILE;
8146 :
8147 47 : ptr->sample_info = (u8 *) gf_malloc(sizeof(u8)*ptr->sampleCount);
8148 47 : if (!ptr->sample_info) return GF_OUT_OF_MEM;
8149 47 : ptr->sample_alloc = ptr->sampleCount;
8150 47 : gf_bs_read_data(bs, (char*)ptr->sample_info, ptr->sampleCount);
8151 47 : ISOM_DECREASE_SIZE(ptr, ptr->sampleCount);
8152 47 : return GF_OK;
8153 : }
8154 :
8155 :
8156 : #ifndef GPAC_DISABLE_ISOM_WRITE
8157 :
8158 13 : GF_Err sdtp_box_write(GF_Box *s, GF_BitStream *bs)
8159 : {
8160 : GF_Err e;
8161 : GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s;
8162 13 : e = gf_isom_full_box_write(s, bs);
8163 13 : if (e) return e;
8164 13 : gf_bs_write_data(bs, (char*)ptr->sample_info, ptr->sampleCount);
8165 13 : return GF_OK;
8166 : }
8167 :
8168 37 : GF_Err sdtp_box_size(GF_Box *s)
8169 : {
8170 : GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s;
8171 37 : ptr->size += ptr->sampleCount;
8172 37 : return GF_OK;
8173 : }
8174 :
8175 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8176 :
8177 :
8178 271 : GF_Box *pasp_box_new()
8179 : {
8180 542 : ISOM_DECL_BOX_ALLOC(GF_PixelAspectRatioBox, GF_ISOM_BOX_TYPE_PASP);
8181 271 : return (GF_Box *)tmp;
8182 : }
8183 :
8184 :
8185 271 : void pasp_box_del(GF_Box *s)
8186 : {
8187 : GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s;
8188 271 : if (ptr == NULL) return;
8189 271 : gf_free(ptr);
8190 : }
8191 :
8192 :
8193 116 : GF_Err pasp_box_read(GF_Box *s, GF_BitStream *bs)
8194 : {
8195 : GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s;
8196 116 : ISOM_DECREASE_SIZE(ptr, 8);
8197 116 : ptr->hSpacing = gf_bs_read_u32(bs);
8198 116 : ptr->vSpacing = gf_bs_read_u32(bs);
8199 116 : return GF_OK;
8200 : }
8201 :
8202 :
8203 : #ifndef GPAC_DISABLE_ISOM_WRITE
8204 :
8205 198 : GF_Err pasp_box_write(GF_Box *s, GF_BitStream *bs)
8206 : {
8207 : GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox *)s;
8208 198 : GF_Err e = gf_isom_box_write_header(s, bs);
8209 198 : if (e) return e;
8210 198 : gf_bs_write_u32(bs, ptr->hSpacing);
8211 198 : gf_bs_write_u32(bs, ptr->vSpacing);
8212 198 : return GF_OK;
8213 : }
8214 :
8215 500 : GF_Err pasp_box_size(GF_Box *s)
8216 : {
8217 500 : s->size += 8;
8218 500 : return GF_OK;
8219 : }
8220 :
8221 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8222 :
8223 :
8224 :
8225 14 : GF_Box *clap_box_new()
8226 : {
8227 28 : ISOM_DECL_BOX_ALLOC(GF_CleanApertureBox, GF_ISOM_BOX_TYPE_CLAP);
8228 14 : return (GF_Box *)tmp;
8229 : }
8230 :
8231 :
8232 14 : void clap_box_del(GF_Box *s)
8233 : {
8234 : GF_CleanApertureBox *ptr = (GF_CleanApertureBox*)s;
8235 14 : if (ptr == NULL) return;
8236 14 : gf_free(ptr);
8237 : }
8238 :
8239 :
8240 1 : GF_Err clap_box_read(GF_Box *s, GF_BitStream *bs)
8241 : {
8242 : GF_CleanApertureBox *ptr = (GF_CleanApertureBox*)s;
8243 1 : ISOM_DECREASE_SIZE(ptr, 32);
8244 1 : ptr->cleanApertureWidthN = gf_bs_read_u32(bs);
8245 1 : ptr->cleanApertureWidthD = gf_bs_read_u32(bs);
8246 1 : ptr->cleanApertureHeightN = gf_bs_read_u32(bs);
8247 1 : ptr->cleanApertureHeightD = gf_bs_read_u32(bs);
8248 1 : ptr->horizOffN = gf_bs_read_u32(bs);
8249 1 : ptr->horizOffD = gf_bs_read_u32(bs);
8250 1 : ptr->vertOffN = gf_bs_read_u32(bs);
8251 1 : ptr->vertOffD = gf_bs_read_u32(bs);
8252 1 : return GF_OK;
8253 : }
8254 :
8255 :
8256 : #ifndef GPAC_DISABLE_ISOM_WRITE
8257 :
8258 12 : GF_Err clap_box_write(GF_Box *s, GF_BitStream *bs)
8259 : {
8260 : GF_CleanApertureBox *ptr = (GF_CleanApertureBox *)s;
8261 12 : GF_Err e = gf_isom_box_write_header(s, bs);
8262 12 : if (e) return e;
8263 12 : gf_bs_write_u32(bs, ptr->cleanApertureWidthN);
8264 12 : gf_bs_write_u32(bs, ptr->cleanApertureWidthD);
8265 12 : gf_bs_write_u32(bs, ptr->cleanApertureHeightN);
8266 12 : gf_bs_write_u32(bs, ptr->cleanApertureHeightD);
8267 12 : gf_bs_write_u32(bs, ptr->horizOffN);
8268 12 : gf_bs_write_u32(bs, ptr->horizOffD);
8269 12 : gf_bs_write_u32(bs, ptr->vertOffN);
8270 12 : gf_bs_write_u32(bs, ptr->vertOffD);
8271 12 : return GF_OK;
8272 : }
8273 :
8274 34 : GF_Err clap_box_size(GF_Box *s)
8275 : {
8276 34 : s->size += 32;
8277 34 : return GF_OK;
8278 : }
8279 :
8280 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8281 :
8282 :
8283 :
8284 :
8285 137 : GF_Box *metx_box_new()
8286 : {
8287 : //type is overridden by the box constructor
8288 274 : ISOM_DECL_BOX_ALLOC(GF_MetaDataSampleEntryBox, GF_ISOM_BOX_TYPE_METX);
8289 137 : gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
8290 137 : return (GF_Box *)tmp;
8291 : }
8292 :
8293 :
8294 137 : void metx_box_del(GF_Box *s)
8295 : {
8296 : GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s;
8297 137 : if (ptr == NULL) return;
8298 137 : gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
8299 :
8300 137 : if (ptr->content_encoding) gf_free(ptr->content_encoding);
8301 137 : if (ptr->xml_namespace) gf_free(ptr->xml_namespace);
8302 137 : if (ptr->xml_schema_loc) gf_free(ptr->xml_schema_loc);
8303 137 : if (ptr->mime_type) gf_free(ptr->mime_type);
8304 137 : gf_free(ptr);
8305 : }
8306 :
8307 :
8308 71 : GF_Err metx_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
8309 : {
8310 : GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
8311 71 : switch (a->type) {
8312 8 : case GF_ISOM_BOX_TYPE_TXTC:
8313 : //we allow the config box on metx
8314 8 : BOX_FIELD_ASSIGN(config, GF_TextConfigBox)
8315 8 : break;
8316 : }
8317 : return GF_OK;
8318 : }
8319 :
8320 80 : GF_Err metx_box_read(GF_Box *s, GF_BitStream *bs)
8321 : {
8322 : u32 size, i;
8323 : GF_Err e;
8324 : char *str;
8325 : GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s;
8326 :
8327 80 : e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
8328 80 : if (e) return e;
8329 80 : ISOM_DECREASE_SIZE(ptr, 8);
8330 :
8331 80 : size = (u32) ptr->size;
8332 80 : str = gf_malloc(sizeof(char)*size);
8333 80 : if (!str) return GF_OUT_OF_MEM;
8334 :
8335 : i=0;
8336 :
8337 1091 : while (size) {
8338 1091 : str[i] = gf_bs_read_u8(bs);
8339 1091 : size--;
8340 1091 : if (!str[i]) {
8341 80 : i++;
8342 80 : break;
8343 : }
8344 1011 : i++;
8345 : }
8346 80 : if (!size && i>1 && str[i-1]) {
8347 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n"));
8348 0 : gf_free(str);
8349 0 : return GF_ISOM_INVALID_FILE;
8350 : }
8351 80 : if (i>1) {
8352 55 : if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
8353 35 : ptr->xml_namespace = gf_strdup(str);
8354 : } else {
8355 20 : ptr->content_encoding = gf_strdup(str);
8356 : }
8357 : }
8358 :
8359 : i=0;
8360 672 : while (size) {
8361 672 : str[i] = gf_bs_read_u8(bs);
8362 672 : size--;
8363 672 : if (!str[i]) {
8364 80 : i++;
8365 80 : break;
8366 : }
8367 592 : i++;
8368 : }
8369 80 : if (!size && i>1 && str[i-1]) {
8370 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n"));
8371 0 : gf_free(str);
8372 0 : return GF_ISOM_INVALID_FILE;
8373 : }
8374 80 : if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {
8375 41 : if (i>1) {
8376 8 : if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
8377 4 : ptr->xml_schema_loc = gf_strdup(str);
8378 : } else {
8379 4 : ptr->xml_namespace = gf_strdup(str);
8380 : }
8381 : }
8382 :
8383 : i=0;
8384 137 : while (size) {
8385 137 : str[i] = gf_bs_read_u8(bs);
8386 137 : size--;
8387 137 : if (!str[i]) {
8388 41 : i++;
8389 41 : break;
8390 : }
8391 96 : i++;
8392 : }
8393 41 : if (!size && i>1 && str[i-1]) {
8394 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n"));
8395 0 : gf_free(str);
8396 0 : return GF_ISOM_INVALID_FILE;
8397 : }
8398 41 : if (i>1) {
8399 4 : if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
8400 0 : ptr->mime_type = gf_strdup(str);
8401 : } else {
8402 4 : ptr->xml_schema_loc = gf_strdup(str);
8403 : }
8404 : }
8405 : }
8406 : //mett, sbtt, stxt, stpp
8407 : else {
8408 39 : if (i>1) ptr->mime_type = gf_strdup(str);
8409 : }
8410 80 : ptr->size = size;
8411 80 : gf_free(str);
8412 80 : return gf_isom_box_array_read(s, bs);
8413 : }
8414 :
8415 :
8416 : #ifndef GPAC_DISABLE_ISOM_WRITE
8417 :
8418 101 : GF_Err metx_box_write(GF_Box *s, GF_BitStream *bs)
8419 : {
8420 : GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
8421 101 : GF_Err e = gf_isom_box_write_header(s, bs);
8422 101 : if (e) return e;
8423 :
8424 101 : gf_bs_write_data(bs, ptr->reserved, 6);
8425 101 : gf_bs_write_u16(bs, ptr->dataReferenceIndex);
8426 :
8427 101 : if (ptr->type!=GF_ISOM_BOX_TYPE_STPP) {
8428 61 : if (ptr->content_encoding)
8429 25 : gf_bs_write_data(bs, ptr->content_encoding, (u32) strlen(ptr->content_encoding));
8430 61 : gf_bs_write_u8(bs, 0);
8431 : }
8432 :
8433 101 : if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {
8434 46 : if (ptr->xml_namespace)
8435 44 : gf_bs_write_data(bs, ptr->xml_namespace, (u32) strlen(ptr->xml_namespace));
8436 :
8437 46 : gf_bs_write_u8(bs, 0);
8438 :
8439 46 : if (ptr->xml_schema_loc)
8440 10 : gf_bs_write_data(bs, ptr->xml_schema_loc, (u32) strlen(ptr->xml_schema_loc));
8441 46 : gf_bs_write_u8(bs, 0);
8442 :
8443 46 : if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
8444 40 : if (ptr->mime_type)
8445 1 : gf_bs_write_data(bs, ptr->mime_type, (u32) strlen(ptr->mime_type));
8446 :
8447 40 : gf_bs_write_u8(bs, 0);
8448 : }
8449 : }
8450 : //mett, sbtt, stxt
8451 : else {
8452 55 : if (ptr->mime_type)
8453 52 : gf_bs_write_data(bs, ptr->mime_type, (u32) strlen(ptr->mime_type));
8454 :
8455 55 : gf_bs_write_u8(bs, 0);
8456 : }
8457 :
8458 : return GF_OK;
8459 : }
8460 :
8461 202 : GF_Err metx_box_size(GF_Box *s)
8462 : {
8463 : GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
8464 202 : ptr->size += 8;
8465 :
8466 202 : if (ptr->type!=GF_ISOM_BOX_TYPE_STPP) {
8467 116 : if (ptr->content_encoding)
8468 45 : ptr->size += strlen(ptr->content_encoding);
8469 116 : ptr->size++;
8470 : }
8471 :
8472 202 : if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {
8473 :
8474 96 : if (ptr->xml_namespace)
8475 94 : ptr->size += strlen(ptr->xml_namespace);
8476 96 : ptr->size++;
8477 :
8478 96 : if (ptr->xml_schema_loc)
8479 18 : ptr->size += strlen(ptr->xml_schema_loc);
8480 96 : ptr->size++;
8481 :
8482 96 : if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
8483 86 : if (ptr->mime_type)
8484 3 : ptr->size += strlen(ptr->mime_type);
8485 86 : ptr->size++;
8486 : }
8487 :
8488 : }
8489 : //mett, sbtt, stxt
8490 : else {
8491 106 : if (ptr->mime_type)
8492 103 : ptr->size += strlen(ptr->mime_type);
8493 106 : ptr->size++;
8494 : }
8495 202 : return GF_OK;
8496 : }
8497 :
8498 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8499 :
8500 :
8501 : /* SimpleTextSampleEntry */
8502 24 : GF_Box *txtc_box_new()
8503 : {
8504 48 : ISOM_DECL_BOX_ALLOC(GF_TextConfigBox, GF_ISOM_BOX_TYPE_TXTC);
8505 24 : return (GF_Box *)tmp;
8506 : }
8507 :
8508 :
8509 24 : void txtc_box_del(GF_Box *s)
8510 : {
8511 : GF_TextConfigBox *ptr = (GF_TextConfigBox*)s;
8512 24 : if (ptr == NULL) return;
8513 :
8514 24 : if (ptr->config) gf_free(ptr->config);
8515 24 : gf_free(ptr);
8516 : }
8517 :
8518 10 : GF_Err txtc_box_read(GF_Box *s, GF_BitStream *bs)
8519 : {
8520 : GF_TextConfigBox *ptr = (GF_TextConfigBox*)s;
8521 10 : ptr->config = (char *)gf_malloc(sizeof(char)*((u32) ptr->size+1));
8522 10 : if (!ptr->config) return GF_OUT_OF_MEM;
8523 10 : gf_bs_read_data(bs, ptr->config, (u32) ptr->size);
8524 10 : ptr->config[ptr->size] = 0;
8525 10 : return GF_OK;
8526 : }
8527 :
8528 :
8529 : #ifndef GPAC_DISABLE_ISOM_WRITE
8530 :
8531 18 : GF_Err txtc_box_write(GF_Box *s, GF_BitStream *bs)
8532 : {
8533 : GF_TextConfigBox *ptr = (GF_TextConfigBox *)s;
8534 18 : GF_Err e = gf_isom_full_box_write(s, bs);
8535 18 : if (e) return e;
8536 :
8537 18 : if (ptr->config)
8538 16 : gf_bs_write_data(bs, ptr->config, (u32) strlen(ptr->config));
8539 18 : gf_bs_write_u8(bs, 0);
8540 18 : return GF_OK;
8541 : }
8542 :
8543 39 : GF_Err txtc_box_size(GF_Box *s)
8544 : {
8545 : GF_TextConfigBox *ptr = (GF_TextConfigBox *)s;
8546 39 : if (ptr->config)
8547 37 : ptr->size += strlen(ptr->config);
8548 39 : ptr->size++;
8549 39 : return GF_OK;
8550 : }
8551 :
8552 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8553 :
8554 27 : GF_Box *dac3_box_new()
8555 : {
8556 54 : ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3);
8557 27 : return (GF_Box *)tmp;
8558 : }
8559 :
8560 10 : GF_Box *dec3_box_new()
8561 : {
8562 20 : ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3);
8563 10 : tmp->cfg.is_ec3 = 1;
8564 10 : return (GF_Box *)tmp;
8565 : }
8566 :
8567 37 : void dac3_box_del(GF_Box *s)
8568 : {
8569 : GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
8570 37 : gf_free(ptr);
8571 37 : }
8572 :
8573 :
8574 22 : GF_Err dac3_box_read(GF_Box *s, GF_BitStream *bs)
8575 : {
8576 : GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
8577 22 : if (ptr == NULL) return GF_BAD_PARAM;
8578 22 : return gf_odf_ac3_config_parse_bs(bs, ptr->cfg.is_ec3, &ptr->cfg);
8579 : }
8580 :
8581 :
8582 : #ifndef GPAC_DISABLE_ISOM_WRITE
8583 :
8584 23 : GF_Err dac3_box_write(GF_Box *s, GF_BitStream *bs)
8585 : {
8586 : GF_Err e;
8587 : GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
8588 :
8589 23 : if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DEC3;
8590 23 : e = gf_isom_box_write_header(s, bs);
8591 23 : if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DAC3;
8592 23 : if (e) return e;
8593 :
8594 23 : return gf_odf_ac3_cfg_write_bs(&ptr->cfg, bs);
8595 : }
8596 :
8597 45 : GF_Err dac3_box_size(GF_Box *s)
8598 : {
8599 : GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
8600 :
8601 45 : if (ptr->cfg.is_ec3) {
8602 : u32 i;
8603 9 : s->size += 2;
8604 17 : for (i=0; i<ptr->cfg.nb_streams; i++) {
8605 8 : s->size += 3;
8606 8 : if (ptr->cfg.streams[i].nb_dep_sub)
8607 0 : s->size += 1;
8608 : }
8609 : } else {
8610 36 : s->size += 3;
8611 : }
8612 45 : return GF_OK;
8613 : }
8614 :
8615 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8616 :
8617 :
8618 :
8619 9 : void lsrc_box_del(GF_Box *s)
8620 : {
8621 : GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
8622 9 : if (ptr == NULL) return;
8623 9 : if (ptr->hdr) gf_free(ptr->hdr);
8624 9 : gf_free(ptr);
8625 : }
8626 :
8627 :
8628 4 : GF_Err lsrc_box_read(GF_Box *s, GF_BitStream *bs)
8629 : {
8630 : GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
8631 4 : ptr->hdr_size = (u32) ptr->size;
8632 4 : ptr->hdr = gf_malloc(sizeof(char)*ptr->hdr_size);
8633 4 : if (!ptr->hdr) return GF_OUT_OF_MEM;
8634 4 : gf_bs_read_data(bs, ptr->hdr, ptr->hdr_size);
8635 4 : return GF_OK;
8636 : }
8637 :
8638 9 : GF_Box *lsrc_box_new()
8639 : {
8640 18 : ISOM_DECL_BOX_ALLOC(GF_LASERConfigurationBox, GF_ISOM_BOX_TYPE_LSRC);
8641 9 : return (GF_Box *)tmp;
8642 : }
8643 :
8644 :
8645 : #ifndef GPAC_DISABLE_ISOM_WRITE
8646 :
8647 3 : GF_Err lsrc_box_write(GF_Box *s, GF_BitStream *bs)
8648 : {
8649 : GF_Err e;
8650 : GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
8651 3 : e = gf_isom_box_write_header(s, bs);
8652 3 : if (e) return e;
8653 3 : gf_bs_write_data(bs, ptr->hdr, ptr->hdr_size);
8654 3 : return GF_OK;
8655 : }
8656 :
8657 5 : GF_Err lsrc_box_size(GF_Box *s)
8658 : {
8659 : GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
8660 5 : ptr->size += ptr->hdr_size;
8661 5 : return GF_OK;
8662 : }
8663 :
8664 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8665 :
8666 :
8667 9 : void lsr1_box_del(GF_Box *s)
8668 : {
8669 : GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
8670 9 : if (ptr == NULL) return;
8671 9 : gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
8672 9 : if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
8673 9 : gf_free(ptr);
8674 : }
8675 :
8676 6 : GF_Err lsr1_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
8677 : {
8678 : GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
8679 6 : switch (a->type) {
8680 3 : case GF_ISOM_BOX_TYPE_LSRC:
8681 3 : BOX_FIELD_ASSIGN(lsr_config, GF_LASERConfigurationBox)
8682 3 : break;
8683 0 : case GF_ISOM_BOX_TYPE_M4DS:
8684 0 : BOX_FIELD_ASSIGN(descr, GF_MPEG4ExtensionDescriptorsBox)
8685 0 : break;
8686 : }
8687 : return GF_OK;
8688 : }
8689 :
8690 4 : GF_Err lsr1_box_read(GF_Box *s, GF_BitStream *bs)
8691 : {
8692 : GF_Err e;
8693 : GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox*)s;
8694 :
8695 4 : e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
8696 4 : if (e) return e;
8697 :
8698 4 : ISOM_DECREASE_SIZE(ptr, 8);
8699 :
8700 4 : return gf_isom_box_array_read(s, bs);
8701 : }
8702 :
8703 9 : GF_Box *lsr1_box_new()
8704 : {
8705 18 : ISOM_DECL_BOX_ALLOC(GF_LASeRSampleEntryBox, GF_ISOM_BOX_TYPE_LSR1);
8706 9 : gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
8707 9 : return (GF_Box *)tmp;
8708 : }
8709 :
8710 :
8711 : #ifndef GPAC_DISABLE_ISOM_WRITE
8712 :
8713 :
8714 3 : GF_Err lsr1_box_write(GF_Box *s, GF_BitStream *bs)
8715 : {
8716 : GF_Err e;
8717 : GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
8718 3 : e = gf_isom_box_write_header(s, bs);
8719 3 : if (e) return e;
8720 :
8721 3 : gf_bs_write_data(bs, ptr->reserved, 6);
8722 3 : gf_bs_write_u16(bs, ptr->dataReferenceIndex);
8723 3 : return GF_OK;
8724 : }
8725 :
8726 5 : GF_Err lsr1_box_size(GF_Box *s)
8727 : {
8728 5 : u32 pos=0;
8729 : GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
8730 5 : s->size += 8;
8731 5 : gf_isom_check_position(s, (GF_Box *)ptr->lsr_config, &pos);
8732 5 : return GF_OK;
8733 : }
8734 :
8735 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8736 :
8737 :
8738 4557 : void sidx_box_del(GF_Box *s)
8739 : {
8740 : GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox *) s;
8741 4557 : if (ptr == NULL) return;
8742 4557 : if (ptr->refs) gf_free(ptr->refs);
8743 4557 : gf_free(ptr);
8744 : }
8745 :
8746 2462 : GF_Err sidx_box_read(GF_Box *s,GF_BitStream *bs)
8747 : {
8748 : u32 i;
8749 : GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;
8750 :
8751 2462 : ISOM_DECREASE_SIZE(ptr, 8);
8752 2462 : ptr->reference_ID = gf_bs_read_u32(bs);
8753 2462 : ptr->timescale = gf_bs_read_u32(bs);
8754 :
8755 2462 : if (ptr->version==0) {
8756 2462 : ISOM_DECREASE_SIZE(ptr, 8);
8757 2462 : ptr->earliest_presentation_time = gf_bs_read_u32(bs);
8758 2462 : ptr->first_offset = gf_bs_read_u32(bs);
8759 : } else {
8760 0 : ISOM_DECREASE_SIZE(ptr, 16);
8761 0 : ptr->earliest_presentation_time = gf_bs_read_u64(bs);
8762 0 : ptr->first_offset = gf_bs_read_u64(bs);
8763 : }
8764 2462 : ISOM_DECREASE_SIZE(ptr, 4);
8765 2462 : gf_bs_read_u16(bs); /* reserved */
8766 2462 : ptr->nb_refs = gf_bs_read_u16(bs);
8767 :
8768 2462 : ptr->refs = gf_malloc(sizeof(GF_SIDXReference)*ptr->nb_refs);
8769 2462 : if (!ptr->refs) return GF_OUT_OF_MEM;
8770 3340 : for (i=0; i<ptr->nb_refs; i++) {
8771 3340 : ptr->refs[i].reference_type = gf_bs_read_int(bs, 1);
8772 3340 : ptr->refs[i].reference_size = gf_bs_read_int(bs, 31);
8773 3340 : ptr->refs[i].subsegment_duration = gf_bs_read_u32(bs);
8774 3340 : ptr->refs[i].starts_with_SAP = gf_bs_read_int(bs, 1);
8775 3340 : ptr->refs[i].SAP_type = gf_bs_read_int(bs, 3);
8776 3340 : ptr->refs[i].SAP_delta_time = gf_bs_read_int(bs, 28);
8777 :
8778 3340 : ISOM_DECREASE_SIZE(ptr, 12);
8779 : }
8780 : return GF_OK;
8781 : }
8782 :
8783 4557 : GF_Box *sidx_box_new()
8784 : {
8785 9114 : ISOM_DECL_BOX_ALLOC(GF_SegmentIndexBox, GF_ISOM_BOX_TYPE_SIDX);
8786 4557 : return (GF_Box *)tmp;
8787 : }
8788 :
8789 :
8790 : #ifndef GPAC_DISABLE_ISOM_WRITE
8791 :
8792 4253 : GF_Err sidx_box_write(GF_Box *s, GF_BitStream *bs)
8793 : {
8794 : GF_Err e;
8795 : u32 i;
8796 : GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;
8797 :
8798 4253 : e = gf_isom_full_box_write(s, bs);
8799 4253 : if (e) return e;
8800 :
8801 4253 : gf_bs_write_u32(bs, ptr->reference_ID);
8802 4253 : gf_bs_write_u32(bs, ptr->timescale);
8803 4253 : if (ptr->version==0) {
8804 4253 : gf_bs_write_u32(bs, (u32) ptr->earliest_presentation_time);
8805 4253 : gf_bs_write_u32(bs, (u32) ptr->first_offset);
8806 : } else {
8807 0 : gf_bs_write_u64(bs, ptr->earliest_presentation_time);
8808 0 : gf_bs_write_u64(bs, ptr->first_offset);
8809 : }
8810 4253 : gf_bs_write_u16(bs, 0);
8811 4253 : gf_bs_write_u16(bs, ptr->nb_refs);
8812 9056 : for (i=0; i<ptr->nb_refs; i++ ) {
8813 4803 : gf_bs_write_int(bs, ptr->refs[i].reference_type, 1);
8814 4803 : gf_bs_write_int(bs, ptr->refs[i].reference_size, 31);
8815 4803 : gf_bs_write_u32(bs, ptr->refs[i].subsegment_duration);
8816 4803 : gf_bs_write_int(bs, ptr->refs[i].starts_with_SAP, 1);
8817 4803 : gf_bs_write_int(bs, ptr->refs[i].SAP_type, 3);
8818 4803 : gf_bs_write_int(bs, ptr->refs[i].SAP_delta_time, 28);
8819 : }
8820 : return GF_OK;
8821 : }
8822 :
8823 2179 : GF_Err sidx_box_size(GF_Box *s)
8824 : {
8825 : GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;
8826 :
8827 2179 : ptr->size += 12;
8828 2179 : if (ptr->version==0) {
8829 2179 : ptr->size += 8;
8830 : } else {
8831 0 : ptr->size += 16;
8832 : }
8833 2179 : ptr->size += ptr->nb_refs * 12;
8834 2179 : return GF_OK;
8835 : }
8836 :
8837 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8838 :
8839 4 : void ssix_box_del(GF_Box *s)
8840 : {
8841 : u32 i;
8842 : GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox *)s;
8843 4 : if (ptr == NULL) return;
8844 4 : if (ptr->subsegments) {
8845 30 : for (i = 0; i < ptr->subsegment_alloc; i++) {
8846 30 : GF_SubsegmentInfo *subsegment = &ptr->subsegments[i];
8847 30 : if (subsegment->ranges) gf_free(subsegment->ranges);
8848 : }
8849 2 : gf_free(ptr->subsegments);
8850 : }
8851 4 : gf_free(ptr);
8852 : }
8853 :
8854 1 : GF_Err ssix_box_read(GF_Box *s, GF_BitStream *bs)
8855 : {
8856 : u32 i,j;
8857 : GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;
8858 :
8859 1 : ISOM_DECREASE_SIZE(ptr, 4)
8860 1 : ptr->subsegment_count = gf_bs_read_u32(bs);
8861 : //each subseg has at least one range_count (4 bytes), abort if not enough bytes (broken box)
8862 1 : if (ptr->size / 4 < ptr->subsegment_count)
8863 : return GF_ISOM_INVALID_FILE;
8864 :
8865 1 : ptr->subsegment_alloc = ptr->subsegment_count;
8866 1 : GF_SAFE_ALLOC_N(ptr->subsegments, ptr->subsegment_count, GF_SubsegmentInfo);
8867 1 : if (!ptr->subsegments)
8868 : return GF_OUT_OF_MEM;
8869 0 : for (i = 0; i < ptr->subsegment_count; i++) {
8870 0 : GF_SubsegmentInfo *subseg = &ptr->subsegments[i];
8871 0 : ISOM_DECREASE_SIZE(ptr, 4)
8872 0 : subseg->range_count = gf_bs_read_u32(bs);
8873 : //each range is 4 bytes, abort if not enough bytes
8874 0 : if (ptr->size / 4 < subseg->range_count)
8875 : return GF_ISOM_INVALID_FILE;
8876 0 : subseg->ranges = (GF_SubsegmentRangeInfo*) gf_malloc(sizeof(GF_SubsegmentRangeInfo) * subseg->range_count);
8877 0 : if (!subseg->ranges) return GF_OUT_OF_MEM;
8878 0 : for (j = 0; j < subseg->range_count; j++) {
8879 0 : ISOM_DECREASE_SIZE(ptr, 4)
8880 0 : subseg->ranges[j].level = gf_bs_read_u8(bs);
8881 0 : subseg->ranges[j].range_size = gf_bs_read_u24(bs);
8882 : }
8883 : }
8884 : return GF_OK;
8885 : }
8886 :
8887 4 : GF_Box *ssix_box_new()
8888 : {
8889 8 : ISOM_DECL_BOX_ALLOC(GF_SubsegmentIndexBox, GF_ISOM_BOX_TYPE_SSIX);
8890 4 : return (GF_Box *)tmp;
8891 : }
8892 :
8893 :
8894 : #ifndef GPAC_DISABLE_ISOM_WRITE
8895 :
8896 2 : GF_Err ssix_box_write(GF_Box *s, GF_BitStream *bs)
8897 : {
8898 : GF_Err e;
8899 : u32 i, j;
8900 : GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;
8901 :
8902 2 : e = gf_isom_full_box_write(s, bs);
8903 2 : if (e) return e;
8904 :
8905 2 : gf_bs_write_u32(bs, ptr->subsegment_count);
8906 32 : for (i = 0; i<ptr->subsegment_count; i++) {
8907 30 : gf_bs_write_u32(bs, ptr->subsegments[i].range_count);
8908 90 : for (j = 0; j < ptr->subsegments[i].range_count; j++) {
8909 60 : gf_bs_write_u8(bs, ptr->subsegments[i].ranges[j].level);
8910 60 : gf_bs_write_u24(bs, ptr->subsegments[i].ranges[j].range_size);
8911 : }
8912 : }
8913 : return GF_OK;
8914 : }
8915 :
8916 3 : GF_Err ssix_box_size(GF_Box *s)
8917 : {
8918 : u32 i;
8919 : GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;
8920 :
8921 3 : ptr->size += 4;
8922 63 : for (i = 0; i < ptr->subsegment_count; i++) {
8923 60 : ptr->size += 4 + 4 * ptr->subsegments[i].range_count;
8924 : }
8925 3 : return GF_OK;
8926 : }
8927 :
8928 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
8929 :
8930 3 : void leva_box_del(GF_Box *s)
8931 : {
8932 : GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox *)s;
8933 3 : if (ptr == NULL) return;
8934 3 : if (ptr->levels) gf_free(ptr->levels);
8935 3 : gf_free(ptr);
8936 : }
8937 :
8938 1 : GF_Err leva_box_read(GF_Box *s, GF_BitStream *bs)
8939 : {
8940 : u32 i;
8941 : GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;
8942 :
8943 1 : ISOM_DECREASE_SIZE(ptr, 1)
8944 1 : ptr->level_count = gf_bs_read_u8(bs);
8945 : //each level is at least 5 bytes
8946 1 : if (ptr->size / 5 < ptr->level_count)
8947 : return GF_ISOM_INVALID_FILE;
8948 :
8949 1 : GF_SAFE_ALLOC_N(ptr->levels, ptr->level_count, GF_LevelAssignment);
8950 1 : if (!ptr->levels) return GF_OUT_OF_MEM;
8951 :
8952 0 : for (i = 0; i < ptr->level_count; i++) {
8953 0 : GF_LevelAssignment *level = &ptr->levels[i];
8954 : u8 tmp;
8955 0 : if (!level || ptr->size < 5) return GF_BAD_PARAM;
8956 0 : ISOM_DECREASE_SIZE(ptr, 5)
8957 :
8958 0 : level->track_id = gf_bs_read_u32(bs);
8959 0 : tmp = gf_bs_read_u8(bs);
8960 0 : level->padding_flag = tmp >> 7;
8961 0 : level->type = tmp & 0x7F;
8962 0 : if (level->type == 0) {
8963 0 : ISOM_DECREASE_SIZE(ptr, 4)
8964 0 : level->grouping_type = gf_bs_read_u32(bs);
8965 : }
8966 0 : else if (level->type == 1) {
8967 0 : ISOM_DECREASE_SIZE(ptr, 8)
8968 0 : level->grouping_type = gf_bs_read_u32(bs);
8969 0 : level->grouping_type_parameter = gf_bs_read_u32(bs);
8970 : }
8971 0 : else if (level->type == 4) {
8972 0 : ISOM_DECREASE_SIZE(ptr, 4)
8973 0 : level->sub_track_id = gf_bs_read_u32(bs);
8974 : }
8975 : }
8976 : return GF_OK;
8977 : }
8978 :
8979 3 : GF_Box *leva_box_new()
8980 : {
8981 6 : ISOM_DECL_BOX_ALLOC(GF_LevelAssignmentBox, GF_ISOM_BOX_TYPE_LEVA);
8982 3 : return (GF_Box *)tmp;
8983 : }
8984 :
8985 :
8986 : #ifndef GPAC_DISABLE_ISOM_WRITE
8987 :
8988 1 : GF_Err leva_box_write(GF_Box *s, GF_BitStream *bs)
8989 : {
8990 : GF_Err e;
8991 : u32 i;
8992 : GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;
8993 :
8994 1 : e = gf_isom_full_box_write(s, bs);
8995 1 : if (e) return e;
8996 :
8997 1 : gf_bs_write_u8(bs, ptr->level_count);
8998 1 : for (i = 0; i<ptr->level_count; i++) {
8999 0 : gf_bs_write_u32(bs, ptr->levels[i].track_id);
9000 0 : gf_bs_write_u8(bs, ptr->levels[i].padding_flag << 7 | (ptr->levels[i].type & 0x7F));
9001 0 : if (ptr->levels[i].type == 0) {
9002 0 : gf_bs_write_u32(bs, ptr->levels[i].grouping_type);
9003 : }
9004 0 : else if (ptr->levels[i].type == 1) {
9005 0 : gf_bs_write_u32(bs, ptr->levels[i].grouping_type);
9006 0 : gf_bs_write_u32(bs, ptr->levels[i].grouping_type_parameter);
9007 : }
9008 0 : else if (ptr->levels[i].type == 4) {
9009 0 : gf_bs_write_u32(bs, ptr->levels[i].sub_track_id);
9010 : }
9011 : }
9012 : return GF_OK;
9013 : }
9014 :
9015 1 : GF_Err leva_box_size(GF_Box *s)
9016 : {
9017 : u32 i;
9018 : GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;
9019 :
9020 1 : ptr->size += 1;
9021 1 : for (i = 0; i < ptr->level_count; i++) {
9022 0 : ptr->size += 5;
9023 0 : if (ptr->levels[i].type == 0 || ptr->levels[i].type == 4) {
9024 0 : ptr->size += 4;
9025 : }
9026 0 : else if (ptr->levels[i].type == 1) {
9027 0 : ptr->size += 8;
9028 : }
9029 : }
9030 1 : return GF_OK;
9031 : }
9032 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
9033 :
9034 3 : GF_Box *pcrb_box_new()
9035 : {
9036 6 : ISOM_DECL_BOX_ALLOC(GF_PcrInfoBox, GF_ISOM_BOX_TYPE_PCRB);
9037 3 : return (GF_Box *)tmp;
9038 : }
9039 :
9040 3 : void pcrb_box_del(GF_Box *s)
9041 : {
9042 : GF_PcrInfoBox *ptr = (GF_PcrInfoBox *) s;
9043 3 : if (ptr == NULL) return;
9044 3 : if (ptr->pcr_values) gf_free(ptr->pcr_values);
9045 3 : gf_free(ptr);
9046 : }
9047 :
9048 1 : GF_Err pcrb_box_read(GF_Box *s,GF_BitStream *bs)
9049 : {
9050 : u32 i;
9051 : GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;
9052 :
9053 1 : ISOM_DECREASE_SIZE(ptr, 4);
9054 1 : ptr->subsegment_count = gf_bs_read_u32(bs);
9055 :
9056 1 : ptr->pcr_values = gf_malloc(sizeof(u64)*ptr->subsegment_count);
9057 1 : if (!ptr->pcr_values) return GF_OUT_OF_MEM;
9058 0 : for (i=0; i<ptr->subsegment_count; i++) {
9059 0 : u64 data1 = gf_bs_read_u32(bs);
9060 0 : u64 data2 = gf_bs_read_u16(bs);
9061 0 : ISOM_DECREASE_SIZE(ptr, 6);
9062 0 : ptr->pcr_values[i] = (data1 << 10) | (data2 >> 6);
9063 :
9064 : }
9065 : return GF_OK;
9066 : }
9067 :
9068 : #ifndef GPAC_DISABLE_ISOM_WRITE
9069 :
9070 1 : GF_Err pcrb_box_write(GF_Box *s, GF_BitStream *bs)
9071 : {
9072 : GF_Err e;
9073 : u32 i;
9074 : GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;
9075 :
9076 1 : e = gf_isom_box_write_header(s, bs);
9077 1 : if (e) return e;
9078 :
9079 1 : gf_bs_write_u32(bs, ptr->subsegment_count);
9080 :
9081 1 : for (i=0; i<ptr->subsegment_count; i++ ) {
9082 0 : u32 data1 = (u32) (ptr->pcr_values[i] >> 10);
9083 0 : u16 data2 = (u16) (ptr->pcr_values[i] << 6);
9084 :
9085 0 : gf_bs_write_u32(bs, data1);
9086 0 : gf_bs_write_u16(bs, data2);
9087 : }
9088 : return GF_OK;
9089 : }
9090 :
9091 1 : GF_Err pcrb_box_size(GF_Box *s)
9092 : {
9093 : GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;
9094 :
9095 1 : ptr->size += 4;
9096 1 : ptr->size += ptr->subsegment_count * 6;
9097 :
9098 1 : return GF_OK;
9099 : }
9100 :
9101 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
9102 :
9103 :
9104 25 : GF_Box *subs_box_new()
9105 : {
9106 50 : ISOM_DECL_BOX_ALLOC(GF_SubSampleInformationBox, GF_ISOM_BOX_TYPE_SUBS);
9107 25 : tmp->Samples = gf_list_new();
9108 25 : return (GF_Box *)tmp;
9109 : }
9110 :
9111 25 : void subs_box_del(GF_Box *s)
9112 : {
9113 : GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
9114 25 : if (ptr == NULL) return;
9115 :
9116 2325 : while (gf_list_count(ptr->Samples)) {
9117 : GF_SubSampleInfoEntry *pSamp;
9118 2300 : pSamp = (GF_SubSampleInfoEntry*)gf_list_get(ptr->Samples, 0);
9119 9203 : while (gf_list_count(pSamp->SubSamples)) {
9120 : GF_SubSampleEntry *pSubSamp;
9121 4603 : pSubSamp = (GF_SubSampleEntry*) gf_list_get(pSamp->SubSamples, 0);
9122 4603 : gf_free(pSubSamp);
9123 4603 : gf_list_rem(pSamp->SubSamples, 0);
9124 : }
9125 2300 : gf_list_del(pSamp->SubSamples);
9126 2300 : gf_free(pSamp);
9127 2300 : gf_list_rem(ptr->Samples, 0);
9128 : }
9129 25 : gf_list_del(ptr->Samples);
9130 25 : gf_free(ptr);
9131 : }
9132 :
9133 :
9134 : #ifndef GPAC_DISABLE_ISOM_WRITE
9135 :
9136 20 : GF_Err subs_box_write(GF_Box *s, GF_BitStream *bs)
9137 : {
9138 : GF_Err e;
9139 : u32 i, j, entry_count;
9140 : u16 subsample_count;
9141 : GF_SubSampleEntry *pSubSamp;
9142 : GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s;
9143 :
9144 20 : if (!s) return GF_BAD_PARAM;
9145 20 : e = gf_isom_full_box_write(s, bs);
9146 20 : if (e) return e;
9147 20 : entry_count = gf_list_count(ptr->Samples);
9148 20 : gf_bs_write_u32(bs, entry_count);
9149 :
9150 1552 : for (i=0; i<entry_count; i++) {
9151 1532 : GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*) gf_list_get(ptr->Samples, i);
9152 1532 : subsample_count = gf_list_count(pSamp->SubSamples);
9153 1532 : gf_bs_write_u32(bs, pSamp->sample_delta);
9154 1532 : gf_bs_write_u16(bs, subsample_count);
9155 :
9156 4598 : for (j=0; j<subsample_count; j++) {
9157 3066 : pSubSamp = (GF_SubSampleEntry*) gf_list_get(pSamp->SubSamples, j);
9158 3066 : if (ptr->version == 1) {
9159 2355 : gf_bs_write_u32(bs, pSubSamp->subsample_size);
9160 : } else {
9161 711 : gf_bs_write_u16(bs, pSubSamp->subsample_size);
9162 : }
9163 3066 : gf_bs_write_u8(bs, pSubSamp->subsample_priority);
9164 3066 : gf_bs_write_u8(bs, pSubSamp->discardable);
9165 3066 : gf_bs_write_u32(bs, pSubSamp->reserved);
9166 : }
9167 : }
9168 : return e;
9169 : }
9170 :
9171 58 : GF_Err subs_box_size(GF_Box *s)
9172 : {
9173 : GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s;
9174 : u32 entry_count, i;
9175 : u16 subsample_count;
9176 :
9177 : // add 4 byte for entry_count
9178 58 : ptr->size += 4;
9179 58 : entry_count = gf_list_count(ptr->Samples);
9180 4654 : for (i=0; i<entry_count; i++) {
9181 4596 : GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*) gf_list_get(ptr->Samples, i);
9182 4596 : subsample_count = gf_list_count(pSamp->SubSamples);
9183 : // 4 byte for sample_delta, 2 byte for subsample_count
9184 : // and 6 + (4 or 2) bytes for each subsample
9185 4596 : ptr->size += 4 + 2 + subsample_count * (6 + (ptr->version==1 ? 4 : 2));
9186 : }
9187 58 : return GF_OK;
9188 : }
9189 :
9190 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
9191 :
9192 4 : GF_Err subs_box_read(GF_Box *s, GF_BitStream *bs)
9193 : {
9194 : GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
9195 : u32 entry_count, i, j;
9196 : u16 subsample_count;
9197 :
9198 4 : ISOM_DECREASE_SIZE(ptr, 4);
9199 4 : entry_count = gf_bs_read_u32(bs);
9200 :
9201 772 : for (i=0; i<entry_count; i++) {
9202 : u32 subs_size=0;
9203 768 : GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*) gf_malloc(sizeof(GF_SubSampleInfoEntry));
9204 768 : if (!pSamp) return GF_OUT_OF_MEM;
9205 :
9206 : memset(pSamp, 0, sizeof(GF_SubSampleInfoEntry));
9207 768 : pSamp->SubSamples = gf_list_new();
9208 768 : pSamp->sample_delta = gf_bs_read_u32(bs);
9209 768 : subsample_count = gf_bs_read_u16(bs);
9210 : subs_size=6;
9211 :
9212 2305 : for (j=0; j<subsample_count; j++) {
9213 1537 : GF_SubSampleEntry *pSubSamp = (GF_SubSampleEntry*) gf_malloc(sizeof(GF_SubSampleEntry));
9214 1537 : if (!pSubSamp) return GF_OUT_OF_MEM;
9215 :
9216 : memset(pSubSamp, 0, sizeof(GF_SubSampleEntry));
9217 1537 : if (ptr->version==1) {
9218 1523 : pSubSamp->subsample_size = gf_bs_read_u32(bs);
9219 1523 : subs_size+=4;
9220 : } else {
9221 14 : pSubSamp->subsample_size = gf_bs_read_u16(bs);
9222 14 : subs_size+=2;
9223 : }
9224 1537 : pSubSamp->subsample_priority = gf_bs_read_u8(bs);
9225 1537 : pSubSamp->discardable = gf_bs_read_u8(bs);
9226 1537 : pSubSamp->reserved = gf_bs_read_u32(bs);
9227 1537 : subs_size+=6;
9228 :
9229 1537 : gf_list_add(pSamp->SubSamples, pSubSamp);
9230 : }
9231 768 : gf_list_add(ptr->Samples, pSamp);
9232 768 : ISOM_DECREASE_SIZE(ptr, subs_size);
9233 : }
9234 : return GF_OK;
9235 : }
9236 :
9237 :
9238 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
9239 :
9240 7397 : GF_Box *tfdt_box_new()
9241 : {
9242 14794 : ISOM_DECL_BOX_ALLOC(GF_TFBaseMediaDecodeTimeBox, GF_ISOM_BOX_TYPE_TFDT);
9243 7397 : return (GF_Box *)tmp;
9244 : }
9245 :
9246 7397 : void tfdt_box_del(GF_Box *s)
9247 : {
9248 7397 : gf_free(s);
9249 7397 : }
9250 :
9251 : /*this is using chpl format according to some NeroRecode samples*/
9252 4013 : GF_Err tfdt_box_read(GF_Box *s,GF_BitStream *bs)
9253 : {
9254 : GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s;
9255 :
9256 4013 : if (ptr->version==1) {
9257 25 : ISOM_DECREASE_SIZE(ptr, 8);
9258 25 : ptr->baseMediaDecodeTime = gf_bs_read_u64(bs);
9259 : } else {
9260 3988 : ISOM_DECREASE_SIZE(ptr, 4);
9261 3988 : ptr->baseMediaDecodeTime = (u32) gf_bs_read_u32(bs);
9262 : }
9263 : return GF_OK;
9264 : }
9265 :
9266 : #ifndef GPAC_DISABLE_ISOM_WRITE
9267 :
9268 3613 : GF_Err tfdt_box_write(GF_Box *s, GF_BitStream *bs)
9269 : {
9270 : GF_Err e;
9271 : GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *) s;
9272 3613 : e = gf_isom_full_box_write(s, bs);
9273 3613 : if (e) return e;
9274 :
9275 3613 : if (ptr->version==1) {
9276 0 : gf_bs_write_u64(bs, ptr->baseMediaDecodeTime);
9277 : } else {
9278 3613 : gf_bs_write_u32(bs, (u32) ptr->baseMediaDecodeTime);
9279 : }
9280 : return GF_OK;
9281 : }
9282 :
9283 10491 : GF_Err tfdt_box_size(GF_Box *s)
9284 : {
9285 : GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s;
9286 :
9287 10491 : if (!ptr->version && (ptr->baseMediaDecodeTime<=0xFFFFFFFF)) {
9288 : //ptr->version = 0;
9289 10491 : ptr->size += 4;
9290 : } else {
9291 0 : ptr->version = 1;
9292 0 : ptr->size += 8;
9293 : }
9294 10491 : return GF_OK;
9295 : }
9296 :
9297 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
9298 :
9299 : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
9300 :
9301 :
9302 5 : GF_Box *rvcc_box_new()
9303 : {
9304 10 : ISOM_DECL_BOX_ALLOC(GF_RVCConfigurationBox, GF_ISOM_BOX_TYPE_RVCC);
9305 5 : return (GF_Box *)tmp;
9306 : }
9307 :
9308 5 : void rvcc_box_del(GF_Box *s)
9309 : {
9310 5 : gf_free(s);
9311 5 : }
9312 :
9313 2 : GF_Err rvcc_box_read(GF_Box *s,GF_BitStream *bs)
9314 : {
9315 : GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*)s;
9316 2 : ISOM_DECREASE_SIZE(ptr, 2);
9317 2 : ptr->predefined_rvc_config = gf_bs_read_u16(bs);
9318 2 : if (!ptr->predefined_rvc_config) {
9319 2 : ISOM_DECREASE_SIZE(ptr, 2);
9320 2 : ptr->rvc_meta_idx = gf_bs_read_u16(bs);
9321 : }
9322 : return GF_OK;
9323 : }
9324 :
9325 : #ifndef GPAC_DISABLE_ISOM_WRITE
9326 :
9327 2 : GF_Err rvcc_box_write(GF_Box *s, GF_BitStream *bs)
9328 : {
9329 : GF_Err e;
9330 : GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*) s;
9331 :
9332 2 : e = gf_isom_box_write_header(s, bs);
9333 2 : if (e) return e;
9334 :
9335 2 : gf_bs_write_u16(bs, ptr->predefined_rvc_config);
9336 2 : if (!ptr->predefined_rvc_config) {
9337 2 : gf_bs_write_u16(bs, ptr->rvc_meta_idx);
9338 : }
9339 : return GF_OK;
9340 : }
9341 :
9342 4 : GF_Err rvcc_box_size(GF_Box *s)
9343 : {
9344 : GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox *)s;
9345 4 : ptr->size += 2;
9346 4 : if (! ptr->predefined_rvc_config) ptr->size += 2;
9347 4 : return GF_OK;
9348 : }
9349 :
9350 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
9351 :
9352 :
9353 :
9354 554 : GF_Box *sbgp_box_new()
9355 : {
9356 1108 : ISOM_DECL_BOX_ALLOC(GF_SampleGroupBox, GF_ISOM_BOX_TYPE_SBGP);
9357 554 : return (GF_Box *)tmp;
9358 : }
9359 554 : void sbgp_box_del(GF_Box *a)
9360 : {
9361 : GF_SampleGroupBox *p = (GF_SampleGroupBox *)a;
9362 554 : if (p->sample_entries) gf_free(p->sample_entries);
9363 554 : gf_free(p);
9364 554 : }
9365 :
9366 181 : GF_Err sbgp_box_read(GF_Box *s, GF_BitStream *bs)
9367 : {
9368 : u32 i;
9369 : GF_SampleGroupBox *ptr = (GF_SampleGroupBox *)s;
9370 :
9371 181 : ISOM_DECREASE_SIZE(ptr, 8);
9372 181 : ptr->grouping_type = gf_bs_read_u32(bs);
9373 :
9374 181 : if (ptr->version==1) {
9375 0 : ISOM_DECREASE_SIZE(ptr, 4);
9376 0 : ptr->grouping_type_parameter = gf_bs_read_u32(bs);
9377 : }
9378 181 : ptr->entry_count = gf_bs_read_u32(bs);
9379 :
9380 181 : if (ptr->size < sizeof(GF_SampleGroupEntry)*ptr->entry_count)
9381 : return GF_ISOM_INVALID_FILE;
9382 :
9383 181 : ptr->sample_entries = gf_malloc(sizeof(GF_SampleGroupEntry)*ptr->entry_count);
9384 181 : if (!ptr->sample_entries) return GF_OUT_OF_MEM;
9385 :
9386 2622 : for (i=0; i<ptr->entry_count; i++) {
9387 2622 : ISOM_DECREASE_SIZE(ptr, 8);
9388 2622 : ptr->sample_entries[i].sample_count = gf_bs_read_u32(bs);
9389 2622 : ptr->sample_entries[i].group_description_index = gf_bs_read_u32(bs);
9390 : }
9391 : return GF_OK;
9392 : }
9393 :
9394 : #ifndef GPAC_DISABLE_ISOM_WRITE
9395 273 : GF_Err sbgp_box_write(GF_Box *s, GF_BitStream *bs)
9396 : {
9397 : u32 i;
9398 : GF_Err e;
9399 : GF_SampleGroupBox *p = (GF_SampleGroupBox*)s;
9400 :
9401 273 : e = gf_isom_full_box_write(s, bs);
9402 273 : if (e) return e;
9403 273 : gf_bs_write_u32(bs, p->grouping_type);
9404 273 : if (p->version==1)
9405 1 : gf_bs_write_u32(bs, p->grouping_type_parameter);
9406 :
9407 273 : gf_bs_write_u32(bs, p->entry_count);
9408 2979 : for (i = 0; i<p->entry_count; i++ ) {
9409 2706 : gf_bs_write_u32(bs, p->sample_entries[i].sample_count);
9410 2706 : gf_bs_write_u32(bs, p->sample_entries[i].group_description_index);
9411 : }
9412 : return GF_OK;
9413 : }
9414 :
9415 817 : GF_Err sbgp_box_size(GF_Box *s)
9416 : {
9417 : GF_SampleGroupBox *p = (GF_SampleGroupBox*)s;
9418 :
9419 817 : p->size += 8;
9420 817 : if (p->grouping_type_parameter) p->version=1;
9421 :
9422 817 : if (p->version==1) p->size += 4;
9423 817 : p->size += 8*p->entry_count;
9424 817 : return GF_OK;
9425 : }
9426 :
9427 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
9428 :
9429 355 : static void *sgpd_parse_entry(u32 grouping_type, GF_BitStream *bs, s32 bytes_in_box, u32 entry_size, u32 *total_bytes)
9430 : {
9431 : Bool null_size_ok = GF_FALSE;
9432 : GF_DefaultSampleGroupDescriptionEntry *def_ptr;
9433 :
9434 355 : switch (grouping_type) {
9435 2 : case GF_ISOM_SAMPLE_GROUP_ROLL:
9436 : case GF_ISOM_SAMPLE_GROUP_PROL:
9437 : {
9438 : GF_RollRecoveryEntry *ptr;
9439 2 : GF_SAFEALLOC(ptr, GF_RollRecoveryEntry);
9440 2 : if (!ptr) return NULL;
9441 2 : ptr->roll_distance = gf_bs_read_int(bs, 16);
9442 2 : *total_bytes = 2;
9443 2 : return ptr;
9444 : }
9445 54 : case GF_ISOM_SAMPLE_GROUP_RAP:
9446 : {
9447 : GF_VisualRandomAccessEntry *ptr;
9448 54 : GF_SAFEALLOC(ptr, GF_VisualRandomAccessEntry);
9449 54 : if (!ptr) return NULL;
9450 54 : ptr->num_leading_samples_known = gf_bs_read_int(bs, 1);
9451 54 : ptr->num_leading_samples = gf_bs_read_int(bs, 7);
9452 54 : *total_bytes = 1;
9453 54 : return ptr;
9454 : }
9455 0 : case GF_ISOM_SAMPLE_GROUP_SAP:
9456 : {
9457 : GF_SAPEntry *ptr;
9458 0 : GF_SAFEALLOC(ptr, GF_SAPEntry);
9459 0 : if (!ptr) return NULL;
9460 0 : ptr->dependent_flag = gf_bs_read_int(bs, 1);
9461 0 : gf_bs_read_int(bs, 3);
9462 0 : ptr->SAP_type = gf_bs_read_int(bs, 4);
9463 0 : *total_bytes = 1;
9464 0 : return ptr;
9465 : }
9466 0 : case GF_ISOM_SAMPLE_GROUP_SYNC:
9467 : {
9468 : GF_SYNCEntry *ptr;
9469 0 : GF_SAFEALLOC(ptr, GF_SYNCEntry);
9470 0 : if (!ptr) return NULL;
9471 0 : gf_bs_read_int(bs, 2);
9472 0 : ptr->NALU_type = gf_bs_read_int(bs, 6);
9473 0 : *total_bytes = 1;
9474 0 : return ptr;
9475 : }
9476 9 : case GF_ISOM_SAMPLE_GROUP_TELE:
9477 : {
9478 : GF_TemporalLevelEntry *ptr;
9479 9 : GF_SAFEALLOC(ptr, GF_TemporalLevelEntry);
9480 9 : if (!ptr) return NULL;
9481 9 : ptr->level_independently_decodable = gf_bs_read_int(bs, 1);
9482 9 : gf_bs_read_int(bs, 7);
9483 9 : *total_bytes = 1;
9484 9 : return ptr;
9485 : }
9486 134 : case GF_ISOM_SAMPLE_GROUP_SEIG:
9487 : {
9488 : GF_CENCSampleEncryptionGroupEntry *ptr;
9489 134 : if (bytes_in_box<3) return NULL;
9490 134 : GF_SAFEALLOC(ptr, GF_CENCSampleEncryptionGroupEntry);
9491 134 : if (!ptr) return NULL;
9492 134 : Bool use_mkey = gf_bs_read_int(bs, 1);
9493 134 : gf_bs_read_int(bs, 7); //reserved
9494 134 : ptr->crypt_byte_block = gf_bs_read_int(bs, 4);
9495 134 : ptr->skip_byte_block = gf_bs_read_int(bs, 4);
9496 134 : ptr->IsProtected = gf_bs_read_u8(bs);
9497 : bytes_in_box -= 3;
9498 134 : if (use_mkey) {
9499 9 : u64 pos = gf_bs_get_position(bs);
9500 9 : u32 i, count = gf_bs_read_u16(bs);
9501 9 : bytes_in_box -= 2;
9502 9 : if (bytes_in_box<0) {
9503 0 : gf_free(ptr);
9504 0 : return NULL;
9505 : }
9506 18 : for (i=0; i<count; i++) {
9507 18 : u8 ivsize = gf_bs_read_u8(bs);
9508 18 : gf_bs_skip_bytes(bs, 16);
9509 18 : bytes_in_box -= 17;
9510 18 : if (!ivsize) {
9511 : //const IV
9512 0 : ivsize = gf_bs_read_u8(bs);
9513 0 : gf_bs_skip_bytes(bs, ivsize);
9514 0 : bytes_in_box -= 1 + ivsize;
9515 : }
9516 18 : if (bytes_in_box<0) {
9517 0 : gf_free(ptr);
9518 0 : return NULL;
9519 : }
9520 : }
9521 9 : ptr->key_info_size = 1 + (u32) (gf_bs_get_position(bs) - pos);
9522 9 : ptr->key_info = gf_malloc(sizeof(u8) * ptr->key_info_size);
9523 9 : if (!ptr->key_info) {
9524 0 : gf_free(ptr);
9525 0 : return NULL;
9526 : }
9527 9 : gf_bs_seek(bs, pos);
9528 9 : ptr->key_info[0] = 1;
9529 9 : gf_bs_read_data(bs, ptr->key_info + 1, ptr->key_info_size - 1);
9530 9 : *total_bytes = 3 + ptr->key_info_size - 1;
9531 :
9532 9 : if (!gf_cenc_validate_key_info(ptr->key_info, ptr->key_info_size)) {
9533 0 : gf_free(ptr->key_info);
9534 0 : gf_free(ptr);
9535 0 : return NULL;
9536 : }
9537 : } else {
9538 : bin128 kid;
9539 : u8 const_iv_size = 0;
9540 125 : u8 iv_size = gf_bs_read_u8(bs);
9541 125 : gf_bs_read_data(bs, kid, 16);
9542 : bytes_in_box -= 17;
9543 125 : if (bytes_in_box<0) {
9544 0 : gf_free(ptr);
9545 0 : return NULL;
9546 : }
9547 :
9548 125 : *total_bytes = 20;
9549 125 : if ((ptr->IsProtected == 1) && !iv_size) {
9550 0 : const_iv_size = gf_bs_read_u8(bs);
9551 0 : if ((const_iv_size != 8) && (const_iv_size != 16)) {
9552 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] seig sample group have invalid constant_IV size\n"));
9553 0 : gf_free(ptr);
9554 0 : return NULL;
9555 : }
9556 : }
9557 125 : ptr->key_info_size = 20;
9558 125 : if (!iv_size && ptr->IsProtected) {
9559 0 : ptr->key_info_size += 1 + const_iv_size;
9560 : }
9561 125 : ptr->key_info = gf_malloc(sizeof(u8) * ptr->key_info_size);
9562 125 : if (!ptr->key_info) {
9563 0 : gf_free(ptr);
9564 0 : return NULL;
9565 : }
9566 125 : ptr->key_info[0] = 0;
9567 125 : ptr->key_info[1] = 0;
9568 125 : ptr->key_info[2] = 0;
9569 125 : ptr->key_info[3] = iv_size;
9570 125 : memcpy(ptr->key_info+4, kid, 16);
9571 125 : if (!iv_size && ptr->IsProtected) {
9572 0 : ptr->key_info[20] = const_iv_size;
9573 0 : gf_bs_read_data(bs, (char *)ptr->key_info+21, const_iv_size);
9574 0 : *total_bytes += 1 + const_iv_size;
9575 : }
9576 : }
9577 :
9578 134 : if (!entry_size) {
9579 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] seig sample group does not indicate entry size, deprecated in spec\n"));
9580 : }
9581 : return ptr;
9582 : }
9583 12 : case GF_ISOM_SAMPLE_GROUP_OINF:
9584 : {
9585 12 : GF_OperatingPointsInformation *ptr = gf_isom_oinf_new_entry();
9586 12 : u32 s = (u32) gf_bs_get_position(bs);
9587 12 : gf_isom_oinf_read_entry(ptr, bs);
9588 12 : *total_bytes = (u32) gf_bs_get_position(bs) - s;
9589 12 : if (!entry_size) {
9590 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] oinf sample group does not indicate entry size, deprecated in spec\n"));
9591 : }
9592 : return ptr;
9593 : }
9594 18 : case GF_ISOM_SAMPLE_GROUP_LINF:
9595 : {
9596 18 : GF_LHVCLayerInformation *ptr = gf_isom_linf_new_entry();
9597 18 : u32 s = (u32) gf_bs_get_position(bs);
9598 18 : gf_isom_linf_read_entry(ptr, bs);
9599 18 : *total_bytes = (u32) gf_bs_get_position(bs) - s;
9600 18 : if (!entry_size) {
9601 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] linf sample group does not indicate entry size, deprecated in spec\n"));
9602 : }
9603 : return ptr;
9604 : }
9605 :
9606 126 : case GF_ISOM_SAMPLE_GROUP_TRIF:
9607 126 : if (! entry_size) {
9608 0 : u32 flags = gf_bs_peek_bits(bs, 24, 0);
9609 0 : if (flags & 0x10000) entry_size=3;
9610 : else {
9611 0 : if (flags & 0x80000) entry_size=7;
9612 : else entry_size=11;
9613 : //have dependency list
9614 0 : if (flags & 0x200000) {
9615 0 : u32 nb_entries = gf_bs_peek_bits(bs, 16, entry_size);
9616 0 : entry_size += 2 + 2*nb_entries;
9617 : }
9618 : }
9619 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] trif sample group does not indicate entry size, deprecated in spec\n"));
9620 : }
9621 : break;
9622 0 : case GF_ISOM_SAMPLE_GROUP_NALM:
9623 0 : if (! entry_size) {
9624 0 : u64 start = gf_bs_get_position(bs);
9625 : Bool rle, large_size;
9626 : u32 entry_count;
9627 0 : gf_bs_read_int(bs, 6);
9628 0 : large_size = gf_bs_read_int(bs, 1);
9629 0 : rle = gf_bs_read_int(bs, 1);
9630 0 : entry_count = gf_bs_read_int(bs, large_size ? 16 : 8);
9631 0 : gf_bs_seek(bs, start);
9632 0 : entry_size = 1 + (large_size ? 2 : 1);
9633 0 : entry_size += entry_count * 2;
9634 0 : if (rle) entry_size += entry_count * (large_size ? 2 : 1);
9635 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] nalm sample group does not indicate entry size, deprecated in spec\n"));
9636 : }
9637 : break;
9638 :
9639 0 : case GF_ISOM_SAMPLE_GROUP_TSAS:
9640 : case GF_ISOM_SAMPLE_GROUP_STSA:
9641 : null_size_ok = GF_TRUE;
9642 0 : break;
9643 : //TODO, add support for these ones ?
9644 0 : case GF_ISOM_SAMPLE_GROUP_TSCL:
9645 : entry_size = 20;
9646 0 : break;
9647 0 : case GF_ISOM_SAMPLE_GROUP_LBLI:
9648 : entry_size = 2;
9649 0 : break;
9650 : default:
9651 : break;
9652 : }
9653 :
9654 126 : if (!entry_size && !null_size_ok) {
9655 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] %s sample group does not indicate entry size and is not implemented, cannot parse!\n", gf_4cc_to_str( grouping_type) ));
9656 : return NULL;
9657 : }
9658 126 : GF_SAFEALLOC(def_ptr, GF_DefaultSampleGroupDescriptionEntry);
9659 126 : if (!def_ptr) return NULL;
9660 126 : if (entry_size) {
9661 126 : def_ptr->length = entry_size;
9662 126 : def_ptr->data = (u8 *) gf_malloc(sizeof(u8)*def_ptr->length);
9663 126 : if (!def_ptr->data) {
9664 0 : gf_free(def_ptr);
9665 0 : return NULL;
9666 : }
9667 126 : gf_bs_read_data(bs, (char *) def_ptr->data, def_ptr->length);
9668 126 : *total_bytes = entry_size;
9669 : }
9670 : return def_ptr;
9671 : }
9672 :
9673 497 : static void sgpd_del_entry(u32 grouping_type, void *entry)
9674 : {
9675 497 : switch (grouping_type) {
9676 113 : case GF_ISOM_SAMPLE_GROUP_SYNC:
9677 : case GF_ISOM_SAMPLE_GROUP_ROLL:
9678 : case GF_ISOM_SAMPLE_GROUP_PROL:
9679 : case GF_ISOM_SAMPLE_GROUP_RAP:
9680 : case GF_ISOM_SAMPLE_GROUP_TELE:
9681 : case GF_ISOM_SAMPLE_GROUP_SAP:
9682 113 : gf_free(entry);
9683 113 : return;
9684 167 : case GF_ISOM_SAMPLE_GROUP_SEIG:
9685 : {
9686 : GF_CENCSampleEncryptionGroupEntry *seig = (GF_CENCSampleEncryptionGroupEntry *)entry;
9687 167 : if (seig->key_info) gf_free(seig->key_info);
9688 167 : gf_free(entry);
9689 : }
9690 167 : return;
9691 18 : case GF_ISOM_SAMPLE_GROUP_OINF:
9692 18 : gf_isom_oinf_del_entry(entry);
9693 18 : return;
9694 26 : case GF_ISOM_SAMPLE_GROUP_LINF:
9695 26 : gf_isom_linf_del_entry(entry);
9696 26 : return;
9697 173 : default:
9698 : {
9699 : GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
9700 173 : if (ptr->data) gf_free(ptr->data);
9701 173 : gf_free(ptr);
9702 : }
9703 : }
9704 : }
9705 :
9706 455 : void sgpd_write_entry(u32 grouping_type, void *entry, GF_BitStream *bs)
9707 : {
9708 455 : switch (grouping_type) {
9709 17 : case GF_ISOM_SAMPLE_GROUP_ROLL:
9710 : case GF_ISOM_SAMPLE_GROUP_PROL:
9711 17 : gf_bs_write_int(bs, ((GF_RollRecoveryEntry*)entry)->roll_distance, 16);
9712 17 : return;
9713 119 : case GF_ISOM_SAMPLE_GROUP_RAP:
9714 119 : gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples_known, 1);
9715 119 : gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples, 7);
9716 119 : return;
9717 0 : case GF_ISOM_SAMPLE_GROUP_SAP:
9718 0 : gf_bs_write_int(bs, ((GF_SAPEntry*)entry)->dependent_flag, 1);
9719 0 : gf_bs_write_int(bs, 0, 3);
9720 0 : gf_bs_write_int(bs, ((GF_SAPEntry*)entry)->SAP_type, 4);
9721 0 : return;
9722 0 : case GF_ISOM_SAMPLE_GROUP_SYNC:
9723 0 : gf_bs_write_int(bs, 0, 2);
9724 0 : gf_bs_write_int(bs, ((GF_SYNCEntry*)entry)->NALU_type, 6);
9725 0 : return;
9726 6 : case GF_ISOM_SAMPLE_GROUP_TELE:
9727 6 : gf_bs_write_int(bs, ((GF_TemporalLevelEntry*)entry)->level_independently_decodable, 1);
9728 6 : gf_bs_write_int(bs, 0, 7);
9729 6 : return;
9730 111 : case GF_ISOM_SAMPLE_GROUP_SEIG:
9731 : {
9732 : GF_CENCSampleEncryptionGroupEntry *seig = (GF_CENCSampleEncryptionGroupEntry *)entry;
9733 111 : Bool use_mkey = seig->key_info[0];
9734 : u32 nb_keys = 1;
9735 111 : if (use_mkey) {
9736 6 : nb_keys = seig->key_info[1];
9737 6 : nb_keys<<=8;
9738 6 : nb_keys |= seig->key_info[2];
9739 : }
9740 111 : gf_bs_write_int(bs, use_mkey ? 1 : 0, 1);
9741 111 : gf_bs_write_int(bs, 0, 7);
9742 111 : gf_bs_write_int(bs, seig->crypt_byte_block, 4);
9743 111 : gf_bs_write_int(bs, seig->skip_byte_block, 4);
9744 111 : gf_bs_write_u8(bs, seig->IsProtected);
9745 111 : if (nb_keys>1) {
9746 6 : gf_bs_write_data(bs, seig->key_info+1, seig->key_info_size-1);
9747 : } else {
9748 105 : gf_bs_write_data(bs, seig->key_info+3, seig->key_info_size - 3);
9749 : }
9750 : }
9751 : return;
9752 16 : case GF_ISOM_SAMPLE_GROUP_OINF:
9753 16 : gf_isom_oinf_write_entry(entry, bs);
9754 16 : return;
9755 22 : case GF_ISOM_SAMPLE_GROUP_LINF:
9756 22 : gf_isom_linf_write_entry(entry, bs);
9757 22 : return;
9758 164 : default:
9759 : {
9760 : GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
9761 164 : if (ptr->length)
9762 164 : gf_bs_write_data(bs, (char *) ptr->data, ptr->length);
9763 : }
9764 : }
9765 : }
9766 :
9767 : #ifndef GPAC_DISABLE_ISOM_WRITE
9768 691 : static u32 sgpd_size_entry(u32 grouping_type, void *entry)
9769 : {
9770 691 : switch (grouping_type) {
9771 : case GF_ISOM_SAMPLE_GROUP_ROLL:
9772 : case GF_ISOM_SAMPLE_GROUP_PROL:
9773 : return 2;
9774 153 : case GF_ISOM_SAMPLE_GROUP_TELE:
9775 : case GF_ISOM_SAMPLE_GROUP_RAP:
9776 : case GF_ISOM_SAMPLE_GROUP_SAP:
9777 : case GF_ISOM_SAMPLE_GROUP_SYNC:
9778 153 : return 1;
9779 0 : case GF_ISOM_SAMPLE_GROUP_TSCL:
9780 0 : return 20;
9781 : case GF_ISOM_SAMPLE_GROUP_LBLI:
9782 : return 2;
9783 0 : case GF_ISOM_SAMPLE_GROUP_TSAS:
9784 : case GF_ISOM_SAMPLE_GROUP_STSA:
9785 0 : return 0;
9786 177 : case GF_ISOM_SAMPLE_GROUP_SEIG:
9787 : {
9788 : GF_CENCSampleEncryptionGroupEntry *seig = (GF_CENCSampleEncryptionGroupEntry *)entry;
9789 177 : Bool use_mkey = seig->key_info[0] ? GF_TRUE : GF_FALSE;
9790 177 : if (use_mkey) {
9791 12 : return 3 + seig->key_info_size-1;
9792 : }
9793 165 : return seig->key_info_size; //== 3 + (seig->key_info_size-3);
9794 : }
9795 30 : case GF_ISOM_SAMPLE_GROUP_OINF:
9796 30 : return gf_isom_oinf_size_entry(entry);
9797 40 : case GF_ISOM_SAMPLE_GROUP_LINF:
9798 40 : return gf_isom_linf_size_entry(entry);
9799 242 : default:
9800 242 : return ((GF_DefaultSampleGroupDescriptionEntry *)entry)->length;
9801 : }
9802 : }
9803 : #endif
9804 :
9805 555 : GF_Box *sgpd_box_new()
9806 : {
9807 1110 : ISOM_DECL_BOX_ALLOC(GF_SampleGroupDescriptionBox, GF_ISOM_BOX_TYPE_SGPD);
9808 : /*version 0 is deprecated, use v1 by default*/
9809 555 : tmp->version = 1;
9810 555 : tmp->group_descriptions = gf_list_new();
9811 555 : return (GF_Box *)tmp;
9812 : }
9813 :
9814 555 : void sgpd_box_del(GF_Box *a)
9815 : {
9816 : GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)a;
9817 1607 : while (gf_list_count(p->group_descriptions)) {
9818 497 : void *ptr = gf_list_last(p->group_descriptions);
9819 497 : sgpd_del_entry(p->grouping_type, ptr);
9820 497 : gf_list_rem_last(p->group_descriptions);
9821 : }
9822 555 : gf_list_del(p->group_descriptions);
9823 555 : gf_free(p);
9824 555 : }
9825 :
9826 346 : GF_Err sgpd_box_read(GF_Box *s, GF_BitStream *bs)
9827 : {
9828 : u32 entry_count;
9829 : GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
9830 :
9831 346 : ISOM_DECREASE_SIZE(p, 8);
9832 346 : p->grouping_type = gf_bs_read_u32(bs);
9833 :
9834 346 : if (p->version>=1) {
9835 346 : ISOM_DECREASE_SIZE(p, 4);
9836 346 : p->default_length = gf_bs_read_u32(bs);
9837 : }
9838 346 : if (p->version>=2) {
9839 156 : ISOM_DECREASE_SIZE(p, 4);
9840 156 : p->default_description_index = gf_bs_read_u32(bs);
9841 : }
9842 346 : entry_count = gf_bs_read_u32(bs);
9843 :
9844 346 : if (entry_count>p->size)
9845 : return GF_ISOM_INVALID_FILE;
9846 :
9847 701 : while (entry_count) {
9848 : void *ptr;
9849 355 : u32 parsed_bytes=0;
9850 355 : u32 size = p->default_length;
9851 355 : if ((p->version>=1) && !size) {
9852 0 : size = gf_bs_read_u32(bs);
9853 0 : ISOM_DECREASE_SIZE(p, 4);
9854 : }
9855 355 : ptr = sgpd_parse_entry(p->grouping_type, bs, (s32) p->size, size, &parsed_bytes);
9856 : //don't return an error, just stop parsing so that we skip over the sgpd box
9857 355 : if (!ptr) return GF_OK;
9858 355 : gf_list_add(p->group_descriptions, ptr);
9859 :
9860 355 : ISOM_DECREASE_SIZE(p, parsed_bytes);
9861 355 : entry_count--;
9862 : }
9863 : return GF_OK;
9864 : }
9865 :
9866 : #ifndef GPAC_DISABLE_ISOM_WRITE
9867 417 : GF_Err sgpd_box_write(GF_Box *s, GF_BitStream *bs)
9868 : {
9869 : u32 i, nb_descs;
9870 : GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
9871 : GF_Err e;
9872 417 : e = gf_isom_full_box_write(s, bs);
9873 417 : if (e) return e;
9874 :
9875 417 : gf_bs_write_u32(bs, p->grouping_type);
9876 417 : if (p->version>=1) gf_bs_write_u32(bs, p->default_length);
9877 417 : if (p->version>=2) gf_bs_write_u32(bs, p->default_description_index);
9878 417 : nb_descs = gf_list_count(p->group_descriptions);
9879 417 : gf_bs_write_u32(bs, nb_descs);
9880 :
9881 830 : for (i=0; i<nb_descs; i++) {
9882 413 : void *ptr = gf_list_get(p->group_descriptions, i);
9883 413 : if ((p->version >= 1) && !p->default_length) {
9884 2 : u32 size = sgpd_size_entry(p->grouping_type, ptr);
9885 2 : gf_bs_write_u32(bs, size);
9886 : }
9887 413 : sgpd_write_entry(p->grouping_type, ptr, bs);
9888 : }
9889 : return GF_OK;
9890 : }
9891 :
9892 715 : GF_Err sgpd_box_size(GF_Box *s)
9893 : {
9894 : u32 i, nb_descs;
9895 : Bool use_def_size = GF_TRUE;
9896 : GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
9897 :
9898 715 : p->size += 8;
9899 :
9900 : //we force all sample groups to version 1, v0 being deprecated
9901 715 : if (!p->version)
9902 0 : p->version = 1;
9903 715 : p->size += 4;
9904 :
9905 715 : if (p->version>=2)
9906 277 : p->size += 4;
9907 715 : p->default_length = 0;
9908 :
9909 715 : nb_descs = gf_list_count(p->group_descriptions);
9910 1404 : for (i=0; i<nb_descs; i++) {
9911 689 : void *ptr = gf_list_get(p->group_descriptions, i);
9912 689 : u32 size = sgpd_size_entry(p->grouping_type, ptr);
9913 689 : p->size += size;
9914 689 : if (use_def_size && !p->default_length) {
9915 598 : p->default_length = size;
9916 91 : } else if (p->default_length != size) {
9917 : use_def_size = GF_FALSE;
9918 3 : p->default_length = 0;
9919 : }
9920 : }
9921 715 : if (p->version>=1) {
9922 715 : if (!p->default_length) p->size += nb_descs * 4;
9923 : }
9924 715 : return GF_OK;
9925 : }
9926 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
9927 :
9928 :
9929 916 : void saiz_box_del(GF_Box *s)
9930 : {
9931 : GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
9932 916 : if (ptr == NULL) return;
9933 916 : if (ptr->sample_info_size) gf_free(ptr->sample_info_size);
9934 916 : gf_free(ptr);
9935 : }
9936 :
9937 :
9938 402 : GF_Err saiz_box_read(GF_Box *s, GF_BitStream *bs)
9939 : {
9940 : GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
9941 :
9942 402 : if (ptr->flags & 1) {
9943 9 : ISOM_DECREASE_SIZE(ptr, 8);
9944 9 : ptr->aux_info_type = gf_bs_read_u32(bs);
9945 9 : ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
9946 : }
9947 402 : ISOM_DECREASE_SIZE(ptr, 5);
9948 402 : ptr->default_sample_info_size = gf_bs_read_u8(bs);
9949 402 : ptr->sample_count = gf_bs_read_u32(bs);
9950 :
9951 402 : if (ptr->default_sample_info_size == 0) {
9952 177 : if (ptr->size < ptr->sample_count)
9953 : return GF_ISOM_INVALID_FILE;
9954 :
9955 177 : ptr->sample_info_size = gf_malloc(sizeof(u8)*ptr->sample_count);
9956 177 : ptr->sample_alloc = ptr->sample_count;
9957 177 : if (!ptr->sample_info_size)
9958 : return GF_OUT_OF_MEM;
9959 :
9960 177 : ISOM_DECREASE_SIZE(ptr, ptr->sample_count);
9961 177 : gf_bs_read_data(bs, (char *) ptr->sample_info_size, ptr->sample_count);
9962 : }
9963 : return GF_OK;
9964 : }
9965 :
9966 916 : GF_Box *saiz_box_new()
9967 : {
9968 1832 : ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoSizeBox, GF_ISOM_BOX_TYPE_SAIZ);
9969 916 : return (GF_Box *)tmp;
9970 : }
9971 :
9972 : #ifndef GPAC_DISABLE_ISOM_WRITE
9973 :
9974 437 : GF_Err saiz_box_write(GF_Box *s, GF_BitStream *bs)
9975 : {
9976 : GF_Err e;
9977 : GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*) s;
9978 437 : if (!s) return GF_BAD_PARAM;
9979 437 : e = gf_isom_full_box_write(s, bs);
9980 437 : if (e) return e;
9981 :
9982 437 : if (ptr->flags & 1) {
9983 4 : gf_bs_write_u32(bs, ptr->aux_info_type);
9984 4 : gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
9985 : }
9986 437 : gf_bs_write_u8(bs, ptr->default_sample_info_size);
9987 437 : gf_bs_write_u32(bs, ptr->sample_count);
9988 437 : if (!ptr->default_sample_info_size) {
9989 134 : if (!ptr->sample_info_size)
9990 2 : gf_bs_write_u8(bs, 0);
9991 : else
9992 132 : gf_bs_write_data(bs, (char *) ptr->sample_info_size, ptr->sample_count);
9993 : }
9994 : return GF_OK;
9995 : }
9996 :
9997 1245 : GF_Err saiz_box_size(GF_Box *s)
9998 : {
9999 : GF_SampleAuxiliaryInfoSizeBox *ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
10000 :
10001 1245 : if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
10002 12 : ptr->flags |= 1;
10003 : }
10004 1245 : if (ptr->flags & 1) ptr->size += 8;
10005 1245 : ptr->size += 5;
10006 1245 : if (ptr->default_sample_info_size==0) ptr->size += ptr->sample_count;
10007 1245 : return GF_OK;
10008 : }
10009 : #endif //GPAC_DISABLE_ISOM_WRITE
10010 :
10011 918 : void saio_box_del(GF_Box *s)
10012 : {
10013 : GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;
10014 918 : if (ptr == NULL) return;
10015 918 : if (ptr->offsets) gf_free(ptr->offsets);
10016 918 : if (ptr->cached_data) gf_free(ptr->cached_data);
10017 918 : gf_free(ptr);
10018 : }
10019 :
10020 :
10021 402 : GF_Err saio_box_read(GF_Box *s, GF_BitStream *bs)
10022 : {
10023 : GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *)s;
10024 :
10025 402 : if (ptr->flags & 1) {
10026 3 : ISOM_DECREASE_SIZE(ptr, 8);
10027 3 : ptr->aux_info_type = gf_bs_read_u32(bs);
10028 3 : ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
10029 : }
10030 402 : ISOM_DECREASE_SIZE(ptr, 4);
10031 402 : ptr->entry_count = gf_bs_read_u32(bs);
10032 :
10033 402 : if (ptr->entry_count) {
10034 : u32 i;
10035 400 : if (ptr->size / (ptr->version == 0 ? 4 : 8) < ptr->entry_count)
10036 : return GF_ISOM_INVALID_FILE;
10037 400 : ptr->offsets = gf_malloc(sizeof(u64)*ptr->entry_count);
10038 400 : if (!ptr->offsets)
10039 : return GF_OUT_OF_MEM;
10040 400 : ptr->entry_alloc = ptr->entry_count;
10041 400 : if (ptr->version==0) {
10042 3 : ISOM_DECREASE_SIZE(ptr, 4*ptr->entry_count);
10043 6 : for (i=0; i<ptr->entry_count; i++)
10044 3 : ptr->offsets[i] = gf_bs_read_u32(bs);
10045 : } else {
10046 397 : ISOM_DECREASE_SIZE(ptr, 8*ptr->entry_count);
10047 794 : for (i=0; i<ptr->entry_count; i++)
10048 397 : ptr->offsets[i] = gf_bs_read_u64(bs);
10049 : }
10050 : }
10051 : return GF_OK;
10052 : }
10053 :
10054 918 : GF_Box *saio_box_new()
10055 : {
10056 1836 : ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoOffsetBox, GF_ISOM_BOX_TYPE_SAIO);
10057 918 : return (GF_Box *)tmp;
10058 : }
10059 :
10060 : #ifndef GPAC_DISABLE_ISOM_WRITE
10061 :
10062 437 : GF_Err saio_box_write(GF_Box *s, GF_BitStream *bs)
10063 : {
10064 : GF_Err e;
10065 : GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *) s;
10066 437 : if (!s) return GF_BAD_PARAM;
10067 437 : e = gf_isom_full_box_write(s, bs);
10068 437 : if (e) return e;
10069 :
10070 437 : if (ptr->flags & 1) {
10071 1 : gf_bs_write_u32(bs, ptr->aux_info_type);
10072 1 : gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
10073 : }
10074 :
10075 :
10076 437 : gf_bs_write_u32(bs, ptr->entry_count);
10077 437 : if (ptr->entry_count) {
10078 : u32 i;
10079 : //store position in bitstream before writing data - offsets can be NULL if a single offset is rewritten later on (cf senc_box_write)
10080 435 : ptr->offset_first_offset_field = gf_bs_get_position(bs);
10081 435 : if (ptr->version==0) {
10082 0 : if (!ptr->offsets) {
10083 0 : gf_bs_write_u32(bs, 0);
10084 : } else {
10085 0 : for (i=0; i<ptr->entry_count; i++)
10086 0 : gf_bs_write_u32(bs, (u32) ptr->offsets[i]);
10087 : }
10088 : } else {
10089 435 : if (!ptr->offsets) {
10090 434 : gf_bs_write_u64(bs, 0);
10091 : } else {
10092 1 : for (i=0; i<ptr->entry_count; i++)
10093 1 : gf_bs_write_u64(bs, ptr->offsets[i]);
10094 : }
10095 : }
10096 : }
10097 : return GF_OK;
10098 : }
10099 :
10100 1245 : GF_Err saio_box_size(GF_Box *s)
10101 : {
10102 : GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;
10103 :
10104 1245 : if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
10105 3 : ptr->flags |= 1;
10106 : }
10107 :
10108 1245 : if (ptr->flags & 1) ptr->size += 8;
10109 1245 : ptr->size += 4;
10110 : //a little optim here: in cenc, the saio always points to a single data block, only one entry is needed
10111 1245 : switch (ptr->aux_info_type) {
10112 3 : case GF_ISOM_CENC_SCHEME:
10113 : case GF_ISOM_CBC_SCHEME:
10114 : case GF_ISOM_CENS_SCHEME:
10115 : case GF_ISOM_CBCS_SCHEME:
10116 3 : if (ptr->offsets) gf_free(ptr->offsets);
10117 3 : ptr->offsets = NULL;
10118 3 : ptr->entry_alloc = 0;
10119 3 : ptr->entry_count = 1;
10120 3 : break;
10121 : }
10122 :
10123 1245 : ptr->size += ((ptr->version==1) ? 8 : 4) * ptr->entry_count;
10124 1245 : return GF_OK;
10125 : }
10126 : #endif //GPAC_DISABLE_ISOM_WRITE
10127 :
10128 :
10129 4 : void prft_box_del(GF_Box *s)
10130 : {
10131 4 : gf_free(s);
10132 4 : }
10133 :
10134 1 : GF_Err prft_box_read(GF_Box *s,GF_BitStream *bs)
10135 : {
10136 : GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox *) s;
10137 :
10138 1 : ISOM_DECREASE_SIZE(ptr, 12);
10139 1 : ptr->refTrackID = gf_bs_read_u32(bs);
10140 1 : ptr->ntp = gf_bs_read_u64(bs);
10141 1 : if (ptr->version==0) {
10142 1 : ISOM_DECREASE_SIZE(ptr, 4);
10143 1 : ptr->timestamp = gf_bs_read_u32(bs);
10144 : } else {
10145 0 : ISOM_DECREASE_SIZE(ptr, 8);
10146 0 : ptr->timestamp = gf_bs_read_u64(bs);
10147 : }
10148 : return GF_OK;
10149 : }
10150 :
10151 4 : GF_Box *prft_box_new()
10152 : {
10153 8 : ISOM_DECL_BOX_ALLOC(GF_ProducerReferenceTimeBox, GF_ISOM_BOX_TYPE_PRFT);
10154 4 : return (GF_Box *)tmp;
10155 : }
10156 :
10157 : #ifndef GPAC_DISABLE_ISOM_WRITE
10158 1 : GF_Err prft_box_write(GF_Box *s, GF_BitStream *bs)
10159 : {
10160 : GF_Err e;
10161 : GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox *) s;
10162 1 : if (!s) return GF_BAD_PARAM;
10163 1 : e = gf_isom_full_box_write(s, bs);
10164 1 : if (e) return e;
10165 :
10166 1 : gf_bs_write_u32(bs, ptr->refTrackID);
10167 1 : gf_bs_write_u64(bs, ptr->ntp);
10168 1 : if (ptr->version==0) {
10169 1 : gf_bs_write_u32(bs, (u32) ptr->timestamp);
10170 : } else {
10171 0 : gf_bs_write_u64(bs, ptr->timestamp);
10172 : }
10173 :
10174 : return GF_OK;
10175 : }
10176 :
10177 1 : GF_Err prft_box_size(GF_Box *s)
10178 : {
10179 : GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox*)s;
10180 :
10181 1 : ptr->size += 4+8+ (ptr->version ? 8 : 4);
10182 1 : return GF_OK;
10183 : }
10184 : #endif //GPAC_DISABLE_ISOM_WRITE
10185 :
10186 28 : GF_Box *trgr_box_new()
10187 : {
10188 56 : ISOM_DECL_BOX_ALLOC(GF_TrackGroupBox, GF_ISOM_BOX_TYPE_TRGR);
10189 28 : tmp->groups = gf_list_new();
10190 28 : if (!tmp->groups) {
10191 0 : gf_free(tmp);
10192 0 : return NULL;
10193 : }
10194 : return (GF_Box *)tmp;
10195 : }
10196 :
10197 28 : void trgr_box_del(GF_Box *s)
10198 : {
10199 : GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
10200 28 : if (ptr == NULL) return;
10201 28 : gf_list_del(ptr->groups);
10202 28 : gf_free(ptr);
10203 : }
10204 :
10205 :
10206 19 : GF_Err trgr_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
10207 : {
10208 : GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
10209 :
10210 19 : BOX_FIELD_LIST_ASSIGN(groups)
10211 19 : return gf_list_add(ptr->groups, a);
10212 : }
10213 :
10214 :
10215 20 : GF_Err trgr_box_read(GF_Box *s, GF_BitStream *bs)
10216 : {
10217 20 : return gf_isom_box_array_read_ex(s, bs, s->type);
10218 : }
10219 :
10220 :
10221 : #ifndef GPAC_DISABLE_ISOM_WRITE
10222 :
10223 :
10224 24 : GF_Err trgr_box_write(GF_Box *s, GF_BitStream *bs)
10225 : {
10226 24 : return gf_isom_box_write_header(s, bs);
10227 : }
10228 :
10229 42 : GF_Err trgr_box_size(GF_Box *s)
10230 : {
10231 42 : u32 pos=0;
10232 : GF_TrackGroupBox *ptr = (GF_TrackGroupBox *) s;
10233 42 : gf_isom_check_position_list(s, ptr->groups, &pos);
10234 42 : return GF_OK;
10235 : }
10236 :
10237 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
10238 :
10239 :
10240 31 : GF_Box *trgt_box_new()
10241 : {
10242 62 : ISOM_DECL_BOX_ALLOC(GF_TrackGroupTypeBox, GF_ISOM_BOX_TYPE_TRGT);
10243 31 : return (GF_Box *)tmp;
10244 : }
10245 :
10246 31 : void trgt_box_del(GF_Box *s)
10247 : {
10248 : GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s;
10249 31 : if (ptr == NULL) return;
10250 31 : gf_free(ptr);
10251 : }
10252 :
10253 19 : GF_Err trgt_box_read(GF_Box *s, GF_BitStream *bs)
10254 : {
10255 : GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s;
10256 19 : ISOM_DECREASE_SIZE(ptr, 4);
10257 19 : ptr->track_group_id = gf_bs_read_u32(bs);
10258 19 : return GF_OK;
10259 : }
10260 :
10261 :
10262 : #ifndef GPAC_DISABLE_ISOM_WRITE
10263 :
10264 26 : GF_Err trgt_box_write(GF_Box *s, GF_BitStream *bs)
10265 : {
10266 : GF_Err e;
10267 : GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *) s;
10268 26 : if (!s) return GF_BAD_PARAM;
10269 26 : s->type = ptr->group_type;
10270 26 : e = gf_isom_full_box_write(s, bs);
10271 26 : s->type = GF_ISOM_BOX_TYPE_TRGT;
10272 26 : if (e) return e;
10273 26 : gf_bs_write_u32(bs, ptr->track_group_id);
10274 26 : return GF_OK;
10275 : }
10276 :
10277 44 : GF_Err trgt_box_size(GF_Box *s)
10278 : {
10279 : GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
10280 :
10281 44 : ptr->size+= 4;
10282 44 : return GF_OK;
10283 : }
10284 :
10285 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
10286 :
10287 :
10288 :
10289 3 : GF_Box *stvi_box_new()
10290 : {
10291 6 : ISOM_DECL_BOX_ALLOC(GF_StereoVideoBox, GF_ISOM_BOX_TYPE_STVI);
10292 3 : return (GF_Box *)tmp;
10293 : }
10294 :
10295 3 : void stvi_box_del(GF_Box *s)
10296 : {
10297 : GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;
10298 3 : if (ptr == NULL) return;
10299 3 : if (ptr->stereo_indication_type) gf_free(ptr->stereo_indication_type);
10300 3 : gf_free(ptr);
10301 : }
10302 :
10303 1 : GF_Err stvi_box_read(GF_Box *s, GF_BitStream *bs)
10304 : {
10305 : GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;
10306 :
10307 1 : ISOM_DECREASE_SIZE(ptr, 12);
10308 1 : gf_bs_read_int(bs, 30);
10309 1 : ptr->single_view_allowed = gf_bs_read_int(bs, 2);
10310 1 : ptr->stereo_scheme = gf_bs_read_u32(bs);
10311 1 : ptr->sit_len = gf_bs_read_u32(bs);
10312 1 : ISOM_DECREASE_SIZE(ptr, ptr->sit_len);
10313 :
10314 1 : ptr->stereo_indication_type = gf_malloc(sizeof(char)*ptr->sit_len);
10315 1 : if (!ptr->stereo_indication_type) return GF_OUT_OF_MEM;
10316 :
10317 1 : gf_bs_read_data(bs, ptr->stereo_indication_type, ptr->sit_len);
10318 1 : return GF_OK;
10319 : }
10320 :
10321 :
10322 : #ifndef GPAC_DISABLE_ISOM_WRITE
10323 :
10324 1 : GF_Err stvi_box_write(GF_Box *s, GF_BitStream *bs)
10325 : {
10326 : GF_Err e;
10327 : GF_StereoVideoBox *ptr = (GF_StereoVideoBox *) s;
10328 1 : if (!s) return GF_BAD_PARAM;
10329 1 : e = gf_isom_full_box_write(s, bs);
10330 1 : if (e) return e;
10331 :
10332 1 : gf_bs_write_int(bs, 0, 30);
10333 1 : gf_bs_write_int(bs, ptr->single_view_allowed, 2);
10334 1 : gf_bs_write_u32(bs, ptr->stereo_scheme);
10335 1 : gf_bs_write_u32(bs, ptr->sit_len);
10336 1 : gf_bs_write_data(bs, ptr->stereo_indication_type, ptr->sit_len);
10337 :
10338 1 : return GF_OK;
10339 : }
10340 :
10341 1 : GF_Err stvi_box_size(GF_Box *s)
10342 : {
10343 : GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;
10344 :
10345 1 : ptr->size+= 12 + ptr->sit_len;
10346 1 : return GF_OK;
10347 : }
10348 :
10349 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
10350 :
10351 :
10352 :
10353 3 : GF_Box *fiin_box_new()
10354 : {
10355 6 : ISOM_DECL_BOX_ALLOC(FDItemInformationBox, GF_ISOM_BOX_TYPE_FIIN);
10356 3 : return (GF_Box *)tmp;
10357 : }
10358 :
10359 3 : void fiin_box_del(GF_Box *s)
10360 : {
10361 : FDItemInformationBox *ptr = (FDItemInformationBox *)s;
10362 3 : if (ptr == NULL) return;
10363 3 : if (ptr->partition_entries) gf_list_del(ptr->partition_entries);
10364 3 : gf_free(ptr);
10365 : }
10366 :
10367 :
10368 0 : GF_Err fiin_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
10369 : {
10370 : FDItemInformationBox *ptr = (FDItemInformationBox *)s;
10371 0 : switch(a->type) {
10372 0 : case GF_ISOM_BOX_TYPE_PAEN:
10373 0 : BOX_FIELD_LIST_ASSIGN(partition_entries)
10374 : return GF_OK;
10375 0 : case GF_ISOM_BOX_TYPE_SEGR:
10376 0 : BOX_FIELD_ASSIGN(session_info, FDSessionGroupBox)
10377 0 : return GF_OK;
10378 0 : case GF_ISOM_BOX_TYPE_GITN:
10379 0 : BOX_FIELD_ASSIGN(group_id_to_name, GroupIdToNameBox)
10380 0 : return GF_OK;
10381 : }
10382 : return GF_OK;
10383 : }
10384 :
10385 1 : GF_Err fiin_box_read(GF_Box *s, GF_BitStream *bs)
10386 : {
10387 : FDItemInformationBox *ptr = (FDItemInformationBox *)s;
10388 :
10389 1 : ISOM_DECREASE_SIZE(ptr, 2);
10390 1 : gf_bs_read_u16(bs);
10391 1 : return gf_isom_box_array_read(s, bs);
10392 : }
10393 :
10394 :
10395 : #ifndef GPAC_DISABLE_ISOM_WRITE
10396 :
10397 1 : GF_Err fiin_box_write(GF_Box *s, GF_BitStream *bs)
10398 : {
10399 : GF_Err e;
10400 : FDItemInformationBox *ptr = (FDItemInformationBox *) s;
10401 1 : if (!s) return GF_BAD_PARAM;
10402 1 : e = gf_isom_full_box_write(s, bs);
10403 1 : if (e) return e;
10404 :
10405 1 : gf_bs_write_u16(bs, gf_list_count(ptr->partition_entries) );
10406 1 : return GF_OK;
10407 : }
10408 :
10409 1 : GF_Err fiin_box_size(GF_Box *s)
10410 : {
10411 1 : u32 pos=0;
10412 : FDItemInformationBox *ptr = (FDItemInformationBox *) s;
10413 1 : s->size+= 2;
10414 1 : gf_isom_check_position_list(s, ptr->partition_entries, &pos);
10415 1 : return GF_OK;
10416 : }
10417 :
10418 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
10419 :
10420 :
10421 3 : GF_Box *paen_box_new()
10422 : {
10423 6 : ISOM_DECL_BOX_ALLOC(FDPartitionEntryBox, GF_ISOM_BOX_TYPE_PAEN);
10424 3 : return (GF_Box *)tmp;
10425 : }
10426 :
10427 3 : void paen_box_del(GF_Box *s)
10428 : {
10429 3 : gf_free(s);
10430 3 : }
10431 :
10432 :
10433 0 : GF_Err paen_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
10434 : {
10435 : FDPartitionEntryBox *ptr = (FDPartitionEntryBox *)s;
10436 0 : switch(a->type) {
10437 0 : case GF_ISOM_BOX_TYPE_FPAR:
10438 0 : BOX_FIELD_ASSIGN(blocks_and_symbols, FilePartitionBox)
10439 0 : return GF_OK;
10440 0 : case GF_ISOM_BOX_TYPE_FECR:
10441 0 : BOX_FIELD_ASSIGN(FEC_symbol_locations, FECReservoirBox)
10442 0 : return GF_OK;
10443 0 : case GF_ISOM_BOX_TYPE_FIRE:
10444 0 : BOX_FIELD_ASSIGN(File_symbol_locations, FileReservoirBox)
10445 0 : return GF_OK;
10446 : }
10447 : return GF_OK;
10448 : }
10449 :
10450 1 : GF_Err paen_box_read(GF_Box *s, GF_BitStream *bs)
10451 : {
10452 1 : return gf_isom_box_array_read(s, bs);
10453 : }
10454 :
10455 : #ifndef GPAC_DISABLE_ISOM_WRITE
10456 :
10457 1 : GF_Err paen_box_write(GF_Box *s, GF_BitStream *bs)
10458 : {
10459 1 : if (!s) return GF_BAD_PARAM;
10460 1 : return gf_isom_box_write_header(s, bs);
10461 : }
10462 :
10463 1 : GF_Err paen_box_size(GF_Box *s)
10464 : {
10465 1 : return GF_OK;
10466 : }
10467 :
10468 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
10469 :
10470 :
10471 :
10472 :
10473 4 : GF_Box *fpar_box_new()
10474 : {
10475 8 : ISOM_DECL_BOX_ALLOC(FilePartitionBox, GF_ISOM_BOX_TYPE_FPAR);
10476 4 : return (GF_Box *)tmp;
10477 : }
10478 :
10479 4 : void fpar_box_del(GF_Box *s)
10480 : {
10481 : FilePartitionBox *ptr = (FilePartitionBox *)s;
10482 4 : if (ptr == NULL) return;
10483 4 : if (ptr->scheme_specific_info) gf_free(ptr->scheme_specific_info);
10484 4 : if (ptr->entries) gf_free(ptr->entries);
10485 4 : gf_free(ptr);
10486 : }
10487 :
10488 7 : GF_Err gf_isom_read_null_terminated_string(GF_Box *s, GF_BitStream *bs, u64 size, char **out_str)
10489 : {
10490 : u32 len=10;
10491 : u32 i=0;
10492 :
10493 7 : *out_str = gf_malloc(sizeof(char)*len);
10494 7 : if (! *out_str) return GF_OUT_OF_MEM;
10495 :
10496 7 : if (!s->size) {
10497 0 : *out_str[0] = 0;
10498 0 : return GF_OK;
10499 : }
10500 :
10501 : while (1) {
10502 3647 : ISOM_DECREASE_SIZE(s, 1 );
10503 3647 : (*out_str)[i] = gf_bs_read_u8(bs);
10504 3647 : if (!(*out_str)[i]) break;
10505 3640 : i++;
10506 3640 : if (i==len) {
10507 364 : len += 10;
10508 364 : *out_str = gf_realloc(*out_str, sizeof(char)*len);
10509 : }
10510 3640 : if (gf_bs_available(bs) == 0) {
10511 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] missing null character in null terminated string\n"));
10512 0 : (*out_str)[i] = 0;
10513 0 : return GF_OK;
10514 : }
10515 3640 : if (i >= size) {
10516 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] string bigger than container, probably missing null character\n"));
10517 0 : (*out_str)[i] = 0;
10518 0 : return GF_OK;
10519 : }
10520 : }
10521 : return GF_OK;
10522 : }
10523 :
10524 1 : GF_Err fpar_box_read(GF_Box *s, GF_BitStream *bs)
10525 : {
10526 : u32 i;
10527 : GF_Err e;
10528 : FilePartitionBox *ptr = (FilePartitionBox *)s;
10529 :
10530 1 : ISOM_DECREASE_SIZE(ptr, ((ptr->version ? 4 : 2) + 12) );
10531 1 : ptr->itemID = gf_bs_read_int(bs, ptr->version ? 32 : 16);
10532 1 : ptr->packet_payload_size = gf_bs_read_u16(bs);
10533 1 : gf_bs_read_u8(bs);
10534 1 : ptr->FEC_encoding_ID = gf_bs_read_u8(bs);
10535 1 : ptr->FEC_instance_ID = gf_bs_read_u16(bs);
10536 1 : ptr->max_source_block_length = gf_bs_read_u16(bs);
10537 1 : ptr->encoding_symbol_length = gf_bs_read_u16(bs);
10538 1 : ptr->max_number_of_encoding_symbols = gf_bs_read_u16(bs);
10539 :
10540 1 : e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_specific_info);
10541 1 : if (e) return e;
10542 :
10543 1 : ISOM_DECREASE_SIZE(ptr, (ptr->version ? 4 : 2) );
10544 1 : ptr->nb_entries = gf_bs_read_int(bs, ptr->version ? 32 : 16);
10545 1 : if (ptr->nb_entries > ptr->size / 6)
10546 : return GF_ISOM_INVALID_FILE;
10547 :
10548 1 : ISOM_DECREASE_SIZE(ptr, ptr->nb_entries * 6 );
10549 1 : GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, FilePartitionEntry);
10550 1 : if (!ptr->entries) return GF_OUT_OF_MEM;
10551 :
10552 0 : for (i=0;i < ptr->nb_entries; i++) {
10553 0 : ptr->entries[i].block_count = gf_bs_read_u16(bs);
10554 0 : ptr->entries[i].block_size = gf_bs_read_u32(bs);
10555 : }
10556 : return GF_OK;
10557 : }
10558 :
10559 :
10560 : #ifndef GPAC_DISABLE_ISOM_WRITE
10561 :
10562 1 : GF_Err fpar_box_write(GF_Box *s, GF_BitStream *bs)
10563 : {
10564 : GF_Err e;
10565 : u32 i;
10566 : FilePartitionBox *ptr = (FilePartitionBox *) s;
10567 1 : if (!s) return GF_BAD_PARAM;
10568 1 : e = gf_isom_full_box_write(s, bs);
10569 1 : if (e) return e;
10570 :
10571 1 : gf_bs_write_int(bs, ptr->itemID, ptr->version ? 32 : 16);
10572 1 : gf_bs_write_u16(bs, ptr->packet_payload_size);
10573 1 : gf_bs_write_u8(bs, 0);
10574 1 : gf_bs_write_u8(bs, ptr->FEC_encoding_ID);
10575 1 : gf_bs_write_u16(bs, ptr->FEC_instance_ID);
10576 1 : gf_bs_write_u16(bs, ptr->max_source_block_length);
10577 1 : gf_bs_write_u16(bs, ptr->encoding_symbol_length);
10578 1 : gf_bs_write_u16(bs, ptr->max_number_of_encoding_symbols);
10579 1 : if (ptr->scheme_specific_info) {
10580 0 : gf_bs_write_data(bs, ptr->scheme_specific_info, (u32)strlen(ptr->scheme_specific_info) );
10581 : }
10582 : //null terminated string
10583 1 : gf_bs_write_u8(bs, 0);
10584 :
10585 1 : gf_bs_write_int(bs, ptr->nb_entries, ptr->version ? 32 : 16);
10586 :
10587 1 : for (i=0;i < ptr->nb_entries; i++) {
10588 0 : gf_bs_write_u16(bs, ptr->entries[i].block_count);
10589 0 : gf_bs_write_u32(bs, ptr->entries[i].block_size);
10590 : }
10591 : return GF_OK;
10592 : }
10593 :
10594 1 : GF_Err fpar_box_size(GF_Box *s)
10595 : {
10596 : FilePartitionBox *ptr = (FilePartitionBox *)s;
10597 :
10598 1 : ptr->size += 13 + (ptr->version ? 8 : 4);
10599 1 : if (ptr->scheme_specific_info)
10600 0 : ptr->size += strlen(ptr->scheme_specific_info);
10601 :
10602 1 : ptr->size+= ptr->nb_entries * 6;
10603 1 : return GF_OK;
10604 : }
10605 :
10606 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
10607 :
10608 :
10609 8 : GF_Box *fecr_box_new()
10610 : {
10611 16 : ISOM_DECL_BOX_ALLOC(FECReservoirBox, GF_ISOM_BOX_TYPE_FECR);
10612 8 : return (GF_Box *)tmp;
10613 : }
10614 :
10615 8 : void fecr_box_del(GF_Box *s)
10616 : {
10617 : FECReservoirBox *ptr = (FECReservoirBox *)s;
10618 8 : if (ptr == NULL) return;
10619 8 : if (ptr->entries) gf_free(ptr->entries);
10620 8 : gf_free(ptr);
10621 : }
10622 :
10623 2 : GF_Err fecr_box_read(GF_Box *s, GF_BitStream *bs)
10624 : {
10625 : u32 i;
10626 : FECReservoirBox *ptr = (FECReservoirBox *)s;
10627 :
10628 2 : ISOM_DECREASE_SIZE(ptr, (ptr->version ? 4 : 2) );
10629 2 : ptr->nb_entries = gf_bs_read_int(bs, ptr->version ? 32 : 16);
10630 :
10631 2 : ISOM_DECREASE_SIZE(ptr, ptr->nb_entries * (ptr->version ? 8 : 6) );
10632 2 : GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, FECReservoirEntry);
10633 2 : if (!ptr->entries) return GF_OUT_OF_MEM;
10634 :
10635 0 : for (i=0; i<ptr->nb_entries; i++) {
10636 0 : ptr->entries[i].item_id = gf_bs_read_int(bs, ptr->version ? 32 : 16);
10637 0 : ptr->entries[i].symbol_count = gf_bs_read_u32(bs);
10638 : }
10639 : return GF_OK;
10640 : }
10641 :
10642 :
10643 : #ifndef GPAC_DISABLE_ISOM_WRITE
10644 :
10645 2 : GF_Err fecr_box_write(GF_Box *s, GF_BitStream *bs)
10646 : {
10647 : GF_Err e;
10648 : u32 i;
10649 : FECReservoirBox *ptr = (FECReservoirBox *) s;
10650 2 : if (!s) return GF_BAD_PARAM;
10651 2 : e = gf_isom_full_box_write(s, bs);
10652 2 : if (e) return e;
10653 :
10654 2 : gf_bs_write_int(bs, ptr->nb_entries, ptr->version ? 32 : 16);
10655 2 : for (i=0; i<ptr->nb_entries; i++) {
10656 0 : gf_bs_write_int(bs, ptr->entries[i].item_id, ptr->version ? 32 : 16);
10657 0 : gf_bs_write_u32(bs, ptr->entries[i].symbol_count);
10658 : }
10659 : return GF_OK;
10660 : }
10661 :
10662 2 : GF_Err fecr_box_size(GF_Box *s)
10663 : {
10664 : FECReservoirBox *ptr = (FECReservoirBox *)s;
10665 2 : ptr->size += (ptr->version ? 4 : 2) + ptr->nb_entries * (ptr->version ? 8 : 6);
10666 2 : return GF_OK;
10667 : }
10668 :
10669 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
10670 :
10671 :
10672 :
10673 3 : GF_Box *segr_box_new()
10674 : {
10675 6 : ISOM_DECL_BOX_ALLOC(FDSessionGroupBox, GF_ISOM_BOX_TYPE_SEGR);
10676 3 : return (GF_Box *)tmp;
10677 : }
10678 :
10679 3 : void segr_box_del(GF_Box *s)
10680 : {
10681 : u32 i;
10682 : FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;
10683 3 : if (ptr == NULL) return;
10684 0 : for (i=0; i<ptr->num_session_groups; i++) {
10685 0 : if (ptr->session_groups[i].group_ids) gf_free(ptr->session_groups[i].group_ids);
10686 0 : if (ptr->session_groups[i].channels) gf_free(ptr->session_groups[i].channels);
10687 : }
10688 3 : if (ptr->session_groups) gf_free(ptr->session_groups);
10689 3 : gf_free(ptr);
10690 : }
10691 :
10692 1 : GF_Err segr_box_read(GF_Box *s, GF_BitStream *bs)
10693 : {
10694 : u32 i, k;
10695 : FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;
10696 :
10697 1 : ISOM_DECREASE_SIZE(ptr, 2);
10698 1 : ptr->num_session_groups = gf_bs_read_u16(bs);
10699 1 : if (ptr->size < ptr->num_session_groups) {
10700 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in segr\n", ptr->num_session_groups));
10701 0 : ptr->num_session_groups = 0;
10702 0 : return GF_ISOM_INVALID_FILE;
10703 : }
10704 :
10705 1 : GF_SAFE_ALLOC_N(ptr->session_groups, ptr->num_session_groups, SessionGroupEntry);
10706 1 : if (!ptr->session_groups) return GF_OUT_OF_MEM;
10707 :
10708 0 : for (i=0; i<ptr->num_session_groups; i++) {
10709 0 : ptr->session_groups[i].nb_groups = gf_bs_read_u8(bs);
10710 0 : ISOM_DECREASE_SIZE(ptr, 1);
10711 :
10712 0 : ISOM_DECREASE_SIZE(ptr, ptr->session_groups[i].nb_groups*4);
10713 :
10714 0 : GF_SAFE_ALLOC_N(ptr->session_groups[i].group_ids, ptr->session_groups[i].nb_groups, u32);
10715 0 : if (!ptr->session_groups[i].group_ids) return GF_OUT_OF_MEM;
10716 :
10717 0 : for (k=0; k<ptr->session_groups[i].nb_groups; k++) {
10718 0 : ptr->session_groups[i].group_ids[k] = gf_bs_read_u32(bs);
10719 : }
10720 :
10721 0 : ptr->session_groups[i].nb_channels = gf_bs_read_u16(bs);
10722 0 : ISOM_DECREASE_SIZE(ptr, ptr->session_groups[i].nb_channels*4);
10723 :
10724 0 : GF_SAFE_ALLOC_N(ptr->session_groups[i].channels, ptr->session_groups[i].nb_channels, u32);
10725 0 : if (!ptr->session_groups[i].channels) return GF_OUT_OF_MEM;
10726 :
10727 0 : for (k=0; k<ptr->session_groups[i].nb_channels; k++) {
10728 0 : ptr->session_groups[i].channels[k] = gf_bs_read_u32(bs);
10729 : }
10730 : }
10731 : return GF_OK;
10732 : }
10733 :
10734 :
10735 : #ifndef GPAC_DISABLE_ISOM_WRITE
10736 :
10737 1 : GF_Err segr_box_write(GF_Box *s, GF_BitStream *bs)
10738 : {
10739 : u32 i, k;
10740 : GF_Err e;
10741 : FDSessionGroupBox *ptr = (FDSessionGroupBox *) s;
10742 1 : if (!s) return GF_BAD_PARAM;
10743 :
10744 1 : e = gf_isom_box_write_header(s, bs);
10745 1 : if (e) return e;
10746 :
10747 1 : gf_bs_write_u16(bs, ptr->num_session_groups);
10748 1 : for (i=0; i<ptr->num_session_groups; i++) {
10749 0 : gf_bs_write_u8(bs, ptr->session_groups[i].nb_groups);
10750 0 : for (k=0; k<ptr->session_groups[i].nb_groups; k++) {
10751 0 : gf_bs_write_u32(bs, ptr->session_groups[i].group_ids[k]);
10752 : }
10753 :
10754 0 : gf_bs_write_u16(bs, ptr->session_groups[i].nb_channels);
10755 0 : for (k=0; k<ptr->session_groups[i].nb_channels; k++) {
10756 0 : gf_bs_write_u32(bs, ptr->session_groups[i].channels[k]);
10757 : }
10758 : }
10759 : return GF_OK;
10760 : }
10761 :
10762 1 : GF_Err segr_box_size(GF_Box *s)
10763 : {
10764 : u32 i;
10765 : FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;
10766 :
10767 1 : ptr->size += 2;
10768 :
10769 1 : for (i=0; i<ptr->num_session_groups; i++) {
10770 0 : ptr->size += 1 + 4*ptr->session_groups[i].nb_groups;
10771 0 : ptr->size += 2 + 4*ptr->session_groups[i].nb_channels;
10772 : }
10773 1 : return GF_OK;
10774 : }
10775 :
10776 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
10777 :
10778 :
10779 3 : GF_Box *gitn_box_new()
10780 : {
10781 6 : ISOM_DECL_BOX_ALLOC(GroupIdToNameBox, GF_ISOM_BOX_TYPE_GITN);
10782 3 : return (GF_Box *)tmp;
10783 : }
10784 :
10785 3 : void gitn_box_del(GF_Box *s)
10786 : {
10787 : u32 i;
10788 : GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;
10789 3 : if (ptr == NULL) return;
10790 0 : for (i=0; i<ptr->nb_entries; i++) {
10791 0 : if (ptr->entries[i].name) gf_free(ptr->entries[i].name);
10792 : }
10793 3 : if (ptr->entries) gf_free(ptr->entries);
10794 3 : gf_free(ptr);
10795 : }
10796 :
10797 1 : GF_Err gitn_box_read(GF_Box *s, GF_BitStream *bs)
10798 : {
10799 : u32 i;
10800 : GF_Err e;
10801 : GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;
10802 :
10803 1 : ISOM_DECREASE_SIZE(ptr, 2);
10804 1 : ptr->nb_entries = gf_bs_read_u16(bs);
10805 1 : if (ptr->size / 4 < ptr->nb_entries)
10806 : return GF_ISOM_INVALID_FILE;
10807 :
10808 1 : GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, GroupIdNameEntry);
10809 1 : if (!ptr->entries) return GF_OUT_OF_MEM;
10810 :
10811 0 : for (i=0; i<ptr->nb_entries; i++) {
10812 0 : ISOM_DECREASE_SIZE(ptr, 4);
10813 0 : ptr->entries[i].group_id = gf_bs_read_u32(bs);
10814 :
10815 0 : e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->entries[i].name);
10816 0 : if (e) return e;
10817 : }
10818 : return GF_OK;
10819 : }
10820 :
10821 :
10822 : #ifndef GPAC_DISABLE_ISOM_WRITE
10823 :
10824 1 : GF_Err gitn_box_write(GF_Box *s, GF_BitStream *bs)
10825 : {
10826 : GF_Err e;
10827 : u32 i;
10828 : GroupIdToNameBox *ptr = (GroupIdToNameBox *) s;
10829 1 : if (!s) return GF_BAD_PARAM;
10830 1 : e = gf_isom_full_box_write(s, bs);
10831 1 : if (e) return e;
10832 :
10833 1 : gf_bs_write_u16(bs, ptr->nb_entries);
10834 1 : for (i=0; i<ptr->nb_entries; i++) {
10835 0 : gf_bs_write_u32(bs, ptr->entries[i].group_id);
10836 0 : if (ptr->entries[i].name) gf_bs_write_data(bs, ptr->entries[i].name, (u32)strlen(ptr->entries[i].name) );
10837 0 : gf_bs_write_u8(bs, 0);
10838 : }
10839 : return GF_OK;
10840 : }
10841 :
10842 1 : GF_Err gitn_box_size(GF_Box *s)
10843 : {
10844 : u32 i;
10845 : GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;
10846 1 : ptr->size += 2;
10847 :
10848 1 : for (i=0; i<ptr->nb_entries; i++) {
10849 0 : ptr->size += 5;
10850 0 : if (ptr->entries[i].name) ptr->size += strlen(ptr->entries[i].name);
10851 : }
10852 1 : return GF_OK;
10853 : }
10854 :
10855 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
10856 :
10857 : #ifndef GPAC_DISABLE_ISOM_HINTING
10858 :
10859 3 : GF_Box *fdpa_box_new()
10860 : {
10861 6 : ISOM_DECL_BOX_ALLOC(GF_FDpacketBox, GF_ISOM_BOX_TYPE_FDPA);
10862 3 : return (GF_Box *)tmp;
10863 : }
10864 :
10865 3 : void fdpa_box_del(GF_Box *s)
10866 : {
10867 : u32 i;
10868 : GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;
10869 3 : if (ptr == NULL) return;
10870 :
10871 3 : if (ptr->headers) {
10872 0 : for (i=0; i<ptr->header_ext_count; i++) {
10873 0 : if (ptr->headers[i].data) gf_free(ptr->headers[i].data);
10874 : }
10875 1 : gf_free(ptr->headers);
10876 : }
10877 3 : gf_free(ptr);
10878 : }
10879 :
10880 1 : GF_Err fdpa_box_read(GF_Box *s, GF_BitStream *bs)
10881 : {
10882 : u32 i;
10883 : GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;
10884 :
10885 1 : ISOM_DECREASE_SIZE(ptr, 3);
10886 1 : ptr->info.sender_current_time_present = gf_bs_read_int(bs, 1);
10887 1 : ptr->info.expected_residual_time_present = gf_bs_read_int(bs, 1);
10888 1 : ptr->info.session_close_bit = gf_bs_read_int(bs, 1);
10889 1 : ptr->info.object_close_bit = gf_bs_read_int(bs, 1);
10890 1 : gf_bs_read_int(bs, 4);
10891 1 : ptr->info.transport_object_identifier = gf_bs_read_u16(bs);
10892 1 : ISOM_DECREASE_SIZE(ptr, 2);
10893 1 : ptr->header_ext_count = gf_bs_read_u16(bs);
10894 1 : if (ptr->size / 2 < ptr->header_ext_count) {
10895 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in fdpa\n", ptr->header_ext_count));
10896 : return GF_ISOM_INVALID_FILE;
10897 : }
10898 :
10899 1 : GF_SAFE_ALLOC_N(ptr->headers, ptr->header_ext_count, GF_LCTheaderExtension);
10900 1 : if (!ptr->headers) return GF_OUT_OF_MEM;
10901 :
10902 0 : for (i=0; i<ptr->header_ext_count; i++) {
10903 0 : ptr->headers[i].header_extension_type = gf_bs_read_u8(bs);
10904 0 : ISOM_DECREASE_SIZE(ptr, 1);
10905 :
10906 0 : if (ptr->headers[i].header_extension_type > 127) {
10907 0 : ISOM_DECREASE_SIZE(ptr, 3);
10908 0 : gf_bs_read_data(bs, (char *) ptr->headers[i].content, 3);
10909 : } else {
10910 0 : ISOM_DECREASE_SIZE(ptr, 1);
10911 0 : ptr->headers[i].data_length = gf_bs_read_u8(bs);
10912 0 : if (ptr->headers[i].data_length) {
10913 0 : ptr->headers[i].data_length = 4*ptr->headers[i].data_length - 2;
10914 0 : if (ptr->size < sizeof(char) * ptr->headers[i].data_length)
10915 : return GF_ISOM_INVALID_FILE;
10916 0 : ptr->headers[i].data = gf_malloc(sizeof(char) * ptr->headers[i].data_length);
10917 0 : if (!ptr->headers[i].data) return GF_OUT_OF_MEM;
10918 :
10919 0 : ISOM_DECREASE_SIZE(ptr, ptr->headers[i].data_length);
10920 0 : gf_bs_read_data(bs, ptr->headers[i].data, ptr->headers[i].data_length);
10921 : }
10922 : }
10923 : }
10924 : return GF_OK;
10925 : }
10926 :
10927 : #ifndef GPAC_DISABLE_ISOM_WRITE
10928 :
10929 1 : GF_Err fdpa_box_write(GF_Box *s, GF_BitStream *bs)
10930 : {
10931 : GF_Err e;
10932 : u32 i;
10933 : GF_FDpacketBox *ptr = (GF_FDpacketBox *) s;
10934 1 : if (!s) return GF_BAD_PARAM;
10935 :
10936 1 : e = gf_isom_box_write_header(s, bs);
10937 1 : if (e) return e;
10938 :
10939 1 : gf_bs_write_int(bs, ptr->info.sender_current_time_present, 1);
10940 1 : gf_bs_write_int(bs, ptr->info.expected_residual_time_present, 1);
10941 1 : gf_bs_write_int(bs, ptr->info.session_close_bit, 1);
10942 1 : gf_bs_write_int(bs, ptr->info.object_close_bit, 1);
10943 1 : gf_bs_write_int(bs, 0, 4);
10944 1 : gf_bs_write_u16(bs, ptr->info.transport_object_identifier);
10945 1 : gf_bs_write_u16(bs, ptr->header_ext_count);
10946 1 : for (i=0; i<ptr->header_ext_count; i++) {
10947 0 : gf_bs_write_u8(bs, ptr->headers[i].header_extension_type);
10948 0 : if (ptr->headers[i].header_extension_type > 127) {
10949 0 : gf_bs_write_data(bs, (const char *) ptr->headers[i].content, 3);
10950 : } else {
10951 0 : gf_bs_write_u8(bs, ptr->headers[i].data_length ? (ptr->headers[i].data_length+2)/4 : 0);
10952 0 : if (ptr->headers[i].data_length) {
10953 0 : gf_bs_write_data(bs, ptr->headers[i].data, ptr->headers[i].data_length);
10954 : }
10955 : }
10956 : }
10957 : return GF_OK;
10958 : }
10959 :
10960 1 : GF_Err fdpa_box_size(GF_Box *s)
10961 : {
10962 : u32 i;
10963 : GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;
10964 :
10965 1 : ptr->size += 5;
10966 :
10967 1 : for (i=0; i<ptr->header_ext_count; i++) {
10968 0 : ptr->size += 1;
10969 0 : if (ptr->headers[i].header_extension_type > 127) {
10970 0 : ptr->size += 3;
10971 : } else {
10972 0 : ptr->size += 1 + ptr->headers[i].data_length;
10973 : }
10974 : }
10975 1 : return GF_OK;
10976 : }
10977 :
10978 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
10979 :
10980 :
10981 3 : GF_Box *extr_box_new()
10982 : {
10983 6 : ISOM_DECL_BOX_ALLOC(GF_ExtraDataBox, GF_ISOM_BOX_TYPE_EXTR);
10984 3 : return (GF_Box *)tmp;
10985 : }
10986 :
10987 3 : void extr_box_del(GF_Box *s)
10988 : {
10989 : GF_ExtraDataBox *ptr = (GF_ExtraDataBox *)s;
10990 3 : if (ptr == NULL) return;
10991 3 : if (ptr->feci) gf_isom_box_del((GF_Box*)ptr->feci);
10992 3 : if (ptr->data) gf_free(ptr->data);
10993 3 : gf_free(ptr);
10994 : }
10995 :
10996 1 : GF_Err extr_box_read(GF_Box *s, GF_BitStream *bs)
10997 : {
10998 : GF_Err e;
10999 : GF_ExtraDataBox *ptr = (GF_ExtraDataBox *)s;
11000 :
11001 1 : e = gf_isom_box_parse((GF_Box**) &ptr->feci, bs);
11002 1 : if (e) return e;
11003 0 : if (!ptr->feci || ptr->feci->size > ptr->size) return GF_ISOM_INVALID_MEDIA;
11004 0 : ptr->data_length = (u32) (ptr->size - ptr->feci->size);
11005 0 : ptr->data = gf_malloc(sizeof(char)*ptr->data_length);
11006 0 : if (!ptr->data) return GF_OUT_OF_MEM;
11007 0 : gf_bs_read_data(bs, ptr->data, ptr->data_length);
11008 :
11009 0 : return GF_OK;
11010 : }
11011 :
11012 :
11013 : #ifndef GPAC_DISABLE_ISOM_WRITE
11014 :
11015 1 : GF_Err extr_box_write(GF_Box *s, GF_BitStream *bs)
11016 : {
11017 : GF_Err e;
11018 : GF_ExtraDataBox *ptr = (GF_ExtraDataBox *) s;
11019 1 : if (!s) return GF_BAD_PARAM;
11020 :
11021 1 : e = gf_isom_box_write_header(s, bs);
11022 1 : if (e) return e;
11023 :
11024 1 : if (ptr->feci) {
11025 0 : e = gf_isom_box_write((GF_Box *)ptr->feci, bs);
11026 0 : if (e) return e;
11027 : }
11028 1 : gf_bs_write_data(bs, ptr->data, ptr->data_length);
11029 1 : return GF_OK;
11030 : }
11031 :
11032 1 : GF_Err extr_box_size(GF_Box *s)
11033 : {
11034 : GF_ExtraDataBox *ptr = (GF_ExtraDataBox *) s;
11035 1 : ptr->size += ptr->data_length;
11036 1 : if (ptr->feci) {
11037 0 : GF_Err e = gf_isom_box_size((GF_Box*)ptr->feci);
11038 0 : if (e) return e;
11039 0 : ptr->size += ptr->feci->size;
11040 : }
11041 : return GF_OK;
11042 : }
11043 :
11044 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11045 :
11046 :
11047 :
11048 3 : GF_Box *fdsa_box_new()
11049 : {
11050 6 : ISOM_DECL_BOX_ALLOC(GF_HintSample, GF_ISOM_BOX_TYPE_FDSA);
11051 : if (!tmp) return NULL;
11052 3 : tmp->packetTable = gf_list_new();
11053 3 : tmp->hint_subtype = GF_ISOM_BOX_TYPE_FDP_STSD;
11054 3 : return (GF_Box*)tmp;
11055 : }
11056 :
11057 3 : void fdsa_box_del(GF_Box *s)
11058 : {
11059 : GF_HintSample *ptr = (GF_HintSample *)s;
11060 3 : gf_list_del(ptr->packetTable);
11061 3 : gf_free(ptr);
11062 3 : }
11063 :
11064 0 : GF_Err fdsa_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
11065 : {
11066 : GF_HintSample *ptr = (GF_HintSample *)s;
11067 0 : switch(a->type) {
11068 0 : case GF_ISOM_BOX_TYPE_FDPA:
11069 0 : BOX_FIELD_LIST_ASSIGN(packetTable)
11070 : return GF_OK;
11071 0 : case GF_ISOM_BOX_TYPE_EXTR:
11072 0 : BOX_FIELD_ASSIGN(extra_data, GF_ExtraDataBox)
11073 0 : break;
11074 : }
11075 : return GF_OK;
11076 : }
11077 1 : GF_Err fdsa_box_read(GF_Box *s, GF_BitStream *bs)
11078 : {
11079 1 : return gf_isom_box_array_read(s, bs);
11080 : }
11081 :
11082 :
11083 : #ifndef GPAC_DISABLE_ISOM_WRITE
11084 :
11085 1 : GF_Err fdsa_box_write(GF_Box *s, GF_BitStream *bs)
11086 : {
11087 : GF_Err e;
11088 : GF_HintSample *ptr = (GF_HintSample *) s;
11089 1 : if (!s) return GF_BAD_PARAM;
11090 :
11091 1 : e = gf_isom_box_write_header(s, bs);
11092 1 : if (e) return e;
11093 :
11094 1 : e = gf_isom_box_array_write(s, ptr->packetTable, bs);
11095 1 : if (e) return e;
11096 1 : if (ptr->extra_data) {
11097 0 : e = gf_isom_box_write((GF_Box *)ptr->extra_data, bs);
11098 0 : if (e) return e;
11099 : }
11100 : return GF_OK;
11101 : }
11102 :
11103 1 : GF_Err fdsa_box_size(GF_Box *s)
11104 : {
11105 1 : return GF_OK;
11106 : }
11107 :
11108 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11109 :
11110 : #endif /*GPAC_DISABLE_ISOM_HINTING*/
11111 :
11112 :
11113 3 : void trik_box_del(GF_Box *s)
11114 : {
11115 : GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
11116 3 : if (ptr == NULL) return;
11117 3 : if (ptr->entries) gf_free(ptr->entries);
11118 3 : gf_free(ptr);
11119 : }
11120 :
11121 1 : GF_Err trik_box_read(GF_Box *s,GF_BitStream *bs)
11122 : {
11123 : u32 i;
11124 : GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
11125 1 : ptr->entry_count = (u32) ptr->size;
11126 1 : ptr->entries = (GF_TrickPlayBoxEntry *) gf_malloc(ptr->entry_count * sizeof(GF_TrickPlayBoxEntry) );
11127 1 : if (!ptr->entries) return GF_OUT_OF_MEM;
11128 :
11129 0 : for (i=0; i< ptr->entry_count; i++) {
11130 0 : ptr->entries[i].pic_type = gf_bs_read_int(bs, 2);
11131 0 : ptr->entries[i].dependency_level = gf_bs_read_int(bs, 6);
11132 : }
11133 : return GF_OK;
11134 : }
11135 :
11136 3 : GF_Box *trik_box_new()
11137 : {
11138 6 : ISOM_DECL_BOX_ALLOC(GF_TrickPlayBox, GF_ISOM_BOX_TYPE_TRIK);
11139 3 : return (GF_Box *)tmp;
11140 : }
11141 :
11142 : #ifndef GPAC_DISABLE_ISOM_WRITE
11143 :
11144 1 : GF_Err trik_box_write(GF_Box *s, GF_BitStream *bs)
11145 : {
11146 : GF_Err e;
11147 : u32 i;
11148 : GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
11149 :
11150 1 : e = gf_isom_full_box_write(s, bs);
11151 1 : if (e) return e;
11152 :
11153 0 : for (i=0; i < ptr->entry_count; i++ ) {
11154 0 : gf_bs_write_int(bs, ptr->entries[i].pic_type, 2);
11155 0 : gf_bs_write_int(bs, ptr->entries[i].dependency_level, 6);
11156 : }
11157 : return GF_OK;
11158 : }
11159 :
11160 1 : GF_Err trik_box_size(GF_Box *s)
11161 : {
11162 : GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
11163 1 : ptr->size += 8 * ptr->entry_count;
11164 1 : return GF_OK;
11165 : }
11166 :
11167 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11168 :
11169 :
11170 3 : void bloc_box_del(GF_Box *s)
11171 : {
11172 3 : gf_free(s);
11173 3 : }
11174 :
11175 1 : GF_Err bloc_box_read(GF_Box *s,GF_BitStream *bs)
11176 : {
11177 : GF_BaseLocationBox *ptr = (GF_BaseLocationBox *) s;
11178 :
11179 1 : ISOM_DECREASE_SIZE(s, 256)
11180 1 : gf_bs_read_data(bs, (char *) ptr->baseLocation, 256);
11181 1 : ISOM_DECREASE_SIZE(s, 256)
11182 1 : gf_bs_read_data(bs, (char *) ptr->basePurlLocation, 256);
11183 1 : ISOM_DECREASE_SIZE(s, 512)
11184 1 : gf_bs_skip_bytes(bs, 512);
11185 1 : return GF_OK;
11186 : }
11187 :
11188 3 : GF_Box *bloc_box_new()
11189 : {
11190 6 : ISOM_DECL_BOX_ALLOC(GF_BaseLocationBox, GF_ISOM_BOX_TYPE_TRIK);
11191 3 : return (GF_Box *)tmp;
11192 : }
11193 :
11194 : #ifndef GPAC_DISABLE_ISOM_WRITE
11195 :
11196 1 : GF_Err bloc_box_write(GF_Box *s, GF_BitStream *bs)
11197 : {
11198 : GF_Err e;
11199 : u32 i;
11200 : GF_BaseLocationBox *ptr = (GF_BaseLocationBox *) s;
11201 :
11202 1 : e = gf_isom_full_box_write(s, bs);
11203 1 : if (e) return e;
11204 1 : gf_bs_write_data(bs, (const char *) ptr->baseLocation, 256);
11205 1 : gf_bs_write_data(bs, (const char *) ptr->basePurlLocation, 256);
11206 65 : for (i=0; i < 64; i++ ) {
11207 64 : gf_bs_write_u64(bs, 0);
11208 : }
11209 : return GF_OK;
11210 : }
11211 :
11212 1 : GF_Err bloc_box_size(GF_Box *s)
11213 : {
11214 1 : s->size += 1024;
11215 1 : return GF_OK;
11216 : }
11217 :
11218 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11219 :
11220 3 : void ainf_box_del(GF_Box *s)
11221 : {
11222 : GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
11223 3 : if (ptr->APID) gf_free(ptr->APID);
11224 3 : gf_free(s);
11225 3 : }
11226 :
11227 1 : GF_Err ainf_box_read(GF_Box *s,GF_BitStream *bs)
11228 : {
11229 : GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
11230 :
11231 1 : ISOM_DECREASE_SIZE(s, 4)
11232 1 : ptr->profile_version = gf_bs_read_u32(bs);
11233 1 : return gf_isom_read_null_terminated_string(s, bs, s->size, &ptr->APID);
11234 : }
11235 :
11236 3 : GF_Box *ainf_box_new()
11237 : {
11238 6 : ISOM_DECL_BOX_ALLOC(GF_AssetInformationBox, GF_ISOM_BOX_TYPE_AINF);
11239 3 : return (GF_Box *)tmp;
11240 : }
11241 :
11242 : #ifndef GPAC_DISABLE_ISOM_WRITE
11243 :
11244 1 : GF_Err ainf_box_write(GF_Box *s, GF_BitStream *bs)
11245 : {
11246 : GF_Err e;
11247 : GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
11248 :
11249 1 : e = gf_isom_full_box_write(s, bs);
11250 1 : if (e) return e;
11251 1 : gf_bs_write_u32(bs, ptr->profile_version);
11252 1 : if (ptr->APID)
11253 0 : gf_bs_write_data(bs, ptr->APID, (u32) strlen(ptr->APID) );
11254 1 : gf_bs_write_u8(bs, 0);
11255 1 : return GF_OK;
11256 : }
11257 :
11258 1 : GF_Err ainf_box_size(GF_Box *s)
11259 : {
11260 : GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
11261 1 : s->size += 4 + (ptr->APID ? strlen(ptr->APID) : 0 ) + 1;
11262 1 : return GF_OK;
11263 : }
11264 :
11265 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11266 :
11267 :
11268 4 : void mhac_box_del(GF_Box *s)
11269 : {
11270 : GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;
11271 4 : if (ptr->mha_config) gf_free(ptr->mha_config);
11272 4 : gf_free(s);
11273 4 : }
11274 :
11275 1 : GF_Err mhac_box_read(GF_Box *s,GF_BitStream *bs)
11276 : {
11277 : GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;
11278 :
11279 1 : ISOM_DECREASE_SIZE(s, 5)
11280 1 : ptr->configuration_version = gf_bs_read_u8(bs);
11281 1 : ptr->mha_pl_indication = gf_bs_read_u8(bs);
11282 1 : ptr->reference_channel_layout = gf_bs_read_u8(bs);
11283 1 : ptr->mha_config_size = gf_bs_read_u16(bs);
11284 1 : if (ptr->mha_config_size) {
11285 0 : ISOM_DECREASE_SIZE(s, ptr->mha_config_size)
11286 :
11287 0 : ptr->mha_config = gf_malloc(sizeof(char)*ptr->mha_config_size);
11288 0 : if (!ptr->mha_config) return GF_OUT_OF_MEM;
11289 :
11290 0 : gf_bs_read_data(bs, ptr->mha_config, ptr->mha_config_size);
11291 : }
11292 : return GF_OK;
11293 : }
11294 :
11295 4 : GF_Box *mhac_box_new()
11296 : {
11297 8 : ISOM_DECL_BOX_ALLOC(GF_MHAConfigBox, GF_ISOM_BOX_TYPE_MHAC);
11298 4 : tmp->configuration_version = 1;
11299 4 : return (GF_Box *)tmp;
11300 : }
11301 :
11302 : #ifndef GPAC_DISABLE_ISOM_WRITE
11303 :
11304 2 : GF_Err mhac_box_write(GF_Box *s, GF_BitStream *bs)
11305 : {
11306 : GF_Err e;
11307 : GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;
11308 :
11309 2 : e = gf_isom_box_write_header(s, bs);
11310 2 : if (e) return e;
11311 2 : gf_bs_write_u8(bs, ptr->configuration_version);
11312 2 : gf_bs_write_u8(bs, ptr->mha_pl_indication);
11313 2 : gf_bs_write_u8(bs, ptr->reference_channel_layout);
11314 2 : gf_bs_write_u16(bs, ptr->mha_config ? ptr->mha_config_size : 0);
11315 2 : if (ptr->mha_config && ptr->mha_config_size)
11316 1 : gf_bs_write_data(bs, ptr->mha_config, ptr->mha_config_size);
11317 :
11318 : return GF_OK;
11319 : }
11320 :
11321 4 : GF_Err mhac_box_size(GF_Box *s)
11322 : {
11323 : GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;
11324 4 : s->size += 5;
11325 4 : if (ptr->mha_config_size && ptr->mha_config) s->size += ptr->mha_config_size;
11326 4 : return GF_OK;
11327 : }
11328 :
11329 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11330 :
11331 3 : void mhap_box_del(GF_Box *s)
11332 : {
11333 : GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;
11334 3 : if (ptr->compat_profiles) gf_free(ptr->compat_profiles);
11335 3 : gf_free(s);
11336 3 : }
11337 :
11338 1 : GF_Err mhap_box_read(GF_Box *s,GF_BitStream *bs)
11339 : {
11340 : u32 i;
11341 : GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;
11342 :
11343 1 : ISOM_DECREASE_SIZE(s, 1)
11344 1 : ptr->num_profiles = gf_bs_read_u8(bs);
11345 1 : if (!ptr->num_profiles) return GF_OK;
11346 :
11347 0 : ISOM_DECREASE_SIZE(s, ptr->num_profiles)
11348 0 : ptr->compat_profiles = gf_malloc(sizeof(u8) * ptr->num_profiles);
11349 0 : if (!ptr->compat_profiles) return GF_OUT_OF_MEM;
11350 0 : for (i=0; i<ptr->num_profiles; i++) {
11351 0 : ptr->compat_profiles[i] = gf_bs_read_u8(bs);
11352 : }
11353 : return GF_OK;
11354 : }
11355 :
11356 3 : GF_Box *mhap_box_new()
11357 : {
11358 6 : ISOM_DECL_BOX_ALLOC(GF_MHACompatibleProfilesBox, GF_ISOM_BOX_TYPE_MHAP);
11359 3 : return (GF_Box *)tmp;
11360 : }
11361 :
11362 : #ifndef GPAC_DISABLE_ISOM_WRITE
11363 :
11364 1 : GF_Err mhap_box_write(GF_Box *s, GF_BitStream *bs)
11365 : {
11366 : u32 i;
11367 : GF_Err e;
11368 : GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;
11369 :
11370 1 : e = gf_isom_box_write_header(s, bs);
11371 1 : if (e) return e;
11372 1 : gf_bs_write_u8(bs, ptr->num_profiles);
11373 1 : for (i=0; i<ptr->num_profiles; i++) {
11374 0 : gf_bs_write_u8(bs, ptr->compat_profiles[i]);
11375 : }
11376 : return GF_OK;
11377 : }
11378 :
11379 1 : GF_Err mhap_box_size(GF_Box *s)
11380 : {
11381 : GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;
11382 1 : s->size += 1 + ptr->num_profiles;
11383 1 : return GF_OK;
11384 : }
11385 :
11386 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11387 :
11388 :
11389 32 : void jp2h_box_del(GF_Box *s)
11390 : {
11391 32 : gf_free(s);
11392 32 : }
11393 :
11394 54 : GF_Err jp2h_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
11395 : {
11396 : GF_J2KHeaderBox *ptr = (GF_J2KHeaderBox *)s;
11397 54 : switch(a->type) {
11398 27 : case GF_ISOM_BOX_TYPE_IHDR:
11399 27 : BOX_FIELD_ASSIGN(ihdr, GF_J2KImageHeaderBox)
11400 27 : return GF_OK;
11401 27 : case GF_ISOM_BOX_TYPE_COLR:
11402 27 : BOX_FIELD_ASSIGN(colr, GF_ColourInformationBox)
11403 27 : return GF_OK;
11404 : }
11405 : return GF_OK;
11406 : }
11407 28 : GF_Err jp2h_box_read(GF_Box *s,GF_BitStream *bs)
11408 : {
11409 28 : return gf_isom_box_array_read_ex(s, bs, s->type);
11410 : }
11411 :
11412 32 : GF_Box *jp2h_box_new()
11413 : {
11414 64 : ISOM_DECL_BOX_ALLOC(GF_J2KHeaderBox, GF_ISOM_BOX_TYPE_JP2H);
11415 32 : return (GF_Box *)tmp;
11416 : }
11417 :
11418 : #ifndef GPAC_DISABLE_ISOM_WRITE
11419 :
11420 17 : GF_Err jp2h_box_write(GF_Box *s, GF_BitStream *bs)
11421 : {
11422 17 : return gf_isom_box_write_header(s, bs);
11423 : }
11424 :
11425 31 : GF_Err jp2h_box_size(GF_Box *s)
11426 : {
11427 31 : return GF_OK;
11428 : }
11429 :
11430 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11431 :
11432 :
11433 30 : void ihdr_box_del(GF_Box *s)
11434 : {
11435 30 : gf_free(s);
11436 30 : }
11437 :
11438 28 : GF_Err ihdr_box_read(GF_Box *s,GF_BitStream *bs)
11439 : {
11440 : GF_J2KImageHeaderBox *ptr = (GF_J2KImageHeaderBox *) s;
11441 :
11442 28 : ISOM_DECREASE_SIZE(s, 14)
11443 :
11444 28 : ptr->height = gf_bs_read_u32(bs);
11445 28 : ptr->width = gf_bs_read_u32(bs);
11446 28 : ptr->nb_comp = gf_bs_read_u16(bs);
11447 28 : ptr->bpc = gf_bs_read_u8(bs);
11448 28 : ptr->Comp = gf_bs_read_u8(bs);
11449 28 : ptr->UnkC = gf_bs_read_u8(bs);
11450 28 : ptr->IPR = gf_bs_read_u8(bs);
11451 :
11452 28 : return GF_OK;
11453 : }
11454 :
11455 30 : GF_Box *ihdr_box_new()
11456 : {
11457 60 : ISOM_DECL_BOX_ALLOC(GF_J2KImageHeaderBox, GF_ISOM_BOX_TYPE_IHDR);
11458 30 : return (GF_Box *)tmp;
11459 : }
11460 :
11461 : #ifndef GPAC_DISABLE_ISOM_WRITE
11462 :
11463 24 : GF_Err ihdr_box_write(GF_Box *s, GF_BitStream *bs)
11464 : {
11465 : GF_Err e;
11466 : GF_J2KImageHeaderBox *ptr = (GF_J2KImageHeaderBox *) s;
11467 :
11468 24 : e = gf_isom_box_write_header(s, bs);
11469 24 : if (e) return e;
11470 :
11471 24 : gf_bs_write_u32(bs, ptr->height);
11472 24 : gf_bs_write_u32(bs, ptr->width);
11473 24 : gf_bs_write_u16(bs, ptr->nb_comp);
11474 24 : gf_bs_write_u8(bs, ptr->bpc);
11475 24 : gf_bs_write_u8(bs, ptr->Comp);
11476 24 : gf_bs_write_u8(bs, ptr->UnkC);
11477 24 : gf_bs_write_u8(bs, ptr->IPR);
11478 24 : return GF_OK;
11479 : }
11480 :
11481 31 : GF_Err ihdr_box_size(GF_Box *s)
11482 : {
11483 31 : s->size += 14;
11484 31 : return GF_OK;
11485 : }
11486 :
11487 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11488 :
11489 :
11490 : /* Dolby Vision */
11491 :
11492 7 : GF_Box *dvcC_box_new()
11493 : {
11494 7 : GF_DOVIConfigurationBox *tmp = (GF_DOVIConfigurationBox *)gf_malloc(sizeof(GF_DOVIConfigurationBox));
11495 7 : if (tmp == NULL) return NULL;
11496 : memset(tmp, 0, sizeof(GF_DOVIConfigurationBox));
11497 7 : tmp->type = GF_ISOM_BOX_TYPE_DVCC;
11498 7 : return (GF_Box *)tmp;
11499 : }
11500 :
11501 7 : void dvcC_box_del(GF_Box *s)
11502 : {
11503 : GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox*)s;
11504 7 : gf_free(ptr);
11505 7 : }
11506 :
11507 4 : GF_Err dvcC_box_read(GF_Box *s, GF_BitStream *bs)
11508 : {
11509 : u32 i;
11510 : u32 data[5];
11511 : GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *)s;
11512 :
11513 : //GF_DOVIDecoderConfigurationRecord
11514 4 : ISOM_DECREASE_SIZE(ptr, 24)
11515 4 : ptr->DOVIConfig.dv_version_major = gf_bs_read_u8(bs);
11516 4 : ptr->DOVIConfig.dv_version_minor = gf_bs_read_u8(bs);
11517 4 : ptr->DOVIConfig.dv_profile = gf_bs_read_int(bs, 7);
11518 4 : ptr->DOVIConfig.dv_level = gf_bs_read_int(bs, 6);
11519 4 : ptr->DOVIConfig.rpu_present_flag = gf_bs_read_int(bs, 1);
11520 4 : ptr->DOVIConfig.el_present_flag = gf_bs_read_int(bs, 1);
11521 4 : ptr->DOVIConfig.bl_present_flag = gf_bs_read_int(bs, 1);
11522 :
11523 : memset(data, 0, sizeof(u32)*5);
11524 4 : gf_bs_read_data(bs, (char*)data, 20);
11525 24 : for (i = 0; i < 5; ++i) {
11526 20 : if (data[i] != 0) {
11527 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] dvcC reserved bytes are not zero\n"));
11528 : //return GF_ISOM_INVALID_FILE;
11529 : }
11530 : }
11531 : return GF_OK;
11532 : }
11533 :
11534 : #ifndef GPAC_DISABLE_ISOM_WRITE
11535 4 : GF_Err dvcC_box_write(GF_Box *s, GF_BitStream *bs)
11536 : {
11537 : GF_Err e;
11538 : GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *) s;
11539 4 : if (!s) return GF_BAD_PARAM;
11540 :
11541 4 : e = gf_isom_box_write_header(s, bs);
11542 4 : if (e) return e;
11543 :
11544 : //GF_DOVIDecoderConfigurationRecord
11545 4 : gf_bs_write_u8(bs, ptr->DOVIConfig.dv_version_major);
11546 4 : gf_bs_write_u8(bs, ptr->DOVIConfig.dv_version_minor);
11547 4 : gf_bs_write_int(bs, ptr->DOVIConfig.dv_profile, 7);
11548 4 : gf_bs_write_int(bs, ptr->DOVIConfig.dv_level, 6);
11549 4 : gf_bs_write_int(bs, ptr->DOVIConfig.rpu_present_flag, 1);
11550 4 : gf_bs_write_int(bs, ptr->DOVIConfig.el_present_flag, 1);
11551 4 : gf_bs_write_int(bs, ptr->DOVIConfig.bl_present_flag, 1);
11552 4 : gf_bs_write_u32(bs, 0);
11553 4 : gf_bs_write_u32(bs, 0);
11554 4 : gf_bs_write_u32(bs, 0);
11555 4 : gf_bs_write_u32(bs, 0);
11556 4 : gf_bs_write_u32(bs, 0);
11557 :
11558 4 : return GF_OK;
11559 : }
11560 :
11561 6 : GF_Err dvcC_box_size(GF_Box *s)
11562 : {
11563 : GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *)s;
11564 :
11565 6 : ptr->size += 24;
11566 6 : return GF_OK;
11567 : }
11568 :
11569 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11570 :
11571 :
11572 16 : GF_Box *dOps_box_new()
11573 : {
11574 32 : ISOM_DECL_BOX_ALLOC(GF_OpusSpecificBox, GF_ISOM_BOX_TYPE_DOPS);
11575 16 : return (GF_Box *)tmp;
11576 : }
11577 :
11578 16 : void dOps_box_del(GF_Box *s)
11579 : {
11580 : GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
11581 16 : if (ptr) gf_free(ptr);
11582 16 : }
11583 :
11584 9 : GF_Err dOps_box_read(GF_Box *s, GF_BitStream *bs)
11585 : {
11586 : GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
11587 9 : ptr->version = gf_bs_read_u8(bs);
11588 9 : ptr->OutputChannelCount = gf_bs_read_u8(bs);
11589 9 : ptr->PreSkip = gf_bs_read_u16(bs);
11590 9 : ptr->InputSampleRate = gf_bs_read_u32(bs);
11591 9 : ptr->OutputGain = gf_bs_read_u16(bs);
11592 9 : ptr->ChannelMappingFamily = gf_bs_read_u8(bs);
11593 9 : ISOM_DECREASE_SIZE(ptr, 11)
11594 9 : if (ptr->size) {
11595 8 : ISOM_DECREASE_SIZE(ptr, 2+ptr->OutputChannelCount);
11596 8 : ptr->StreamCount = gf_bs_read_u8(bs);
11597 8 : ptr->CoupledCount = gf_bs_read_u8(bs);
11598 8 : gf_bs_read_data(bs, (char *) ptr->ChannelMapping, ptr->OutputChannelCount);
11599 : }
11600 : return GF_OK;
11601 : }
11602 :
11603 : #ifndef GPAC_DISABLE_ISOM_WRITE
11604 :
11605 10 : GF_Err dOps_box_write(GF_Box *s, GF_BitStream *bs)
11606 : {
11607 : GF_Err e;
11608 : GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
11609 10 : if (!s) return GF_BAD_PARAM;
11610 10 : e = gf_isom_box_write_header(s, bs);
11611 10 : if (e) return e;
11612 10 : gf_bs_write_u8(bs, ptr->version);
11613 10 : gf_bs_write_u8(bs, ptr->OutputChannelCount);
11614 10 : gf_bs_write_u16(bs, ptr->PreSkip);
11615 10 : gf_bs_write_u32(bs, ptr->InputSampleRate);
11616 10 : gf_bs_write_u16(bs, ptr->OutputGain);
11617 10 : gf_bs_write_u8(bs, ptr->ChannelMappingFamily);
11618 10 : if (ptr->ChannelMappingFamily) {
11619 9 : gf_bs_write_u8(bs, ptr->StreamCount);
11620 9 : gf_bs_write_u8(bs, ptr->CoupledCount);
11621 9 : gf_bs_write_data(bs, (char *) ptr->ChannelMapping, ptr->OutputChannelCount);
11622 : }
11623 : return GF_OK;
11624 : }
11625 :
11626 14 : GF_Err dOps_box_size(GF_Box *s)
11627 : {
11628 : GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
11629 14 : ptr->size += 11;
11630 14 : if (ptr->ChannelMappingFamily)
11631 13 : ptr->size += 2 + ptr->OutputChannelCount;
11632 :
11633 14 : return GF_OK;
11634 : }
11635 :
11636 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11637 :
11638 :
11639 10 : void dfla_box_del(GF_Box *s)
11640 : {
11641 : GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
11642 10 : if (ptr->data) gf_free(ptr->data);
11643 10 : gf_free(ptr);
11644 10 : }
11645 :
11646 6 : GF_Err dfla_box_read(GF_Box *s,GF_BitStream *bs)
11647 : {
11648 : GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
11649 6 : ptr->dataSize = (u32) ptr->size;
11650 6 : ptr->size=0;
11651 6 : ptr->data = gf_malloc(ptr->dataSize);
11652 6 : gf_bs_read_data(bs, ptr->data, ptr->dataSize);
11653 6 : return GF_OK;
11654 : }
11655 :
11656 10 : GF_Box *dfla_box_new()
11657 : {
11658 20 : ISOM_DECL_BOX_ALLOC(GF_FLACConfigBox, GF_ISOM_BOX_TYPE_DFLA);
11659 10 : return (GF_Box *)tmp;
11660 : }
11661 :
11662 : #ifndef GPAC_DISABLE_ISOM_WRITE
11663 :
11664 5 : GF_Err dfla_box_write(GF_Box *s, GF_BitStream *bs)
11665 : {
11666 : GF_Err e;
11667 : GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
11668 5 : e = gf_isom_full_box_write(s, bs);
11669 5 : if (e) return e;
11670 5 : gf_bs_write_data(bs, ptr->data, ptr->dataSize);
11671 5 : return GF_OK;
11672 : }
11673 :
11674 9 : GF_Err dfla_box_size(GF_Box *s)
11675 : {
11676 : GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
11677 9 : ptr->size += ptr->dataSize;
11678 9 : return GF_OK;
11679 : }
11680 :
11681 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11682 :
11683 :
11684 :
11685 3 : void mvcg_box_del(GF_Box *s)
11686 : {
11687 : GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;
11688 3 : if (ptr->entries) gf_free(ptr->entries);
11689 3 : gf_free(ptr);
11690 3 : }
11691 :
11692 1 : GF_Err mvcg_box_read(GF_Box *s,GF_BitStream *bs)
11693 : {
11694 : u32 i;
11695 : GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;
11696 1 : ISOM_DECREASE_SIZE(s, 7)
11697 1 : ptr->multiview_group_id = gf_bs_read_u32(bs);
11698 1 : ptr->num_entries = gf_bs_read_u16(bs);
11699 1 : gf_bs_read_u8(bs);
11700 1 : ptr->entries = gf_malloc(ptr->num_entries * sizeof(MVCIEntry));
11701 1 : memset(ptr->entries, 0, ptr->num_entries * sizeof(MVCIEntry));
11702 1 : for (i=0; i<ptr->num_entries; i++) {
11703 0 : ISOM_DECREASE_SIZE(s, 1)
11704 0 : ptr->entries[i].entry_type = gf_bs_read_u8(bs);
11705 0 : switch (ptr->entries[i].entry_type) {
11706 0 : case 0:
11707 0 : ISOM_DECREASE_SIZE(s, 4)
11708 0 : ptr->entries[i].trackID = gf_bs_read_u32(bs);
11709 0 : break;
11710 0 : case 1:
11711 0 : ISOM_DECREASE_SIZE(s, 6)
11712 0 : ptr->entries[i].trackID = gf_bs_read_u32(bs);
11713 0 : ptr->entries[i].tierID = gf_bs_read_u16(bs);
11714 0 : break;
11715 0 : case 2:
11716 0 : ISOM_DECREASE_SIZE(s, 2)
11717 0 : gf_bs_read_int(bs, 6);
11718 0 : ptr->entries[i].output_view_id = gf_bs_read_int(bs, 10);
11719 0 : break;
11720 0 : case 3:
11721 0 : ISOM_DECREASE_SIZE(s, 4)
11722 0 : gf_bs_read_int(bs, 6) ;
11723 0 : ptr->entries[i].start_view_id = gf_bs_read_int(bs, 10);
11724 0 : ptr->entries[i].view_count = gf_bs_read_u16(bs);
11725 0 : break;
11726 : }
11727 : }
11728 1 : return gf_isom_box_array_read(s, bs);
11729 : }
11730 :
11731 3 : GF_Box *mvcg_box_new()
11732 : {
11733 6 : ISOM_DECL_BOX_ALLOC(GF_MultiviewGroupBox, GF_ISOM_BOX_TYPE_MVCG);
11734 3 : return (GF_Box *)tmp;
11735 : }
11736 :
11737 : #ifndef GPAC_DISABLE_ISOM_WRITE
11738 :
11739 1 : GF_Err mvcg_box_write(GF_Box *s, GF_BitStream *bs)
11740 : {
11741 : GF_Err e;
11742 : u32 i;
11743 : GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;
11744 1 : e = gf_isom_full_box_write(s, bs);
11745 1 : if (e) return e;
11746 :
11747 :
11748 1 : gf_bs_write_u32(bs, ptr->multiview_group_id);
11749 1 : gf_bs_write_u16(bs, ptr->num_entries);
11750 1 : gf_bs_write_u8(bs, 0);
11751 :
11752 1 : for (i=0; i<ptr->num_entries; i++) {
11753 0 : gf_bs_write_u8(bs, ptr->entries[i].entry_type);
11754 0 : switch (ptr->entries[i].entry_type) {
11755 0 : case 0:
11756 0 : gf_bs_write_u32(bs, ptr->entries[i].trackID);
11757 0 : break;
11758 0 : case 1:
11759 0 : gf_bs_write_u32(bs, ptr->entries[i].trackID);
11760 0 : gf_bs_write_u16(bs, ptr->entries[i].tierID);
11761 0 : break;
11762 0 : case 2:
11763 0 : gf_bs_write_int(bs, 0, 6);
11764 0 : gf_bs_write_int(bs, ptr->entries[i].output_view_id, 10);
11765 0 : break;
11766 0 : case 3:
11767 0 : gf_bs_write_int(bs, 0, 6) ;
11768 0 : gf_bs_write_int(bs, ptr->entries[i].start_view_id, 10);
11769 0 : gf_bs_write_u16(bs, ptr->entries[i].view_count);
11770 0 : break;
11771 : }
11772 : }
11773 : return GF_OK;
11774 : }
11775 :
11776 1 : GF_Err mvcg_box_size(GF_Box *s)
11777 : {
11778 : u32 i;
11779 : GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;
11780 :
11781 1 : ptr->size += 7;
11782 1 : for (i=0; i<ptr->num_entries; i++) {
11783 0 : switch (ptr->entries[i].entry_type) {
11784 0 : case 0:
11785 0 : ptr->size += 1 + 4;
11786 0 : break;
11787 0 : case 1:
11788 0 : ptr->size += 1 + 6;
11789 0 : break;
11790 0 : case 2:
11791 0 : ptr->size += 1 + 2;
11792 0 : break;
11793 0 : case 3:
11794 0 : ptr->size += 1 + 4;
11795 0 : break;
11796 : }
11797 : }
11798 1 : return GF_OK;
11799 : }
11800 :
11801 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11802 :
11803 :
11804 3 : void vwid_box_del(GF_Box *s)
11805 : {
11806 : u32 i;
11807 : GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
11808 3 : if (ptr->views) {
11809 0 : for (i=0; i<ptr->num_views; i++) {
11810 0 : if (ptr->views[i].view_refs)
11811 0 : gf_free(ptr->views[i].view_refs);
11812 : }
11813 1 : gf_free(ptr->views);
11814 : }
11815 3 : gf_free(ptr);
11816 3 : }
11817 :
11818 1 : GF_Err vwid_box_read(GF_Box *s,GF_BitStream *bs)
11819 : {
11820 : u32 i;
11821 : GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
11822 1 : ISOM_DECREASE_SIZE(s, 3)
11823 1 : gf_bs_read_int(bs, 2);
11824 1 : ptr->min_temporal_id = gf_bs_read_int(bs, 3);
11825 1 : ptr->max_temporal_id = gf_bs_read_int(bs, 3);
11826 1 : ptr->num_views = gf_bs_read_u16(bs);
11827 1 : if (ptr->num_views > ptr->size / 6)
11828 : return GF_ISOM_INVALID_FILE;
11829 :
11830 1 : ptr->views = gf_malloc(sizeof(ViewIDEntry)*ptr->num_views);
11831 1 : memset(ptr->views, 0, sizeof(ViewIDEntry)*ptr->num_views);
11832 1 : for (i=0; i<ptr->num_views; i++) {
11833 : u32 j;
11834 0 : ISOM_DECREASE_SIZE(s, 6)
11835 :
11836 0 : gf_bs_read_int(bs, 6);
11837 0 : ptr->views[i].view_id = gf_bs_read_int(bs, 10);
11838 0 : gf_bs_read_int(bs, 6);
11839 0 : ptr->views[i].view_order_index = gf_bs_read_int(bs, 10);
11840 0 : ptr->views[i].texture_in_stream = gf_bs_read_int(bs, 1);
11841 0 : ptr->views[i].texture_in_track = gf_bs_read_int(bs, 1);
11842 0 : ptr->views[i].depth_in_stream = gf_bs_read_int(bs, 1);
11843 0 : ptr->views[i].depth_in_track = gf_bs_read_int(bs, 1);
11844 0 : ptr->views[i].base_view_type = gf_bs_read_int(bs, 2);
11845 0 : ptr->views[i].num_ref_views = gf_bs_read_int(bs, 10);
11846 :
11847 0 : if (ptr->views[i].num_ref_views > ptr->size / 2)
11848 : return GF_ISOM_INVALID_FILE;
11849 :
11850 0 : ptr->views[i].view_refs = gf_malloc(sizeof(ViewIDRefViewEntry)*ptr->views[i].num_ref_views);
11851 0 : for (j=0; j<ptr->views[i].num_ref_views; j++) {
11852 0 : ISOM_DECREASE_SIZE(s, 2)
11853 0 : gf_bs_read_int(bs, 4);
11854 0 : ptr->views[i].view_refs[j].dep_comp_idc = gf_bs_read_int(bs, 2);
11855 0 : ptr->views[i].view_refs[j].ref_view_id = gf_bs_read_int(bs, 10);
11856 : }
11857 : }
11858 : return GF_OK;
11859 : }
11860 :
11861 3 : GF_Box *vwid_box_new()
11862 : {
11863 6 : ISOM_DECL_BOX_ALLOC(GF_ViewIdentifierBox, GF_ISOM_BOX_TYPE_VWID);
11864 3 : return (GF_Box *)tmp;
11865 : }
11866 :
11867 : #ifndef GPAC_DISABLE_ISOM_WRITE
11868 :
11869 1 : GF_Err vwid_box_write(GF_Box *s, GF_BitStream *bs)
11870 : {
11871 : GF_Err e;
11872 : u32 i, j;
11873 : GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
11874 1 : e = gf_isom_full_box_write(s, bs);
11875 1 : if (e) return e;
11876 :
11877 1 : gf_bs_write_int(bs, 0, 2);
11878 1 : gf_bs_write_int(bs, ptr->min_temporal_id, 3);
11879 1 : gf_bs_write_int(bs, ptr->max_temporal_id, 3);
11880 1 : gf_bs_write_u16(bs, ptr->num_views);
11881 :
11882 1 : for (i=0; i<ptr->num_views; i++) {
11883 0 : gf_bs_write_int(bs, 0, 6);
11884 0 : gf_bs_write_int(bs, ptr->views[i].view_id, 10);
11885 0 : gf_bs_write_int(bs, 0, 6);
11886 0 : gf_bs_write_int(bs, ptr->views[i].view_order_index, 10);
11887 :
11888 0 : gf_bs_write_int(bs, ptr->views[i].texture_in_stream, 1);
11889 0 : gf_bs_write_int(bs, ptr->views[i].texture_in_track, 1);
11890 0 : gf_bs_write_int(bs, ptr->views[i].depth_in_stream, 1);
11891 0 : gf_bs_write_int(bs, ptr->views[i].depth_in_track, 1);
11892 0 : gf_bs_write_int(bs, ptr->views[i].base_view_type, 2);
11893 0 : gf_bs_write_int(bs, ptr->views[i].num_ref_views, 10);
11894 :
11895 0 : for (j=0; j<ptr->views[i].num_ref_views; j++) {
11896 0 : gf_bs_write_int(bs, 0, 4);
11897 0 : gf_bs_write_int(bs, ptr->views[i].view_refs[j].dep_comp_idc, 2);
11898 0 : gf_bs_write_int(bs, ptr->views[i].view_refs[j].ref_view_id, 10);
11899 : }
11900 : }
11901 : return GF_OK;
11902 : }
11903 :
11904 1 : GF_Err vwid_box_size(GF_Box *s)
11905 : {
11906 : u32 i;
11907 : GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
11908 1 : ptr->size += 3;
11909 1 : for (i=0; i<ptr->num_views; i++) {
11910 0 : ptr->size += 6 + 2 * ptr->views[i].num_ref_views;
11911 : }
11912 1 : return GF_OK;
11913 : }
11914 :
11915 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11916 :
11917 :
11918 8 : void pcmC_box_del(GF_Box *s)
11919 : {
11920 8 : gf_free(s);
11921 8 : }
11922 :
11923 6 : GF_Err pcmC_box_read(GF_Box *s,GF_BitStream *bs)
11924 : {
11925 : GF_PCMConfigBox *ptr = (GF_PCMConfigBox *) s;
11926 :
11927 6 : ISOM_DECREASE_SIZE(s, 2)
11928 6 : ptr->format_flags = gf_bs_read_u8(bs);
11929 6 : ptr->PCM_sample_size = gf_bs_read_u8(bs);
11930 6 : return GF_OK;
11931 : }
11932 :
11933 8 : GF_Box *pcmC_box_new()
11934 : {
11935 16 : ISOM_DECL_BOX_ALLOC(GF_PCMConfigBox, GF_ISOM_BOX_TYPE_PCMC);
11936 8 : return (GF_Box *)tmp;
11937 : }
11938 :
11939 : #ifndef GPAC_DISABLE_ISOM_WRITE
11940 :
11941 6 : GF_Err pcmC_box_write(GF_Box *s, GF_BitStream *bs)
11942 : {
11943 : GF_Err e;
11944 : GF_PCMConfigBox *ptr = (GF_PCMConfigBox *) s;
11945 :
11946 6 : e = gf_isom_full_box_write(s, bs);
11947 6 : if (e) return e;
11948 6 : gf_bs_write_u8(bs, ptr->format_flags);
11949 6 : gf_bs_write_u8(bs, ptr->PCM_sample_size);
11950 6 : return GF_OK;
11951 : }
11952 :
11953 6 : GF_Err pcmC_box_size(GF_Box *s)
11954 : {
11955 6 : s->size += 2;
11956 6 : return GF_OK;
11957 : }
11958 :
11959 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
11960 :
11961 :
11962 :
11963 13 : void chnl_box_del(GF_Box *s)
11964 : {
11965 13 : gf_free(s);
11966 13 : }
11967 :
11968 6 : GF_Err chnl_box_read(GF_Box *s,GF_BitStream *bs)
11969 : {
11970 : GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s;
11971 :
11972 6 : ISOM_DECREASE_SIZE(s, 1)
11973 6 : ptr->layout.stream_structure = gf_bs_read_u8(bs);
11974 6 : if (ptr->layout.stream_structure & 1) {
11975 5 : ISOM_DECREASE_SIZE(s, 1)
11976 5 : ptr->layout.definedLayout = gf_bs_read_u8(bs);
11977 5 : if (ptr->layout.definedLayout) {
11978 5 : u32 remain = (u32) ptr->size;
11979 5 : if (ptr->layout.stream_structure & 2) remain--;
11980 5 : ptr->layout.channels_count = 0;
11981 50 : while (remain) {
11982 40 : ISOM_DECREASE_SIZE(s, 1)
11983 40 : ptr->layout.layouts[ptr->layout.channels_count].position = gf_bs_read_u8(bs);
11984 40 : remain--;
11985 40 : if (ptr->layout.layouts[ptr->layout.channels_count].position == 126) {
11986 0 : ISOM_DECREASE_SIZE(s, 3)
11987 0 : ptr->layout.layouts[ptr->layout.channels_count].azimuth = gf_bs_read_int(bs, 16);
11988 0 : ptr->layout.layouts[ptr->layout.channels_count].elevation = gf_bs_read_int(bs, 8);
11989 0 : remain-=3;
11990 : }
11991 : }
11992 : } else {
11993 0 : ISOM_DECREASE_SIZE(s, 8)
11994 0 : ptr->layout.omittedChannelsMap = gf_bs_read_u64(bs);
11995 : }
11996 : }
11997 6 : if (ptr->layout.stream_structure & 2) {
11998 0 : ISOM_DECREASE_SIZE(s, 1)
11999 0 : ptr->layout.object_count = gf_bs_read_u8(bs);
12000 : }
12001 : return GF_OK;
12002 : }
12003 :
12004 13 : GF_Box *chnl_box_new()
12005 : {
12006 26 : ISOM_DECL_BOX_ALLOC(GF_ChannelLayoutBox, GF_ISOM_BOX_TYPE_CHNL);
12007 13 : return (GF_Box *)tmp;
12008 : }
12009 :
12010 : #ifndef GPAC_DISABLE_ISOM_WRITE
12011 :
12012 11 : GF_Err chnl_box_write(GF_Box *s, GF_BitStream *bs)
12013 : {
12014 : GF_Err e;
12015 : GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s;
12016 :
12017 11 : e = gf_isom_full_box_write(s, bs);
12018 11 : if (e) return e;
12019 :
12020 11 : gf_bs_write_u8(bs, ptr->layout.stream_structure);
12021 11 : if (ptr->layout.stream_structure & 1) {
12022 10 : gf_bs_write_u8(bs, ptr->layout.definedLayout);
12023 10 : if (ptr->layout.definedLayout==0) {
12024 : u32 i;
12025 0 : for (i=0; i<ptr->layout.channels_count; i++) {
12026 0 : gf_bs_write_u8(bs, ptr->layout.layouts[i].position);
12027 0 : if (ptr->layout.layouts[i].position==126) {
12028 0 : gf_bs_write_int(bs, ptr->layout.layouts[i].azimuth, 16);
12029 0 : gf_bs_write_int(bs, ptr->layout.layouts[i].elevation, 8);
12030 : }
12031 : }
12032 : } else {
12033 10 : gf_bs_write_u64(bs, ptr->layout.omittedChannelsMap);
12034 : }
12035 : }
12036 11 : if (ptr->layout.stream_structure & 2) {
12037 0 : gf_bs_write_u8(bs, ptr->layout.object_count);
12038 : }
12039 : return GF_OK;
12040 : }
12041 :
12042 21 : GF_Err chnl_box_size(GF_Box *s)
12043 : {
12044 : GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s;
12045 21 : s->size += 1;
12046 21 : if (ptr->layout.stream_structure & 1) {
12047 20 : s->size += 1;
12048 20 : if (ptr->layout.definedLayout==0) {
12049 : u32 i;
12050 0 : for (i=0; i<ptr->layout.channels_count; i++) {
12051 0 : s->size+=1;
12052 0 : if (ptr->layout.layouts[i].position==126)
12053 0 : s->size+=3;
12054 : }
12055 : } else {
12056 20 : s->size += 8;
12057 : }
12058 : }
12059 21 : if (ptr->layout.stream_structure & 2) {
12060 0 : s->size += 1;
12061 : }
12062 21 : return GF_OK;
12063 : }
12064 :
12065 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
12066 :
12067 :
12068 4 : GF_Box *emsg_box_new()
12069 : {
12070 8 : ISOM_DECL_BOX_ALLOC(GF_EventMessageBox, GF_ISOM_BOX_TYPE_EMSG);
12071 4 : return (GF_Box *)tmp;
12072 : }
12073 :
12074 4 : void emsg_box_del(GF_Box *s)
12075 : {
12076 : GF_EventMessageBox *ptr = (GF_EventMessageBox *) s;
12077 4 : if (ptr == NULL) return;
12078 4 : if (ptr->scheme_id_uri) gf_free(ptr->scheme_id_uri);
12079 4 : if (ptr->value) gf_free(ptr->value);
12080 4 : if (ptr->message_data) gf_free(ptr->message_data);
12081 4 : gf_free(ptr);
12082 : }
12083 :
12084 0 : GF_Err emsg_box_read(GF_Box *s,GF_BitStream *bs)
12085 : {
12086 : GF_Err e;
12087 : GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;
12088 :
12089 0 : if (ptr->version==0) {
12090 0 : e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_id_uri);
12091 0 : if (e) return e;
12092 0 : e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->value);
12093 0 : if (e) return e;
12094 :
12095 0 : ISOM_DECREASE_SIZE(ptr, 16);
12096 0 : ptr->timescale = gf_bs_read_u32(bs);
12097 0 : ptr->presentation_time_delta = gf_bs_read_u32(bs);
12098 0 : ptr->event_duration = gf_bs_read_u32(bs);
12099 0 : ptr->event_id = gf_bs_read_u32(bs);
12100 0 : } else if (ptr->version==1) {
12101 0 : ISOM_DECREASE_SIZE(ptr, 20);
12102 0 : ptr->timescale = gf_bs_read_u32(bs);
12103 0 : ptr->presentation_time_delta = gf_bs_read_u64(bs);
12104 0 : ptr->event_duration = gf_bs_read_u32(bs);
12105 0 : ptr->event_id = gf_bs_read_u32(bs);
12106 :
12107 0 : e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_id_uri);
12108 0 : if (e) return e;
12109 0 : e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->value);
12110 0 : if (e) return e;
12111 : } else {
12112 : return GF_OK;
12113 : }
12114 0 : if (ptr->size) {
12115 0 : if (ptr->size>0xFFFFFFFUL) {
12116 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[IsoMedia] emsg message data size too big ("LLU") to be loaded\n", ptr->size));
12117 : return GF_OUT_OF_MEM;
12118 : }
12119 0 : ptr->message_data_size = (u32) ptr->size;
12120 0 : ptr->message_data = gf_malloc(ptr->message_data_size);
12121 0 : if (!ptr->message_data) return GF_OUT_OF_MEM;
12122 0 : gf_bs_read_data(bs, ptr->message_data, ptr->message_data_size);
12123 0 : ptr->size = 0;
12124 : }
12125 : return GF_OK;
12126 : }
12127 :
12128 : #ifndef GPAC_DISABLE_ISOM_WRITE
12129 :
12130 1 : GF_Err emsg_box_write(GF_Box *s, GF_BitStream *bs)
12131 : {
12132 : GF_Err e;
12133 : u32 len;
12134 : GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;
12135 :
12136 1 : e = gf_isom_full_box_write(s, bs);
12137 1 : if (e) return e;
12138 :
12139 1 : if (ptr->version==1) {
12140 0 : gf_bs_write_u32(bs, ptr->timescale);
12141 0 : gf_bs_write_u64(bs, ptr->presentation_time_delta);
12142 0 : gf_bs_write_u32(bs, ptr->event_duration);
12143 0 : gf_bs_write_u32(bs, ptr->event_id);
12144 : }
12145 :
12146 1 : len = ptr->scheme_id_uri ? (u32) strlen(ptr->scheme_id_uri) : 0;
12147 0 : if (len) gf_bs_write_data(bs, ptr->scheme_id_uri, len);
12148 1 : gf_bs_write_u8(bs, 0);
12149 :
12150 1 : len = ptr->value ? (u32) strlen(ptr->value) : 0;
12151 0 : if (len) gf_bs_write_data(bs, ptr->value, len);
12152 1 : gf_bs_write_u8(bs, 0);
12153 :
12154 1 : if (ptr->version==0) {
12155 1 : gf_bs_write_u32(bs, ptr->timescale);
12156 1 : gf_bs_write_u32(bs, (u32) ptr->presentation_time_delta);
12157 1 : gf_bs_write_u32(bs, ptr->event_duration);
12158 1 : gf_bs_write_u32(bs, ptr->event_id);
12159 : }
12160 1 : if (ptr->message_data)
12161 0 : gf_bs_write_data(bs, ptr->message_data, ptr->message_data_size);
12162 : return GF_OK;
12163 : }
12164 :
12165 1 : GF_Err emsg_box_size(GF_Box *s)
12166 : {
12167 : GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;
12168 :
12169 1 : ptr->size += 4;
12170 1 : if (ptr->version) {
12171 0 : ptr->size += 20;
12172 : } else {
12173 1 : ptr->size += 16;
12174 : }
12175 1 : ptr->size+=2; //1 NULL-terminated strings
12176 1 : if (ptr->scheme_id_uri) ptr->size += strlen(ptr->scheme_id_uri);
12177 1 : if (ptr->value) ptr->size += strlen(ptr->value);
12178 1 : if (ptr->message_data)
12179 0 : ptr->size += ptr->message_data_size;
12180 :
12181 1 : return GF_OK;
12182 : }
12183 : #endif // GPAC_DISABLE_ISOM_WRITE
12184 :
12185 :
12186 :
12187 :
12188 3 : GF_Box *csgp_box_new()
12189 : {
12190 6 : ISOM_DECL_BOX_ALLOC(GF_CompactSampleGroupBox, GF_ISOM_BOX_TYPE_CSGP);
12191 3 : return (GF_Box *)tmp;
12192 : }
12193 3 : void csgp_box_del(GF_Box *a)
12194 : {
12195 : GF_CompactSampleGroupBox *p = (GF_CompactSampleGroupBox *)a;
12196 3 : if (p->patterns) {
12197 : u32 i;
12198 0 : for (i=0; i<p->pattern_count; i++) {
12199 0 : gf_free(p->patterns[i].sample_group_description_indices);
12200 : }
12201 1 : gf_free(p->patterns);
12202 : }
12203 3 : gf_free(p);
12204 3 : }
12205 :
12206 0 : u32 get_size_by_code(u32 code)
12207 : {
12208 9 : if (code==0) return 4;
12209 0 : if (code==1) return 8;
12210 0 : if (code==2) return 16;
12211 0 : return 32;
12212 : }
12213 1 : GF_Err csgp_box_read(GF_Box *s, GF_BitStream *bs)
12214 : {
12215 : u32 i, bits, gidx_mask;
12216 : Bool index_msb_indicates_fragment_local_description, grouping_type_parameter_present;
12217 : u32 pattern_size, scount_size, index_size;
12218 : GF_CompactSampleGroupBox *ptr = (GF_CompactSampleGroupBox *)s;
12219 :
12220 1 : ISOM_DECREASE_SIZE(ptr, 8);
12221 1 : ptr->version = gf_bs_read_u8(bs);
12222 1 : ptr->flags = gf_bs_read_u24(bs);
12223 :
12224 1 : index_msb_indicates_fragment_local_description = (ptr->flags & (1<<7)) ? GF_TRUE : GF_FALSE;
12225 1 : grouping_type_parameter_present = (ptr->flags & (1<<6)) ? GF_TRUE : GF_FALSE;
12226 :
12227 1 : pattern_size = get_size_by_code( ((ptr->flags>>4) & 0x3) );
12228 1 : scount_size = get_size_by_code( ((ptr->flags>>2) & 0x3) );
12229 1 : index_size = get_size_by_code( (ptr->flags & 0x3) );
12230 :
12231 1 : if (((pattern_size==4) && (scount_size!=4)) || ((pattern_size!=4) && (scount_size==4))) {
12232 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] compact sample gorup pattern_size and sample_count_size mare not both 4 bits\n"));
12233 : return GF_ISOM_INVALID_FILE;
12234 : }
12235 :
12236 1 : ptr->grouping_type = gf_bs_read_u32(bs);
12237 1 : if (grouping_type_parameter_present) {
12238 0 : ISOM_DECREASE_SIZE(ptr, 4);
12239 0 : ptr->grouping_type_parameter = gf_bs_read_u32(bs);
12240 : }
12241 1 : ISOM_DECREASE_SIZE(ptr, 4);
12242 1 : ptr->pattern_count = gf_bs_read_u32(bs);
12243 :
12244 :
12245 1 : if (ptr->size / ( (pattern_size + scount_size) / 8 ) < ptr->pattern_count )
12246 : return GF_ISOM_INVALID_FILE;
12247 :
12248 1 : ptr->patterns = gf_malloc(sizeof(GF_CompactSampleGroupPattern) * ptr->pattern_count);
12249 1 : if (!ptr->patterns) return GF_OUT_OF_MEM;
12250 :
12251 : bits = 0;
12252 0 : for (i=0; i<ptr->pattern_count; i++) {
12253 0 : ptr->patterns[i].length = gf_bs_read_int(bs, pattern_size);
12254 0 : ptr->patterns[i].sample_count = gf_bs_read_int(bs, scount_size);
12255 0 : bits += pattern_size + scount_size;
12256 0 : if (! (bits % 8)) {
12257 0 : bits/=8;
12258 0 : ISOM_DECREASE_SIZE(ptr, bits);
12259 : bits=0;
12260 : }
12261 0 : ptr->patterns[i].sample_group_description_indices = gf_malloc(sizeof(u32) * ptr->patterns[i].length);
12262 0 : if (!ptr->patterns[i].sample_group_description_indices) return GF_OUT_OF_MEM;
12263 : }
12264 : bits = 0;
12265 1 : gidx_mask = ((u32)1) << (index_size-1);
12266 1 : for (i=0; i<ptr->pattern_count; i++) {
12267 : u32 j;
12268 0 : for (j=0; j<ptr->patterns[i].length; j++) {
12269 0 : u32 idx = gf_bs_read_int(bs, index_size);
12270 0 : if (index_msb_indicates_fragment_local_description) {
12271 : //MSB set, this is a index of a group described in the fragment
12272 0 : if (idx & gidx_mask) {
12273 0 : idx += 0x10000;
12274 : }
12275 : }
12276 0 : ptr->patterns[i].sample_group_description_indices[j] = idx;
12277 0 : bits += index_size;
12278 :
12279 0 : if (! (bits % 8)) {
12280 0 : bits/=8;
12281 0 : ISOM_DECREASE_SIZE(ptr, bits);
12282 : bits=0;
12283 : }
12284 : }
12285 : }
12286 1 : if (bits)
12287 0 : gf_bs_align(bs);
12288 : return GF_OK;
12289 : }
12290 :
12291 : #ifndef GPAC_DISABLE_ISOM_WRITE
12292 1 : GF_Err csgp_box_write(GF_Box *s, GF_BitStream *bs)
12293 : {
12294 : u32 i;
12295 : GF_Err e;
12296 : GF_CompactSampleGroupBox *ptr = (GF_CompactSampleGroupBox*)s;
12297 1 : u32 pattern_size = get_size_by_code( ((ptr->flags>>4) & 0x3) );
12298 1 : u32 scount_size = get_size_by_code( ((ptr->flags>>2) & 0x3) );
12299 1 : u32 index_size = get_size_by_code( (ptr->flags & 0x3) );
12300 :
12301 1 : e = gf_isom_box_write_header(s, bs);
12302 1 : if (e) return e;
12303 :
12304 1 : gf_bs_write_u8(bs, ptr->version);
12305 1 : gf_bs_write_int(bs, ptr->flags, 24);
12306 1 : gf_bs_write_u32(bs, ptr->grouping_type);
12307 :
12308 1 : if (ptr->flags & (1<<6))
12309 0 : gf_bs_write_u32(bs, ptr->grouping_type_parameter);
12310 :
12311 1 : gf_bs_write_u32(bs, ptr->pattern_count);
12312 :
12313 1 : for (i = 0; i<ptr->pattern_count; i++ ) {
12314 0 : gf_bs_write_int(bs, ptr->patterns[i].length, pattern_size);
12315 0 : gf_bs_write_int(bs, ptr->patterns[i].sample_count, scount_size);
12316 : }
12317 :
12318 0 : for (i = 0; i<ptr->pattern_count; i++ ) {
12319 : u32 j;
12320 0 : for (j=0; j<ptr->patterns[i].length; j++) {
12321 0 : u32 idx = ptr->patterns[i].sample_group_description_indices[j];
12322 0 : if (idx > 0x10000) {
12323 0 : idx -= 0x10000;
12324 0 : gf_bs_write_int(bs, 1, 1);
12325 0 : gf_bs_write_int(bs, idx, index_size-1);
12326 : } else {
12327 0 : gf_bs_write_int(bs, idx, index_size);
12328 : }
12329 : }
12330 : }
12331 1 : gf_bs_align(bs);
12332 1 : return GF_OK;
12333 : }
12334 :
12335 1 : GF_Err csgp_box_size(GF_Box *s)
12336 : {
12337 : u32 i, bits;
12338 : GF_CompactSampleGroupBox *ptr = (GF_CompactSampleGroupBox*)s;
12339 1 : u32 pattern_size = get_size_by_code( ((ptr->flags>>4) & 0x3) );
12340 1 : u32 scount_size = get_size_by_code( ((ptr->flags>>2) & 0x3) );
12341 1 : u32 index_size = get_size_by_code( (ptr->flags & 0x3) );
12342 :
12343 1 : ptr->size += 12; //v, flags , grouping_type, pattern_length
12344 1 : if (ptr->flags & (1<<6))
12345 0 : ptr->size+=4;
12346 :
12347 1 : ptr->size += ptr->pattern_count * (pattern_size + scount_size) / 8;
12348 : bits=0;
12349 1 : for (i=0; i<ptr->pattern_count; i++)
12350 0 : bits += ptr->patterns[i].length * index_size;
12351 1 : ptr->size += bits/8;
12352 1 : if (bits % 8) ptr->size++;
12353 1 : return GF_OK;
12354 : }
12355 :
12356 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
12357 :
12358 9 : GF_Box *dmlp_box_new()
12359 : {
12360 18 : ISOM_DECL_BOX_ALLOC(GF_TrueHDConfigBox, GF_ISOM_BOX_TYPE_DMLP);
12361 9 : return (GF_Box *)tmp;
12362 : }
12363 :
12364 9 : void dmlp_box_del(GF_Box *s)
12365 : {
12366 9 : gf_free(s);
12367 9 : }
12368 :
12369 :
12370 6 : GF_Err dmlp_box_read(GF_Box *s, GF_BitStream *bs)
12371 : {
12372 : GF_TrueHDConfigBox *ptr = (GF_TrueHDConfigBox *)s;
12373 6 : ISOM_DECREASE_SIZE(ptr, 10)
12374 6 : ptr->format_info = gf_bs_read_u32(bs);
12375 6 : ptr->peak_data_rate = gf_bs_read_int(bs, 15);
12376 6 : gf_bs_read_int(bs, 1);
12377 6 : gf_bs_read_u32(bs);
12378 6 : return GF_OK;
12379 : }
12380 :
12381 :
12382 : #ifndef GPAC_DISABLE_ISOM_WRITE
12383 :
12384 3 : GF_Err dmlp_box_write(GF_Box *s, GF_BitStream *bs)
12385 : {
12386 : GF_Err e;
12387 : GF_TrueHDConfigBox *ptr = (GF_TrueHDConfigBox *)s;
12388 :
12389 3 : e = gf_isom_box_write_header(s, bs);
12390 3 : if (e) return e;
12391 3 : gf_bs_write_u32(bs, ptr->format_info);
12392 3 : gf_bs_write_int(bs, ptr->peak_data_rate, 15);
12393 3 : gf_bs_write_int(bs, 0, 1);
12394 3 : gf_bs_write_u32(bs, 0);
12395 3 : return GF_OK;
12396 : }
12397 :
12398 5 : GF_Err dmlp_box_size(GF_Box *s)
12399 : {
12400 5 : s->size += 10;
12401 5 : return GF_OK;
12402 : }
12403 :
12404 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
12405 :
12406 3 : GF_Box *xtra_box_new()
12407 : {
12408 6 : ISOM_DECL_BOX_ALLOC(GF_XtraBox, GF_ISOM_BOX_TYPE_XTRA);
12409 3 : tmp->tags = gf_list_new();
12410 3 : return (GF_Box *)tmp;
12411 : }
12412 :
12413 3 : void xtra_box_del(GF_Box *s)
12414 : {
12415 : GF_XtraBox *ptr = (GF_XtraBox *)s;
12416 6 : while (gf_list_count(ptr->tags)) {
12417 0 : GF_XtraTag *tag = gf_list_pop_back(ptr->tags);
12418 0 : if (tag->name) gf_free(tag->name);
12419 0 : if (tag->prop_value) gf_free(tag->prop_value);
12420 0 : gf_free(tag);
12421 : }
12422 3 : gf_list_del(ptr->tags);
12423 3 : gf_free(s);
12424 3 : }
12425 :
12426 1 : GF_Err xtra_box_read(GF_Box *s, GF_BitStream *bs)
12427 : {
12428 : GF_XtraBox *ptr = (GF_XtraBox *)s;
12429 2 : while (ptr->size) {
12430 : GF_XtraTag *tag;
12431 : u32 prop_type = 0;
12432 :
12433 : char *data=NULL, *data2=NULL;
12434 0 : ISOM_DECREASE_SIZE_NO_ERR(ptr, 18)
12435 0 : s32 tag_size = gf_bs_read_u32(bs);
12436 0 : u32 name_size = gf_bs_read_u32(bs);
12437 0 : tag_size -= 8;
12438 :
12439 0 : ISOM_DECREASE_SIZE_NO_ERR(ptr, name_size)
12440 0 : data = gf_malloc(sizeof(char) * (name_size+1));
12441 0 : gf_bs_read_data(bs, data, name_size);
12442 0 : data[name_size] = 0;
12443 0 : tag_size-=name_size;
12444 :
12445 0 : u32 flags = gf_bs_read_u32(bs);
12446 0 : u32 prop_size = gf_bs_read_u32(bs);
12447 0 : tag_size-=8;
12448 :
12449 0 : if (prop_size>4) {
12450 0 : tag_size-=2;
12451 0 : prop_type = gf_bs_read_u16(bs);
12452 0 : prop_size -= 6;
12453 0 : ISOM_DECREASE_SIZE_NO_ERR(ptr, prop_size)
12454 0 : data2 = gf_malloc(sizeof(char) * (prop_size));
12455 0 : gf_bs_read_data(bs, data2, prop_size);
12456 0 : tag_size-=prop_size;
12457 : }
12458 0 : GF_SAFEALLOC(tag, GF_XtraTag)
12459 0 : tag->flags = flags;
12460 0 : tag->name = data;
12461 0 : tag->prop_size = prop_size;
12462 0 : tag->prop_value = data2;
12463 0 : tag->prop_type = prop_type;
12464 0 : gf_list_add(ptr->tags, tag);
12465 :
12466 0 : if (tag_size) {
12467 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isom] invalid tag size in Xtra !\n"));
12468 : }
12469 : }
12470 : return GF_OK;
12471 : }
12472 :
12473 :
12474 : #ifndef GPAC_DISABLE_ISOM_WRITE
12475 :
12476 1 : GF_Err xtra_box_write(GF_Box *s, GF_BitStream *bs)
12477 : {
12478 : GF_Err e;
12479 : GF_XtraBox *ptr = (GF_XtraBox *)s;
12480 1 : u32 i, count = gf_list_count(ptr->tags);
12481 :
12482 1 : e = gf_isom_box_write_header(s, bs);
12483 1 : if (e) return e;
12484 :
12485 0 : for (i=0; i<count; i++) {
12486 0 : GF_XtraTag *tag = gf_list_get(ptr->tags, i);
12487 : u32 tag_size = 16;
12488 0 : u32 name_len = tag->name ? (u32) strlen(tag->name) : 0;
12489 0 : tag_size += name_len;
12490 0 : if (tag->prop_value) {
12491 0 : tag_size += 2 + tag->prop_size;
12492 : }
12493 0 : gf_bs_write_u32(bs, tag_size);
12494 0 : gf_bs_write_u32(bs, name_len);
12495 0 : gf_bs_write_data(bs, tag->name, name_len);
12496 0 : gf_bs_write_u32(bs, tag->flags);
12497 0 : gf_bs_write_u32(bs, 6 + tag->prop_size);
12498 0 : gf_bs_write_u16(bs, tag->prop_type);
12499 0 : gf_bs_write_data(bs, tag->prop_value, tag->prop_size);
12500 : }
12501 : return GF_OK;
12502 : }
12503 :
12504 1 : GF_Err xtra_box_size(GF_Box *s)
12505 : {
12506 : GF_XtraBox *ptr = (GF_XtraBox *)s;
12507 1 : u32 i, count = gf_list_count(ptr->tags);
12508 1 : for (i=0; i<count; i++) {
12509 0 : GF_XtraTag *tag = gf_list_get(ptr->tags, i);
12510 0 : ptr->size += 18 + (u32) strlen(tag->name) + tag->prop_size;
12511 : }
12512 1 : return GF_OK;
12513 : }
12514 :
12515 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
12516 :
12517 :
12518 :
12519 3 : GF_Box *st3d_box_new()
12520 : {
12521 6 : ISOM_DECL_BOX_ALLOC(GF_Stereo3DBox, GF_ISOM_BOX_TYPE_ST3D);
12522 3 : return (GF_Box *)tmp;
12523 : }
12524 :
12525 3 : void st3d_box_del(GF_Box *s)
12526 : {
12527 3 : gf_free(s);
12528 3 : }
12529 :
12530 :
12531 1 : GF_Err st3d_box_read(GF_Box *s, GF_BitStream *bs)
12532 : {
12533 : GF_Stereo3DBox *ptr = (GF_Stereo3DBox *)s;
12534 1 : ISOM_DECREASE_SIZE(ptr, 1)
12535 1 : ptr->stereo_type = gf_bs_read_u8(bs);
12536 1 : return GF_OK;
12537 : }
12538 :
12539 :
12540 : #ifndef GPAC_DISABLE_ISOM_WRITE
12541 :
12542 1 : GF_Err st3d_box_write(GF_Box *s, GF_BitStream *bs)
12543 : {
12544 : GF_Err e;
12545 : GF_Stereo3DBox *ptr = (GF_Stereo3DBox *)s;
12546 :
12547 1 : e = gf_isom_full_box_write(s, bs);
12548 1 : if (e) return e;
12549 1 : gf_bs_write_u8(bs, ptr->stereo_type);
12550 1 : return GF_OK;
12551 : }
12552 :
12553 1 : GF_Err st3d_box_size(GF_Box *s)
12554 : {
12555 1 : s->size += 1;
12556 1 : return GF_OK;
12557 : }
12558 :
12559 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
12560 :
12561 :
12562 :
12563 3 : GF_Box *svhd_box_new()
12564 : {
12565 6 : ISOM_DECL_BOX_ALLOC(GF_SphericalVideoInfoBox, GF_ISOM_BOX_TYPE_SVHD);
12566 3 : return (GF_Box *)tmp;
12567 : }
12568 :
12569 3 : void svhd_box_del(GF_Box *s)
12570 : {
12571 : GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;
12572 3 : if (ptr->string) gf_free(ptr->string);
12573 3 : gf_free(s);
12574 3 : }
12575 :
12576 :
12577 1 : GF_Err svhd_box_read(GF_Box *s, GF_BitStream *bs)
12578 : {
12579 : GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;
12580 1 : ptr->string = gf_malloc(sizeof(char) * ((u32) ptr->size+1));
12581 1 : if (!ptr->string) return GF_OUT_OF_MEM;
12582 1 : gf_bs_read_data(bs, ptr->string, (u32) ptr->size);
12583 1 : ptr->string[ptr->size] = 0;
12584 1 : return GF_OK;
12585 : }
12586 :
12587 :
12588 : #ifndef GPAC_DISABLE_ISOM_WRITE
12589 :
12590 1 : GF_Err svhd_box_write(GF_Box *s, GF_BitStream *bs)
12591 : {
12592 : GF_Err e;
12593 : GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;
12594 :
12595 1 : e = gf_isom_full_box_write(s, bs);
12596 1 : if (e) return e;
12597 1 : if (ptr->string)
12598 0 : gf_bs_write_data(bs, ptr->string, (u32) strlen(ptr->string));
12599 1 : gf_bs_write_u8(bs, 0);
12600 1 : return GF_OK;
12601 : }
12602 :
12603 1 : GF_Err svhd_box_size(GF_Box *s)
12604 : {
12605 : GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;
12606 1 : if (ptr->string)
12607 0 : s->size += (u32) strlen(ptr->string);
12608 1 : s->size += 1;
12609 1 : return GF_OK;
12610 : }
12611 :
12612 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
12613 :
12614 :
12615 3 : GF_Box *prhd_box_new()
12616 : {
12617 6 : ISOM_DECL_BOX_ALLOC(GF_ProjectionHeaderBox, GF_ISOM_BOX_TYPE_PRHD);
12618 3 : return (GF_Box *)tmp;
12619 : }
12620 :
12621 3 : void prhd_box_del(GF_Box *s)
12622 : {
12623 3 : gf_free(s);
12624 3 : }
12625 :
12626 :
12627 1 : GF_Err prhd_box_read(GF_Box *s, GF_BitStream *bs)
12628 : {
12629 : GF_ProjectionHeaderBox *ptr = (GF_ProjectionHeaderBox *)s;
12630 1 : ISOM_DECREASE_SIZE(ptr, 12)
12631 1 : ptr->yaw = (s32) gf_bs_read_u32(bs);
12632 1 : ptr->pitch = (s32) gf_bs_read_u32(bs);
12633 1 : ptr->roll = (s32) gf_bs_read_u32(bs);
12634 1 : return GF_OK;
12635 : }
12636 :
12637 :
12638 : #ifndef GPAC_DISABLE_ISOM_WRITE
12639 :
12640 1 : GF_Err prhd_box_write(GF_Box *s, GF_BitStream *bs)
12641 : {
12642 : GF_Err e;
12643 : GF_ProjectionHeaderBox *ptr = (GF_ProjectionHeaderBox *)s;
12644 :
12645 1 : e = gf_isom_full_box_write(s, bs);
12646 1 : if (e) return e;
12647 1 : gf_bs_write_u32(bs, ptr->yaw);
12648 1 : gf_bs_write_u32(bs, ptr->pitch);
12649 1 : gf_bs_write_u32(bs, ptr->roll);
12650 1 : return GF_OK;
12651 : }
12652 :
12653 1 : GF_Err prhd_box_size(GF_Box *s)
12654 : {
12655 1 : s->size += 12;
12656 1 : return GF_OK;
12657 : }
12658 :
12659 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
12660 :
12661 9 : GF_Box *proj_type_box_new()
12662 : {
12663 18 : ISOM_DECL_BOX_ALLOC(GF_ProjectionTypeBox, GF_ISOM_BOX_TYPE_EQUI); //will be overwritten
12664 9 : return (GF_Box *)tmp;
12665 : }
12666 :
12667 9 : void proj_type_box_del(GF_Box *s)
12668 : {
12669 9 : gf_free(s);
12670 9 : }
12671 :
12672 3 : GF_Err proj_type_box_read(GF_Box *s, GF_BitStream *bs)
12673 : {
12674 : GF_ProjectionTypeBox *ptr = (GF_ProjectionTypeBox *)s;
12675 :
12676 3 : if (ptr->type==GF_ISOM_BOX_TYPE_CBMP) {
12677 1 : ISOM_DECREASE_SIZE(ptr, 8)
12678 1 : ptr->layout = gf_bs_read_u32(bs);
12679 1 : ptr->padding = gf_bs_read_u32(bs);
12680 : }
12681 2 : else if (ptr->type==GF_ISOM_BOX_TYPE_EQUI) {
12682 1 : ISOM_DECREASE_SIZE(ptr, 16)
12683 1 : ptr->bounds_top = gf_bs_read_u32(bs);
12684 1 : ptr->bounds_bottom = gf_bs_read_u32(bs);
12685 1 : ptr->bounds_left = gf_bs_read_u32(bs);
12686 1 : ptr->bounds_right = gf_bs_read_u32(bs);
12687 : } else {
12688 1 : ISOM_DECREASE_SIZE(ptr, 8)
12689 1 : ptr->crc = gf_bs_read_u32(bs);
12690 1 : ptr->encoding_4cc = gf_bs_read_u32(bs);
12691 : }
12692 3 : return gf_isom_box_array_read(s, bs);
12693 : }
12694 :
12695 :
12696 : #ifndef GPAC_DISABLE_ISOM_WRITE
12697 :
12698 3 : GF_Err proj_type_box_write(GF_Box *s, GF_BitStream *bs)
12699 : {
12700 : GF_Err e;
12701 : GF_ProjectionTypeBox *ptr = (GF_ProjectionTypeBox *)s;
12702 :
12703 3 : e = gf_isom_full_box_write(s, bs);
12704 3 : if (e) return e;
12705 3 : if (ptr->type==GF_ISOM_BOX_TYPE_CBMP) {
12706 1 : gf_bs_write_u32(bs, ptr->layout);
12707 1 : gf_bs_write_u32(bs, ptr->padding);
12708 : }
12709 2 : else if (ptr->type==GF_ISOM_BOX_TYPE_EQUI) {
12710 1 : gf_bs_write_u32(bs, ptr->bounds_top);
12711 1 : gf_bs_write_u32(bs, ptr->bounds_bottom);
12712 1 : gf_bs_write_u32(bs, ptr->bounds_left);
12713 1 : gf_bs_write_u32(bs, ptr->bounds_right);
12714 : } else {
12715 1 : gf_bs_write_u32(bs, ptr->crc);
12716 1 : gf_bs_write_u32(bs, ptr->encoding_4cc);
12717 : }
12718 : return GF_OK;
12719 : }
12720 :
12721 3 : GF_Err proj_type_box_size(GF_Box *s)
12722 : {
12723 : GF_ProjectionTypeBox *ptr = (GF_ProjectionTypeBox *)s;
12724 3 : if (ptr->type==GF_ISOM_BOX_TYPE_CBMP)
12725 1 : s->size += 8;
12726 2 : else if (ptr->type==GF_ISOM_BOX_TYPE_EQUI)
12727 1 : s->size += 16;
12728 : else
12729 1 : s->size += 8;
12730 :
12731 3 : return GF_OK;
12732 : }
12733 :
12734 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
12735 :
12736 : #endif /*GPAC_DISABLE_ISOM*/
|