Coverage Report

Created: 2026-03-10 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpac/src/isomedia/box_code_apple.c
Line
Count
Source
1
/*
2
 *      GPAC - Multimedia Framework C SDK
3
 *
4
 *      Authors: Jean Le Feuvre
5
 *      Copyright (c) Telecom ParisTech 2006-2025
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
#ifndef GPAC_DISABLE_ISOM
29
30
void ilst_box_del(GF_Box *s)
31
2.82k
{
32
2.82k
  GF_ItemListBox *ptr = (GF_ItemListBox *)s;
33
2.82k
  if (ptr == NULL) return;
34
2.82k
  gf_free(ptr);
35
2.82k
}
36
37
GF_Err ilst_box_read(GF_Box *s, GF_BitStream *bs)
38
2.82k
{
39
2.82k
  GF_Err e;
40
2.82k
  u32 sub_type;
41
2.82k
  GF_Box *a = NULL;
42
2.82k
  GF_ItemListBox *ptr = (GF_ItemListBox *)s;
43
19.3k
  while (ptr->size) {
44
    /*if no ilst type coded, break*/
45
18.7k
    sub_type = gf_bs_peek_bits(bs, 32, 0);
46
18.7k
    if (sub_type) {
47
9.68k
      e = gf_isom_box_parse_ex(&a, bs, s->type, GF_FALSE, s->size);
48
49
      /* the macro will return in this case before we can free */
50
9.68k
      if (!e && a && ptr->size < a->size) {
51
109
        GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isom] not enough bytes in box %s: %d left, reading %d (file %s, line %d)\n", gf_4cc_to_str(ptr->type), ptr->size, a->size, __FILE__, __LINE__ )); \
52
109
        e = GF_ISOM_INVALID_FILE;
53
109
      }
54
9.68k
      if (e) {
55
1.93k
        if (a) gf_isom_box_del(a);
56
1.93k
        return e;
57
1.93k
      }
58
7.74k
      if (!a) return GF_NON_COMPLIANT_BITSTREAM;
59
60
15.4k
      ISOM_DECREASE_SIZE(ptr, a->size);
61
15.4k
      gf_list_add(ptr->child_boxes, a);
62
15.4k
    } else {
63
9.04k
      gf_bs_read_u32(bs);
64
9.04k
      ISOM_DECREASE_SIZE(ptr, 4);
65
8.75k
    }
66
18.7k
  }
67
589
  return GF_OK;
68
2.82k
}
69
70
GF_Box *ilst_box_new()
71
2.82k
{
72
2.82k
  ISOM_DECL_BOX_ALLOC(GF_ItemListBox, GF_ISOM_BOX_TYPE_ILST);
73
2.82k
  tmp->child_boxes = gf_list_new();
74
2.82k
  return (GF_Box *)tmp;
75
2.82k
}
76
77
#ifndef GPAC_DISABLE_ISOM_WRITE
78
79
GF_Err ilst_box_write(GF_Box *s, GF_BitStream *bs)
80
31
{
81
31
  GF_Err e;
82
//  GF_ItemListBox *ptr = (GF_ItemListBox *)s;
83
84
31
  e = gf_isom_box_write_header(s, bs);
85
31
  if (e) return e;
86
87
31
  return GF_OK;
88
31
}
89
90
91
GF_Err ilst_box_size(GF_Box *s)
92
31
{
93
31
  return GF_OK;
94
31
}
95
96
#endif /*GPAC_DISABLE_ISOM_WRITE*/
97
98
void ilst_item_box_del(GF_Box *s)
99
1.88k
{
100
1.88k
  GF_ListItemBox *ptr = (GF_ListItemBox *) s;
101
1.88k
  if (ptr == NULL) return;
102
1.88k
  gf_free(ptr);
103
1.88k
}
104
105
GF_Err ilst_item_box_read(GF_Box *s,GF_BitStream *bs)
106
1.88k
{
107
1.88k
  GF_Err e;
108
1.88k
  u32 sub_type;
109
1.88k
  GF_Box *a = NULL;
110
1.88k
  GF_ListItemBox *ptr = (GF_ListItemBox *)s;
111
112
  /*iTunes way: there's a data atom containing the data*/
113
1.88k
  sub_type = gf_bs_peek_bits(bs, 32, 4);
114
1.88k
  if (sub_type == GF_ISOM_BOX_TYPE_DATA ) {
115
568
    e = gf_isom_box_parse(&a, bs);
116
117
568
    if (!e && a && (ptr->size < a->size)) {
118
43
      GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isom] not enough bytes in box %s: %d left, reading %d (file %s, line %d)\n", gf_4cc_to_str(ptr->type), ptr->size, a->size, __FILE__, __LINE__ )); \
119
43
      e = GF_ISOM_INVALID_FILE;
120
43
    }
121
568
    if (!a) e = GF_ISOM_INVALID_FILE;
122
123
568
    if (e) {
124
249
      if (a) gf_isom_box_del(a);
125
249
      return e;
126
249
    }
127
319
    if (!a) return GF_NON_COMPLIANT_BITSTREAM;
128
129
638
    ISOM_DECREASE_SIZE(ptr, a->size);
130
131
638
    if (ptr->data) gf_isom_box_del_parent(&ptr->child_boxes, (GF_Box *) ptr->data);
132
133
    /* otherwise a->data will always overflow */
134
638
    if (a->size > 4 && (a->type != GF_ISOM_BOX_TYPE_VOID)) {
135
79
      ptr->data = (GF_DataBox *)a;
136
79
      if (!ptr->child_boxes) ptr->child_boxes = gf_list_new();
137
79
      gf_list_add(ptr->child_boxes, ptr->data);
138
240
    } else {
139
240
      ptr->data = NULL;
140
240
      gf_isom_box_del(a);
141
240
    }
142
638
  }
143
  /*QT way*/
144
1.32k
  else {
145
1.32k
    u64 pos = gf_bs_get_position(bs);
146
1.32k
    u64 prev_size = s->size;
147
    /*try parsing as generic box list*/
148
1.32k
    e = gf_isom_box_array_read(s, bs);
149
1.32k
    if (e==GF_OK) return GF_OK;
150
    //reset content and retry - this deletes ptr->data !!
151
728
    gf_isom_box_array_del(s->child_boxes);
152
728
    s->child_boxes=NULL;
153
728
    gf_bs_seek(bs, pos);
154
728
    s->size = prev_size;
155
156
728
    ptr->data = (GF_DataBox *)gf_isom_box_new_parent(&ptr->child_boxes, GF_ISOM_BOX_TYPE_DATA);
157
    //nope, check qt-style
158
728
    ptr->data->qt_style = GF_TRUE;
159
728
    ISOM_DECREASE_SIZE(ptr, 2);
160
728
    ptr->data->dataSize = gf_bs_read_u16(bs);
161
728
    gf_bs_read_u16(bs);
162
163
728
    ptr->data->data = (char *) gf_malloc(sizeof(char)*(ptr->data->dataSize + 1));
164
728
    if (!ptr->data->data) return GF_OUT_OF_MEM;
165
166
728
    gf_bs_read_data(bs, ptr->data->data, ptr->data->dataSize);
167
728
    ptr->data->data[ptr->data->dataSize] = 0;
168
728
    ISOM_DECREASE_SIZE(ptr, ptr->data->dataSize);
169
502
  }
170
821
  return GF_OK;
171
1.88k
}
172
173
GF_Box *ilst_item_box_new()
174
1.88k
{
175
1.88k
  ISOM_DECL_BOX_ALLOC(GF_ListItemBox, GF_ISOM_ITUNE_NAME); //type will be overwrite
176
1.88k
  return (GF_Box *)tmp;
177
1.88k
}
178
179
GF_Err ilst_item_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
180
997
{
181
997
  GF_ListItemBox *ptr = (GF_ListItemBox*)s;
182
997
  switch (a->type) {
183
188
  case GF_QT_BOX_TYPE_NAME:
184
188
    BOX_FIELD_ASSIGN(name, GF_NameBox)
185
134
    break;
186
335
  case GF_QT_BOX_TYPE_MEAN:
187
335
    BOX_FIELD_ASSIGN(mean, GF_NameBox)
188
269
    break;
189
269
  case GF_ISOM_BOX_TYPE_DATA:
190
67
    BOX_FIELD_ASSIGN(data, GF_DataBox)
191
10
    break;
192
407
  default:
193
407
    return GF_OK;
194
997
  }
195
413
  return GF_OK;
196
997
}
197
198
#ifndef GPAC_DISABLE_ISOM_WRITE
199
200
GF_Err ilst_item_box_write(GF_Box *s, GF_BitStream *bs)
201
8
{
202
8
  GF_Err e;
203
8
  GF_ListItemBox *ptr = (GF_ListItemBox *) s;
204
205
8
  e = gf_isom_box_write_header(s, bs);
206
8
  if (e) return e;
207
208
  /*generic box list*/
209
8
  if (ptr->child_boxes && !ptr->data) {
210
0
  }
211
  //empty ilst
212
8
  else if (!ptr->data) {
213
0
  }
214
  /*iTune way: data-box-encapsulated box list*/
215
8
  else if (!ptr->data->qt_style) {
216
8
  }
217
  /*QT way: raw data*/
218
0
  else {
219
0
    gf_bs_write_u16(bs, ptr->data->dataSize);
220
0
    gf_bs_write_u16(bs, 0);
221
0
    gf_bs_write_data(bs, ptr->data->data, ptr->data->dataSize);
222
0
    ptr->size = 0; //abort
223
0
  }
224
8
  return GF_OK;
225
8
}
226
227
GF_Err ilst_item_box_size(GF_Box *s)
228
8
{
229
8
  GF_ListItemBox *ptr = (GF_ListItemBox *)s;
230
231
  /*generic box list*/
232
8
  if (ptr->child_boxes && !ptr->data) {
233
0
  }
234
  /*iTune way: data-box-encapsulated box list*/
235
8
  else if (ptr->data && !ptr->data->qt_style) {
236
8
    u32 pos=0;
237
8
    gf_isom_check_position(s, (GF_Box* ) ptr->mean, &pos);
238
8
    gf_isom_check_position(s, (GF_Box* ) ptr->name, &pos);
239
8
    gf_isom_check_position(s, (GF_Box* ) ptr->data, &pos);
240
8
  }
241
  /*QT way: raw data*/
242
0
  else if (ptr->data) {
243
0
    ptr->size += ptr->data->dataSize + 4;
244
0
  }
245
8
  return GF_OK;
246
8
}
247
248
#endif /*GPAC_DISABLE_ISOM_WRITE*/
249
250
GF_Box *vexu_box_new()
251
42
{
252
42
  ISOM_DECL_BOX_ALLOC(GF_VideoExtendedUsageBox, GF_ISOM_BOX_TYPE_VEXU);
253
42
  tmp->child_boxes = gf_list_new();
254
42
  return (GF_Box *)tmp;
255
42
}
256
257
258
void vexu_box_del(GF_Box *s)
259
42
{
260
42
  GF_VideoExtendedUsageBox *ptr = (GF_VideoExtendedUsageBox*)s;
261
42
  if (ptr == NULL) return;
262
42
  gf_free(ptr);
263
42
}
264
265
266
GF_Err vexu_box_read(GF_Box *s, GF_BitStream *bs)
267
42
{
268
42
  return gf_isom_box_array_read(s, bs);
269
42
}
270
271
272
#ifndef GPAC_DISABLE_ISOM_WRITE
273
274
GF_Err vexu_box_write(GF_Box *s, GF_BitStream *bs)
275
0
{
276
0
  return gf_isom_box_write_header(s, bs);
277
0
}
278
279
GF_Err vexu_box_size(GF_Box *s)
280
0
{
281
0
  return GF_OK;
282
0
}
283
284
#endif /*GPAC_DISABLE_ISOM_WRITE*/
285
286
GF_Box *eyes_box_new()
287
2
{
288
2
  ISOM_DECL_BOX_ALLOC(GF_StereoViewBox, GF_ISOM_BOX_TYPE_EYES);
289
2
  tmp->child_boxes = gf_list_new();
290
2
  return (GF_Box *)tmp;
291
2
}
292
293
294
void eyes_box_del(GF_Box *s)
295
2
{
296
2
  GF_StereoViewBox *ptr = (GF_StereoViewBox*)s;
297
2
  if (ptr == NULL) return;
298
2
  gf_free(ptr);
299
2
}
300
301
302
GF_Err eyes_box_read(GF_Box *s, GF_BitStream *bs)
303
1
{
304
1
  GF_StereoViewBox *ptr = (GF_StereoViewBox*)s;
305
  //GF_Err e;
306
1
  u32 size = 0, type = 0;
307
308
  // mandatory Stereo view information 'stri' box
309
1
  size = gf_bs_read_int(bs, 32);
310
1
  type = gf_bs_read_int(bs, 32);
311
1
  if (size != 13 || type != 0x73747269) {
312
1
    GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Only support 'eyes' box with one 'stri' box at the begining.\n"));
313
1
    return GF_OK;
314
1
  }
315
0
  ptr->stri.version = gf_bs_read_int(bs, 8);
316
0
  ptr->stri.flags = gf_bs_read_int(bs, 24);
317
0
  ptr->stri.reserved = gf_bs_read_int(bs, 4);
318
0
  ptr->stri.eye_views_reversed = gf_bs_read_int(bs, 1);
319
0
  ptr->stri.has_additional_views = gf_bs_read_int(bs, 1);
320
0
  ptr->stri.has_right_eye_view = gf_bs_read_int(bs, 1);
321
0
  ptr->stri.has_left_eye_view = gf_bs_read_int(bs, 1);
322
323
0
  ptr->size -= 13;
324
325
  // if there are more child-boxes in 'eyes' box
326
0
  return gf_isom_box_array_read(s, bs);
327
1
}
328
329
330
#ifndef GPAC_DISABLE_ISOM_WRITE
331
332
GF_Err eyes_box_write(GF_Box *s, GF_BitStream *bs)
333
0
{
334
0
  gf_isom_box_write_header(s, bs);
335
336
0
  GF_StereoViewBox *ptr = (GF_StereoViewBox*)s;
337
338
  // mandatory Stereo view information 'stri' box
339
0
  gf_bs_write_int(bs, 13, 32); // size
340
0
  gf_bs_write_int(bs, 's', 8);
341
0
  gf_bs_write_int(bs, 't', 8);
342
0
  gf_bs_write_int(bs, 'r', 8);
343
0
  gf_bs_write_int(bs, 'i', 8); // box type
344
0
  gf_bs_write_int(bs, 0, 8); // version
345
0
  gf_bs_write_int(bs, 0, 24); // flag
346
0
  gf_bs_write_int(bs, ptr->stri.reserved, 4);
347
0
  gf_bs_write_int(bs, ptr->stri.eye_views_reversed, 1);
348
0
  gf_bs_write_int(bs, ptr->stri.has_additional_views, 1);
349
0
  gf_bs_write_int(bs, ptr->stri.has_right_eye_view, 1);
350
0
  gf_bs_write_int(bs, ptr->stri.has_left_eye_view, 1);
351
352
0
  return GF_OK;
353
0
}
354
355
GF_Err eyes_box_size(GF_Box *s)
356
0
{
357
0
  s->size += 13;
358
0
  return GF_OK;
359
0
}
360
361
#endif /*GPAC_DISABLE_ISOM_WRITE*/
362
363
364
GF_Box *hero_box_new()
365
3
{
366
3
  ISOM_DECL_BOX_ALLOC(GF_HeroStereoEyeDescriptionBox, GF_ISOM_BOX_TYPE_HERO);
367
3
  return (GF_Box *)tmp;
368
3
}
369
370
void hero_box_del(GF_Box *s)
371
3
{
372
3
  GF_HeroStereoEyeDescriptionBox *ptr = (GF_HeroStereoEyeDescriptionBox*)s;
373
3
  if (ptr == NULL) return;
374
3
  gf_free(ptr);
375
3
}
376
377
378
GF_Err hero_box_read(GF_Box *s, GF_BitStream *bs)
379
3
{
380
3
  GF_HeroStereoEyeDescriptionBox *ptr = (GF_HeroStereoEyeDescriptionBox*)s;
381
3
  ptr->version = gf_bs_read_int(bs, 8);
382
3
  ptr->flags = gf_bs_read_int(bs, 24);
383
3
  ptr->hero_eye_indicator = gf_bs_read_int(bs, 8);
384
3
  return GF_OK;
385
3
}
386
387
388
#ifndef GPAC_DISABLE_ISOM_WRITE
389
390
GF_Err hero_box_write(GF_Box *s, GF_BitStream *bs)
391
0
{
392
0
  GF_HeroStereoEyeDescriptionBox *ptr = (GF_HeroStereoEyeDescriptionBox *)s;
393
0
  GF_Err e = gf_isom_full_box_write(s, bs);
394
0
  if (e) return e;
395
0
  gf_bs_write_int(bs, ptr->hero_eye_indicator, 8);
396
0
  return GF_OK;
397
0
}
398
399
GF_Err hero_box_size(GF_Box *s)
400
0
{
401
0
  s->size += 5;
402
0
  return GF_OK;
403
0
}
404
405
#endif /*GPAC_DISABLE_ISOM_WRITE*/
406
407
void databox_box_del(GF_Box *s)
408
2.26k
{
409
2.26k
  GF_DataBox *ptr = (GF_DataBox *) s;
410
2.26k
  if (ptr == NULL) return;
411
2.26k
  if (ptr->data)
412
1.82k
    gf_free(ptr->data);
413
2.26k
  gf_free(ptr);
414
415
2.26k
}
416
417
GF_Err databox_box_read(GF_Box *s,GF_BitStream *bs)
418
1.52k
{
419
1.52k
  GF_DataBox *ptr = (GF_DataBox *)s;
420
421
1.52k
  ISOM_DECREASE_SIZE(ptr, 4);
422
1.33k
  ptr->locale = gf_bs_read_u32(bs);
423
424
1.33k
  if (ptr->size) {
425
1.09k
    ptr->dataSize = (u32) ptr->size;
426
1.09k
    ptr->data = (char*)gf_malloc(ptr->dataSize * sizeof(ptr->data[0]) + 1);
427
1.09k
    if (!ptr->data) return GF_OUT_OF_MEM;
428
1.09k
    ptr->data[ptr->dataSize] = 0;
429
1.09k
    gf_bs_read_data(bs, ptr->data, ptr->dataSize);
430
1.09k
  }
431
432
1.33k
  return GF_OK;
433
1.33k
}
434
435
GF_Box *databox_box_new()
436
2.26k
{
437
2.26k
  ISOM_DECL_BOX_ALLOC(GF_DataBox, GF_ISOM_BOX_TYPE_DATA);
438
439
2.26k
  return (GF_Box *)tmp;
440
2.26k
}
441
442
#ifndef GPAC_DISABLE_ISOM_WRITE
443
444
GF_Err databox_box_write(GF_Box *s, GF_BitStream *bs)
445
120
{
446
120
  GF_Err e;
447
120
  GF_DataBox *ptr = (GF_DataBox *) s;
448
449
120
  e = gf_isom_full_box_write(s, bs);
450
120
  if (e) return e;
451
120
  gf_bs_write_int(bs, ptr->locale, 32);
452
120
  if(ptr->data != NULL && ptr->dataSize > 0) {
453
120
    gf_bs_write_data(bs, ptr->data, ptr->dataSize);
454
120
  }
455
120
  return GF_OK;
456
120
}
457
458
GF_Err databox_box_size(GF_Box *s)
459
120
{
460
120
  GF_DataBox *ptr = (GF_DataBox *)s;
461
462
120
  ptr->size += 4;
463
120
  if(ptr->data != NULL && ptr->dataSize > 0) {
464
120
    ptr->size += ptr->dataSize;
465
120
  }
466
120
  return GF_OK;
467
120
}
468
469
#endif /*GPAC_DISABLE_ISOM_WRITE*/
470
471
void alis_box_del(GF_Box *s)
472
419
{
473
419
  GF_DataEntryAliasBox *ptr = (GF_DataEntryAliasBox *)s;
474
419
  if (ptr == NULL) return;
475
419
  gf_free(ptr);
476
419
}
477
478
GF_Err alis_box_read(GF_Box *s, GF_BitStream *bs)
479
416
{
480
//  GF_DataEntryAliasBox *ptr = (GF_DataEntryAliasBox *)s;
481
416
  return GF_OK;
482
416
}
483
484
GF_Box *alis_box_new()
485
419
{
486
419
  ISOM_DECL_BOX_ALLOC(GF_DataEntryAliasBox, GF_QT_BOX_TYPE_ALIS);
487
419
  return (GF_Box *)tmp;
488
419
}
489
490
#ifndef GPAC_DISABLE_ISOM_WRITE
491
492
GF_Err alis_box_write(GF_Box *s, GF_BitStream *bs)
493
0
{
494
0
  GF_Err e;
495
//  GF_DataEntryAliasBox *ptr = (GF_DataEntryAliasBox *)s;
496
497
0
  e = gf_isom_full_box_write(s, bs);
498
0
  if (e) return e;
499
0
  return GF_OK;
500
0
}
501
502
GF_Err alis_box_size(GF_Box *s)
503
0
{
504
0
  return GF_OK;
505
0
}
506
507
#endif /*GPAC_DISABLE_ISOM_WRITE*/
508
509
void wide_box_del(GF_Box *s)
510
172
{
511
172
  if (s == NULL) return;
512
172
  gf_free(s);
513
172
}
514
515
516
GF_Err wide_box_read(GF_Box *s, GF_BitStream *bs)
517
172
{
518
172
  gf_bs_skip_bytes(bs, s->size);
519
172
  s->size = 0;
520
172
  return GF_OK;
521
172
}
522
523
GF_Box *wide_box_new()
524
172
{
525
172
  ISOM_DECL_BOX_ALLOC(GF_WideBox, GF_QT_BOX_TYPE_WIDE);
526
172
  return (GF_Box *)tmp;
527
172
}
528
529
#ifndef GPAC_DISABLE_ISOM_WRITE
530
531
GF_Err wide_box_write(GF_Box *s, GF_BitStream *bs)
532
0
{
533
0
  GF_Err e;
534
0
  e = gf_isom_box_write_header(s, bs);
535
0
  if (e) return e;
536
0
  return GF_OK;
537
0
}
538
539
GF_Err wide_box_size(GF_Box *s)
540
0
{
541
0
  return GF_OK;
542
0
}
543
544
#endif /*GPAC_DISABLE_ISOM_WRITE*/
545
546
GF_Box *gf_isom_get_meta_extensions(GF_ISOFile *mov, u32 meta_type)
547
224
{
548
224
  u32 i;
549
224
  GF_UserDataMap *map;
550
551
224
  if (!mov || !mov->moov) return NULL;
552
553
220
  if (!mov->moov->udta) return NULL;
554
142
  map = udta_getEntry(mov->moov->udta, (meta_type==1) ? GF_ISOM_BOX_TYPE_XTRA : GF_ISOM_BOX_TYPE_META, NULL);
555
142
  if (!map) return NULL;
556
557
12
  for(i = 0; i < gf_list_count(map->boxes); i++) {
558
12
    GF_MetaBox *meta = (GF_MetaBox*)gf_list_get(map->boxes, i);
559
12
    if ((meta_type==1) && (meta->type==GF_ISOM_BOX_TYPE_XTRA)) return (GF_Box *) meta;
560
561
12
    if (meta && meta->handler) {
562
12
      if ( (meta_type==0) && (meta->handler->handlerType == GF_ISOM_HANDLER_TYPE_MDIR))
563
12
        return (GF_Box *) meta;
564
0
      if ( (meta_type==2) && (meta->handler->handlerType == GF_ISOM_HANDLER_TYPE_MDTA))
565
0
        return (GF_Box *) meta;
566
0
    }
567
12
  }
568
0
  return NULL;
569
12
}
570
571
#ifndef GPAC_DISABLE_ISOM_WRITE
572
GF_Box *gf_isom_create_meta_extensions(GF_ISOFile *mov, u32 meta_type)
573
0
{
574
0
  GF_Err e;
575
0
  u32 i;
576
0
  GF_MetaBox *meta;
577
0
  GF_UserDataMap *map;
578
0
  u32 udta_subtype = (meta_type==1) ? GF_ISOM_BOX_TYPE_XTRA : GF_ISOM_BOX_TYPE_META;
579
580
0
  if (!mov || !mov->moov) return NULL;
581
582
0
  if (!mov->moov->udta) {
583
0
    e = moov_on_child_box((GF_Box*)mov->moov, gf_isom_box_new_parent(&mov->moov->child_boxes, GF_ISOM_BOX_TYPE_UDTA), GF_FALSE);
584
0
    if (e) return NULL;
585
0
  }
586
587
0
  map = udta_getEntry(mov->moov->udta, udta_subtype, NULL);
588
0
  if (map) {
589
0
    for (i=0; i<gf_list_count(map->boxes); i++) {
590
0
      meta = (GF_MetaBox*)gf_list_get(map->boxes, i);
591
0
      if (meta_type==1) return (GF_Box *) meta;
592
593
0
      if (meta && meta->handler) {
594
0
        if ((meta_type==0) && (meta->handler->handlerType == GF_ISOM_HANDLER_TYPE_MDIR)) return (GF_Box *) meta;
595
0
        if ((meta_type==2) && (meta->handler->handlerType == GF_ISOM_HANDLER_TYPE_MDTA)) return (GF_Box *) meta;
596
0
      }
597
0
    }
598
0
  }
599
600
  //udta handles children boxes through maps
601
0
  meta = (GF_MetaBox *)gf_isom_box_new(udta_subtype);
602
603
0
  if (meta) {
604
0
    udta_on_child_box_ex((GF_Box *)mov->moov->udta, (GF_Box *)meta, GF_FALSE, GF_TRUE);
605
0
    if (meta_type!=1) {
606
0
      meta->handler = (GF_HandlerBox *)gf_isom_box_new_parent(&meta->child_boxes, GF_ISOM_BOX_TYPE_HDLR);
607
0
      if(meta->handler == NULL) {
608
0
        gf_isom_box_del((GF_Box *)meta);
609
0
        return NULL;
610
0
      }
611
0
      meta->handler->handlerType = (meta_type==2) ? GF_ISOM_HANDLER_TYPE_MDTA : GF_ISOM_HANDLER_TYPE_MDIR;
612
0
      gf_isom_box_new_parent(&meta->child_boxes, GF_ISOM_BOX_TYPE_ILST);
613
0
    }
614
0
  }
615
0
  return (GF_Box *) meta;
616
0
}
617
#endif /*GPAC_DISABLE_ISOM_WRITE*/
618
619
620
621
void gmin_box_del(GF_Box *s)
622
829
{
623
829
  gf_free(s);
624
829
}
625
626
GF_Err gmin_box_read(GF_Box *s, GF_BitStream *bs)
627
828
{
628
828
  GF_GenericMediaHeaderInfoBox *ptr = (GF_GenericMediaHeaderInfoBox *)s;
629
828
  ISOM_DECREASE_SIZE(ptr, 12);
630
169
  ptr->graphics_mode = gf_bs_read_u16(bs);
631
169
  ptr->op_color_red = gf_bs_read_u16(bs);
632
169
  ptr->op_color_green = gf_bs_read_u16(bs);
633
169
  ptr->op_color_blue = gf_bs_read_u16(bs);
634
169
  ptr->balance = gf_bs_read_u16(bs);
635
169
  ptr->reserved = gf_bs_read_u16(bs);
636
169
  return GF_OK;
637
828
}
638
639
GF_Box *gmin_box_new()
640
829
{
641
829
  ISOM_DECL_BOX_ALLOC(GF_GenericMediaHeaderInfoBox, GF_QT_BOX_TYPE_GMIN);
642
829
  return (GF_Box *)tmp;
643
829
}
644
645
646
647
#ifndef GPAC_DISABLE_ISOM_WRITE
648
649
GF_Err gmin_box_write(GF_Box *s, GF_BitStream *bs)
650
69
{
651
69
  GF_Err e;
652
69
  GF_GenericMediaHeaderInfoBox *ptr = (GF_GenericMediaHeaderInfoBox *)s;
653
654
69
  e = gf_isom_full_box_write(s, bs);
655
69
  if (e) return e;
656
657
69
  gf_bs_write_u16(bs, ptr->graphics_mode);
658
69
  gf_bs_write_u16(bs, ptr->op_color_red);
659
69
  gf_bs_write_u16(bs, ptr->op_color_green);
660
69
  gf_bs_write_u16(bs, ptr->op_color_blue);
661
69
  gf_bs_write_u16(bs, ptr->balance);
662
69
  gf_bs_write_u16(bs, ptr->reserved);
663
69
  return GF_OK;
664
69
}
665
666
GF_Err gmin_box_size(GF_Box *s)
667
69
{
668
69
  GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
669
69
  ptr->size += 12;
670
69
  return GF_OK;
671
69
}
672
673
#endif /*GPAC_DISABLE_ISOM_WRITE*/
674
675
676
677
678
void clef_box_del(GF_Box *s)
679
223
{
680
223
  gf_free(s);
681
223
}
682
683
GF_Err clef_box_read(GF_Box *s, GF_BitStream *bs)
684
220
{
685
220
  GF_ApertureBox *ptr = (GF_ApertureBox *)s;
686
220
  ISOM_DECREASE_SIZE(ptr, 8);
687
200
  ptr->width = gf_bs_read_u32(bs);
688
200
  ptr->height = gf_bs_read_u32(bs);
689
200
  return GF_OK;
690
220
}
691
692
GF_Box *clef_box_new()
693
223
{
694
223
  ISOM_DECL_BOX_ALLOC(GF_ApertureBox, GF_QT_BOX_TYPE_CLEF);
695
223
  return (GF_Box *)tmp;
696
223
}
697
698
699
#ifndef GPAC_DISABLE_ISOM_WRITE
700
701
GF_Err clef_box_write(GF_Box *s, GF_BitStream *bs)
702
81
{
703
81
  GF_Err e;
704
81
  GF_ApertureBox *ptr = (GF_ApertureBox *)s;
705
706
81
  e = gf_isom_full_box_write(s, bs);
707
81
  if (e) return e;
708
81
  gf_bs_write_u32(bs, ptr->width);
709
81
  gf_bs_write_u32(bs, ptr->height);
710
81
  return GF_OK;
711
81
}
712
713
GF_Err clef_box_size(GF_Box *s)
714
81
{
715
81
  s->size += 8;
716
81
  return GF_OK;
717
81
}
718
719
#endif /*GPAC_DISABLE_ISOM_WRITE*/
720
721
722
void tmcd_box_del(GF_Box *s)
723
215
{
724
215
  if (s == NULL) return;
725
215
  gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
726
215
  gf_free(s);
727
215
}
728
729
730
GF_Err tmcd_box_read(GF_Box *s, GF_BitStream *bs)
731
215
{
732
215
  GF_TimeCodeSampleEntryBox *ptr = (GF_TimeCodeSampleEntryBox *)s;
733
215
  GF_Err e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)s, bs);
734
215
  if (e) return e;
735
736
215
  ISOM_DECREASE_SIZE(s, 26);
737
144
  gf_bs_read_u32(bs); //reserved
738
144
  ptr->flags = gf_bs_read_u32(bs);
739
144
  ptr->timescale = gf_bs_read_u32(bs);
740
144
  ptr->frame_duration = gf_bs_read_u32(bs);
741
144
  ptr->frames_per_counter_tick = gf_bs_read_u8(bs);
742
144
  gf_bs_read_u8(bs); //reserved
743
744
144
  return gf_isom_box_array_read(s, bs);
745
215
}
746
747
GF_Box *tmcd_box_new()
748
215
{
749
215
  ISOM_DECL_BOX_ALLOC(GF_TimeCodeSampleEntryBox, GF_QT_BOX_TYPE_TMCD);
750
215
  gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
751
215
  return (GF_Box *)tmp;
752
215
}
753
754
755
#ifndef GPAC_DISABLE_ISOM_WRITE
756
757
GF_Err tmcd_box_write(GF_Box *s, GF_BitStream *bs)
758
69
{
759
69
  GF_Err e;
760
69
  GF_TimeCodeSampleEntryBox *ptr = (GF_TimeCodeSampleEntryBox *)s;
761
69
  e = gf_isom_box_write_header(s, bs);
762
69
  if (e) return e;
763
764
69
  gf_bs_write_data(bs, ptr->reserved, 6);
765
69
  gf_bs_write_u16(bs, ptr->dataReferenceIndex);
766
767
69
  gf_bs_write_u32(bs, 0); //reserved
768
69
  gf_bs_write_u32(bs, ptr->flags);
769
69
  gf_bs_write_u32(bs, ptr->timescale);
770
69
  gf_bs_write_u32(bs, ptr->frame_duration);
771
69
  gf_bs_write_u8(bs, ptr->frames_per_counter_tick);
772
69
  gf_bs_write_u8(bs, 0); //reserved
773
774
69
  return GF_OK;
775
69
}
776
777
GF_Err tmcd_box_size(GF_Box *s)
778
69
{
779
69
  GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
780
69
  ptr->size += 8 + 18;
781
69
  return GF_OK;
782
69
}
783
784
#endif /*GPAC_DISABLE_ISOM_WRITE*/
785
786
787
void tcmi_box_del(GF_Box *s)
788
709
{
789
709
  GF_TimeCodeMediaInformationBox *ptr = (GF_TimeCodeMediaInformationBox *)s;
790
709
  if (ptr->font) gf_free(ptr->font);
791
709
  gf_free(s);
792
709
}
793
794
795
GF_Err tcmi_box_read(GF_Box *s, GF_BitStream *bs)
796
708
{
797
708
  u32 len;
798
708
  GF_TimeCodeMediaInformationBox *ptr = (GF_TimeCodeMediaInformationBox *)s;
799
800
  //don't remove font name len field, some writers just skip it if no font ...
801
708
  ISOM_DECREASE_SIZE(s, 20);
802
803
620
  ptr->text_font = gf_bs_read_u16(bs);
804
620
  ptr->text_face = gf_bs_read_u16(bs);
805
620
  ptr->text_size = gf_bs_read_u16(bs);
806
620
  gf_bs_read_u16(bs);
807
620
  ptr->text_color_red = gf_bs_read_u16(bs);
808
620
  ptr->text_color_green = gf_bs_read_u16(bs);
809
620
  ptr->text_color_blue = gf_bs_read_u16(bs);
810
620
  ptr->back_color_red = gf_bs_read_u16(bs);
811
620
  ptr->back_color_green = gf_bs_read_u16(bs);
812
620
  ptr->back_color_blue = gf_bs_read_u16(bs);
813
620
  if (!ptr->size) {
814
212
    GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] broken tmci box, missing font name length field\n" ));
815
212
    return GF_OK;
816
212
  }
817
816
  ISOM_DECREASE_SIZE(s, 1);
818
819
816
  len = gf_bs_read_u8(bs);
820
816
  if (len > ptr->size)
821
219
    len = (u32) ptr->size;
822
816
  if (len) {
823
279
    ptr->font = gf_malloc(len+1);
824
279
    if (!ptr->font) return GF_OUT_OF_MEM;
825
279
    gf_bs_read_data(bs, ptr->font, len);
826
279
    ptr->size -= len;
827
279
    ptr->font[len]=0;
828
279
  }
829
408
  return GF_OK;
830
816
}
831
832
GF_Box *tcmi_box_new()
833
709
{
834
709
  ISOM_DECL_BOX_ALLOC(GF_TimeCodeMediaInformationBox, GF_QT_BOX_TYPE_TCMI);
835
709
  tmp->text_size = 12;
836
709
  tmp->text_color_red = 0xFFFF;
837
709
  tmp->text_color_green = 0xFFFF;
838
709
  tmp->text_color_blue = 0xFFFF;
839
709
  return (GF_Box *)tmp;
840
709
}
841
842
843
#ifndef GPAC_DISABLE_ISOM_WRITE
844
845
GF_Err tcmi_box_write(GF_Box *s, GF_BitStream *bs)
846
69
{
847
69
  GF_Err e;
848
69
  u32 len;
849
69
  GF_TimeCodeMediaInformationBox *ptr = (GF_TimeCodeMediaInformationBox *)s;
850
851
69
  e = gf_isom_full_box_write(s, bs);
852
69
  if (e) return e;
853
69
  gf_bs_write_u16(bs, ptr->text_font);
854
69
  gf_bs_write_u16(bs, ptr->text_face);
855
69
  gf_bs_write_u16(bs, ptr->text_size);
856
69
  gf_bs_write_u16(bs, 0);
857
69
  gf_bs_write_u16(bs, ptr->text_color_red);
858
69
  gf_bs_write_u16(bs, ptr->text_color_green);
859
69
  gf_bs_write_u16(bs, ptr->text_color_blue);
860
69
  gf_bs_write_u16(bs, ptr->back_color_red);
861
69
  gf_bs_write_u16(bs, ptr->back_color_green);
862
69
  gf_bs_write_u16(bs, ptr->back_color_blue);
863
69
  len = ptr->font ? (u32) strlen(ptr->font) : 0;
864
69
  gf_bs_write_u8(bs, len);
865
69
  if (ptr->font)
866
51
    gf_bs_write_data(bs, ptr->font, len);
867
868
69
  return GF_OK;
869
69
}
870
871
GF_Err tcmi_box_size(GF_Box *s)
872
69
{
873
69
  GF_TimeCodeMediaInformationBox *ptr = (GF_TimeCodeMediaInformationBox *)s;
874
69
  ptr->size += 21;
875
69
  if (ptr->font)
876
51
      ptr->size += strlen(ptr->font);
877
69
  return GF_OK;
878
69
}
879
880
#endif /*GPAC_DISABLE_ISOM_WRITE*/
881
882
883
void fiel_box_del(GF_Box *s)
884
330
{
885
330
  gf_free(s);
886
330
}
887
888
889
GF_Err fiel_box_read(GF_Box *s, GF_BitStream *bs)
890
330
{
891
330
  GF_FieldInfoBox *ptr = (GF_FieldInfoBox *)s;
892
893
330
  ISOM_DECREASE_SIZE(s, 2);
894
895
254
    ptr->field_count = gf_bs_read_u8(bs);
896
254
    ptr->field_order = gf_bs_read_u8(bs);
897
254
  return GF_OK;
898
330
}
899
900
GF_Box *fiel_box_new()
901
330
{
902
330
  ISOM_DECL_BOX_ALLOC(GF_FieldInfoBox, GF_QT_BOX_TYPE_FIEL);
903
330
  return (GF_Box *)tmp;
904
330
}
905
906
907
#ifndef GPAC_DISABLE_ISOM_WRITE
908
909
GF_Err fiel_box_write(GF_Box *s, GF_BitStream *bs)
910
1
{
911
1
  GF_Err e;
912
1
  GF_FieldInfoBox *ptr = (GF_FieldInfoBox *)s;
913
1
  e = gf_isom_box_write_header(s, bs);
914
1
  if (e) return e;
915
1
  gf_bs_write_u8(bs, ptr->field_count);
916
1
  gf_bs_write_u8(bs, ptr->field_order);
917
1
  return GF_OK;
918
1
}
919
920
GF_Err fiel_box_size(GF_Box *s)
921
1
{
922
1
  s->size += 2;
923
1
  return GF_OK;
924
1
}
925
926
#endif /*GPAC_DISABLE_ISOM_WRITE*/
927
928
929
void gama_box_del(GF_Box *s)
930
155
{
931
155
  gf_free(s);
932
155
}
933
934
935
GF_Err gama_box_read(GF_Box *s, GF_BitStream *bs)
936
155
{
937
155
  GF_GamaInfoBox *ptr = (GF_GamaInfoBox *)s;
938
939
155
  ISOM_DECREASE_SIZE(s, 4);
940
941
76
    ptr->gama = gf_bs_read_u32(bs);
942
76
  return GF_OK;
943
155
}
944
945
GF_Box *gama_box_new()
946
155
{
947
155
  ISOM_DECL_BOX_ALLOC(GF_GamaInfoBox, GF_QT_BOX_TYPE_GAMA);
948
155
  return (GF_Box *)tmp;
949
155
}
950
951
952
#ifndef GPAC_DISABLE_ISOM_WRITE
953
954
GF_Err gama_box_write(GF_Box *s, GF_BitStream *bs)
955
0
{
956
0
  GF_GamaInfoBox *ptr = (GF_GamaInfoBox *)s;
957
0
  GF_Err e = gf_isom_box_write_header(s, bs);
958
0
  if (e) return e;
959
0
  gf_bs_write_u32(bs, ptr->gama);
960
0
  return GF_OK;
961
0
}
962
963
GF_Err gama_box_size(GF_Box *s)
964
0
{
965
0
  s->size += 4;
966
0
  return GF_OK;
967
0
}
968
969
#endif /*GPAC_DISABLE_ISOM_WRITE*/
970
971
972
void chrm_box_del(GF_Box *s)
973
956
{
974
956
  gf_free(s);
975
956
}
976
977
978
GF_Err chrm_box_read(GF_Box *s, GF_BitStream *bs)
979
955
{
980
955
  GF_ChromaInfoBox *ptr = (GF_ChromaInfoBox *)s;
981
982
955
  ISOM_DECREASE_SIZE(s, 2);
983
984
543
    ptr->chroma = gf_bs_read_u16(bs);
985
543
  return GF_OK;
986
955
}
987
988
GF_Box *chrm_box_new()
989
956
{
990
956
  ISOM_DECL_BOX_ALLOC(GF_ChromaInfoBox, GF_QT_BOX_TYPE_CHRM);
991
956
  return (GF_Box *)tmp;
992
956
}
993
994
995
#ifndef GPAC_DISABLE_ISOM_WRITE
996
997
GF_Err chrm_box_write(GF_Box *s, GF_BitStream *bs)
998
0
{
999
0
  GF_ChromaInfoBox *ptr = (GF_ChromaInfoBox *)s;
1000
0
  GF_Err e = gf_isom_box_write_header(s, bs);
1001
0
  if (e) return e;
1002
0
  gf_bs_write_u16(bs, ptr->chroma);
1003
0
  return GF_OK;
1004
0
}
1005
1006
GF_Err chrm_box_size(GF_Box *s)
1007
0
{
1008
0
  s->size += 2;
1009
0
  return GF_OK;
1010
0
}
1011
1012
#endif /*GPAC_DISABLE_ISOM_WRITE*/
1013
1014
1015
void chan_box_del(GF_Box *s)
1016
1.41k
{
1017
1.41k
  GF_ChannelLayoutInfoBox *ptr = (GF_ChannelLayoutInfoBox *)s;
1018
1.41k
  if (ptr->audio_descs) gf_free(ptr->audio_descs);
1019
1.41k
  if (ptr->ext_data) gf_free(ptr->ext_data);
1020
1.41k
  gf_free(s);
1021
1.41k
}
1022
1023
1024
GF_Err chan_box_read(GF_Box *s, GF_BitStream *bs)
1025
1.41k
{
1026
1.41k
  u32 i;
1027
1.41k
  GF_ChannelLayoutInfoBox *ptr = (GF_ChannelLayoutInfoBox *)s;
1028
1029
1.41k
  ISOM_DECREASE_SIZE(s, 12);
1030
1.12k
  ptr->layout_tag = gf_bs_read_u32(bs);
1031
1.12k
  ptr->bitmap = gf_bs_read_u32(bs);
1032
1.12k
  ptr->num_audio_description = gf_bs_read_u32(bs);
1033
1034
1.12k
  if (ptr->size / 20 < ptr->num_audio_description)
1035
96
    return GF_ISOM_INVALID_FILE;
1036
1037
1.02k
  ptr->audio_descs = gf_malloc(sizeof(GF_AudioChannelDescription) * ptr->num_audio_description);
1038
1.02k
  if (!ptr->audio_descs) return GF_OUT_OF_MEM;
1039
1040
2.65k
  for (i=0; i<ptr->num_audio_description; i++) {
1041
1.63k
    GF_AudioChannelDescription *adesc = &ptr->audio_descs[i];
1042
1.63k
    ISOM_DECREASE_SIZE(s, 20);
1043
1.63k
    adesc->label = gf_bs_read_u32(bs);
1044
1.63k
    adesc->flags = gf_bs_read_u32(bs);
1045
1.63k
    adesc->coordinates[0] = gf_bs_read_float(bs);
1046
1.63k
    adesc->coordinates[1] = gf_bs_read_float(bs);
1047
1.63k
    adesc->coordinates[2] = gf_bs_read_float(bs);
1048
1.63k
  }
1049
  //avoids warning on most files
1050
1.02k
  if (ptr->size==20) {
1051
221
    ptr->size=0;
1052
221
    gf_bs_skip_bytes(bs, 20);
1053
221
  }
1054
1.02k
  if (ptr->size<10000) {
1055
1.01k
    ptr->ext_data_size = (u32) ptr->size;
1056
1.01k
    ptr->ext_data = gf_malloc(sizeof(u8) * ptr->ext_data_size);
1057
1.01k
    if (!ptr->ext_data) return GF_OUT_OF_MEM;
1058
1.01k
    gf_bs_read_data(bs, (char *)ptr->ext_data, (u32) ptr->size);
1059
1.01k
    ptr->size = 0;
1060
1.01k
  }
1061
1.02k
  return GF_OK;
1062
1.02k
}
1063
1064
GF_Box *chan_box_new()
1065
1.41k
{
1066
1.41k
  ISOM_DECL_BOX_ALLOC(GF_ChannelLayoutInfoBox, GF_QT_BOX_TYPE_CHAN);
1067
1.41k
  return (GF_Box *)tmp;
1068
1.41k
}
1069
1070
1071
#ifndef GPAC_DISABLE_ISOM_WRITE
1072
1073
GF_Err chan_box_write(GF_Box *s, GF_BitStream *bs)
1074
1
{
1075
1
  GF_Err e;
1076
1
  u32 i;
1077
1
  GF_ChannelLayoutInfoBox *ptr = (GF_ChannelLayoutInfoBox *)s;
1078
1079
1
  e = gf_isom_full_box_write(s, bs);
1080
1
  if (e) return e;
1081
1082
1083
1
  gf_bs_write_u32(bs, ptr->layout_tag);
1084
1
  gf_bs_write_u32(bs, ptr->bitmap);
1085
1
  gf_bs_write_u32(bs, ptr->num_audio_description);
1086
1
  for (i=0; i<ptr->num_audio_description; i++) {
1087
0
    GF_AudioChannelDescription *adesc = &ptr->audio_descs[i];
1088
0
    gf_bs_write_u32(bs, adesc->label);
1089
0
    gf_bs_write_u32(bs, adesc->flags);
1090
0
    gf_bs_write_float(bs, adesc->coordinates[0]);
1091
0
    gf_bs_write_float(bs, adesc->coordinates[1]);
1092
0
    gf_bs_write_float(bs, adesc->coordinates[2]);
1093
0
  }
1094
1
  if (ptr->ext_data) {
1095
1
    gf_bs_write_data(bs, ptr->ext_data, ptr->ext_data_size);
1096
1
  }
1097
1
  return GF_OK;
1098
1
}
1099
1100
GF_Err chan_box_size(GF_Box *s)
1101
1
{
1102
1
  GF_ChannelLayoutInfoBox *ptr = (GF_ChannelLayoutInfoBox *)s;
1103
1
  s->size += 12 + 20 * ptr->num_audio_description;
1104
1
  if (ptr->ext_data) {
1105
1
    s->size += ptr->ext_data_size;
1106
1
  }
1107
1
  return GF_OK;
1108
1
}
1109
1110
#endif /*GPAC_DISABLE_ISOM_WRITE*/
1111
1112
1113
1114
void load_box_del(GF_Box *s)
1115
494
{
1116
494
  gf_free(s);
1117
494
}
1118
1119
1120
GF_Err load_box_read(GF_Box *s, GF_BitStream *bs)
1121
494
{
1122
494
  GF_TrackLoadBox *ptr = (GF_TrackLoadBox *)s;
1123
494
  ISOM_DECREASE_SIZE(s, 16);
1124
238
  ptr->preload_start_time = gf_bs_read_u32(bs);
1125
238
  ptr->preload_duration = gf_bs_read_u32(bs);
1126
238
  ptr->preload_flags = gf_bs_read_u32(bs);
1127
238
  ptr->default_hints = gf_bs_read_u32(bs);
1128
238
  return GF_OK;
1129
494
}
1130
1131
GF_Box *load_box_new()
1132
494
{
1133
494
  ISOM_DECL_BOX_ALLOC(GF_TrackLoadBox, GF_QT_BOX_TYPE_LOAD);
1134
494
  return (GF_Box *)tmp;
1135
494
}
1136
1137
1138
#ifndef GPAC_DISABLE_ISOM_WRITE
1139
1140
GF_Err load_box_write(GF_Box *s, GF_BitStream *bs)
1141
23
{
1142
23
  GF_TrackLoadBox *ptr = (GF_TrackLoadBox *)s;
1143
1144
23
  GF_Err e = gf_isom_box_write_header(s, bs);
1145
23
  if (e) return e;
1146
1147
23
  gf_bs_write_u32(bs, ptr->preload_start_time);
1148
23
  gf_bs_write_u32(bs, ptr->preload_duration);
1149
23
  gf_bs_write_u32(bs, ptr->preload_flags);
1150
23
  gf_bs_write_u32(bs, ptr->default_hints);
1151
23
  return GF_OK;
1152
23
}
1153
1154
GF_Err load_box_size(GF_Box *s)
1155
23
{
1156
23
  s->size += 16;
1157
23
  return GF_OK;
1158
23
}
1159
1160
#endif /*GPAC_DISABLE_ISOM_WRITE*/
1161
1162
1163
void keys_box_del(GF_Box *s)
1164
2.15k
{
1165
2.15k
  GF_MetaKeysBox *ptr = (GF_MetaKeysBox *)s;
1166
2.15k
  if (ptr == NULL) return;
1167
3.04k
  while (gf_list_count(ptr->keys)) {
1168
894
    GF_MetaKey *k = gf_list_pop_back(ptr->keys);
1169
894
    if (k->data) gf_free(k->data);
1170
894
    gf_free(k);
1171
894
  }
1172
2.15k
  gf_list_del(ptr->keys);
1173
2.15k
  gf_free(ptr);
1174
2.15k
}
1175
1176
GF_Err keys_box_read(GF_Box *s, GF_BitStream *bs)
1177
1.89k
{
1178
1.89k
  u32 i, nb_keys;
1179
1.89k
  GF_MetaKeysBox *ptr = (GF_MetaKeysBox *)s;
1180
1181
1.89k
  ISOM_DECREASE_SIZE(ptr, 4);
1182
1.82k
  nb_keys = gf_bs_read_u32(bs);
1183
2.71k
  for (i=0; i<nb_keys; i++) {
1184
2.14k
    GF_MetaKey *k;
1185
2.14k
    ISOM_DECREASE_SIZE(ptr, 8);
1186
1.35k
    u32 ksize = gf_bs_read_u32(bs);
1187
1.35k
    if (ksize<8) return GF_ISOM_INVALID_FILE;
1188
1.30k
    u32 ns = gf_bs_read_u32(bs);
1189
1.30k
    ISOM_DECREASE_SIZE(ptr, ksize-8);
1190
894
    GF_SAFEALLOC(k, GF_MetaKey);
1191
894
    if (!k) return GF_OUT_OF_MEM;
1192
894
    gf_list_add(ptr->keys, k);
1193
894
    k->ns = ns;
1194
894
    k->size = ksize-8;
1195
894
    k->data = gf_malloc(k->size+1);
1196
894
    if (!k->data) return GF_OUT_OF_MEM;
1197
894
    gf_bs_read_data(bs, k->data, k->size);
1198
894
    k->data[k->size]=0;
1199
894
  }
1200
566
  return GF_OK;
1201
1.82k
}
1202
1203
GF_Box *keys_box_new()
1204
2.15k
{
1205
2.15k
  ISOM_DECL_BOX_ALLOC(GF_MetaKeysBox, GF_ISOM_BOX_TYPE_KEYS);
1206
2.15k
  tmp->keys = gf_list_new();
1207
2.15k
  return (GF_Box *)tmp;
1208
2.15k
}
1209
1210
#ifndef GPAC_DISABLE_ISOM_WRITE
1211
1212
GF_Err keys_box_write(GF_Box *s, GF_BitStream *bs)
1213
23
{
1214
23
  GF_Err e;
1215
23
  u32 i, nb_keys;
1216
23
  GF_MetaKeysBox *ptr = (GF_MetaKeysBox *)s;
1217
1218
23
  e = gf_isom_full_box_write(s, bs);
1219
23
  if (e) return e;
1220
23
  nb_keys = gf_list_count(ptr->keys);
1221
23
  gf_bs_write_u32(bs, nb_keys);
1222
135
  for (i=0; i<nb_keys; i++) {
1223
112
    GF_MetaKey *k = gf_list_get(ptr->keys, i);
1224
112
    gf_bs_write_u32(bs, k->size+8);
1225
112
    gf_bs_write_u32(bs, k->ns);
1226
112
    if (k->data)
1227
112
      gf_bs_write_data(bs, k->data, k->size);
1228
112
  }
1229
23
  return GF_OK;
1230
23
}
1231
1232
1233
GF_Err keys_box_size(GF_Box *s)
1234
23
{
1235
23
  u32 i, nb_keys;
1236
23
  GF_MetaKeysBox *ptr = (GF_MetaKeysBox *)s;
1237
23
  ptr->size += 4;
1238
23
  nb_keys = gf_list_count(ptr->keys);
1239
135
  for (i=0; i<nb_keys; i++) {
1240
112
    GF_MetaKey *k = gf_list_get(ptr->keys, i);
1241
112
    if (!k->data) k->size = 0;
1242
112
    ptr->size += 8 + k->size;
1243
112
  }
1244
23
  return GF_OK;
1245
23
}
1246
1247
#endif /*GPAC_DISABLE_ISOM_WRITE*/
1248
1249
#endif /*GPAC_DISABLE_ISOM*/