Coverage Report

Created: 2026-01-17 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpac/src/odf/odf_code.c
Line
Count
Source
1
/*
2
 *      GPAC - Multimedia Framework C SDK
3
 *
4
 *      Authors: Jean Le Feuvre
5
 *      Copyright (c) Telecom ParisTech 2000-2019
6
 *          All rights reserved
7
 *
8
 *  This file is part of GPAC / MPEG-4 ObjectDescriptor 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/odf_dev.h>
27
#include <gpac/utf.h>
28
29
#define DATE_CODING_LEN 5
30
31
#ifndef GPAC_MINIMAL_ODF
32
33
static GFINLINE GF_Err OD_ReadUTF8String(GF_BitStream *bs, char **string, Bool isUTF8, u32 *read)
34
{
35
  u32 len;
36
  *read = 1;
37
  len = gf_bs_read_int(bs, 8) + 1;
38
  if (gf_bs_available(bs) < len) return GF_BAD_PARAM;
39
  if (!isUTF8) len *= 2;
40
  (*string) = (char *) gf_malloc(sizeof(char)*len);
41
  if (! (*string) ) return GF_OUT_OF_MEM;
42
  gf_bs_read_data(bs, (*string), len);
43
  *read += len;
44
  return GF_OK;
45
}
46
47
static GFINLINE u32 OD_SizeUTF8String(char *string, Bool isUTF8)
48
{
49
  if (isUTF8) return 1 + (u32) strlen(string);
50
  return 1 + 2 * gf_utf8_wcslen((const unsigned short *)string);
51
}
52
53
static GFINLINE void OD_WriteUTF8String(GF_BitStream *bs, char *string, Bool isUTF8)
54
{
55
  u32 len;
56
  if (isUTF8) {
57
    len = (u32) strlen(string);
58
    gf_bs_write_int(bs, len, 8);
59
    gf_bs_write_data(bs, string, len);
60
  } else {
61
    len = gf_utf8_wcslen((const unsigned short *)string);
62
    gf_bs_write_int(bs, len, 8);
63
    gf_bs_write_data(bs, string, len*2);
64
  }
65
}
66
67
#endif // GPAC_MINIMAL_ODF
68
69
/*use to parse strings read the length as well - Warning : the alloc is done here !!*/
70
GF_Err gf_odf_read_url_string(GF_BitStream *bs, char **string, u32 *readBytes)
71
13.6k
{
72
13.6k
  u32 length;
73
13.6k
  *readBytes = 0;
74
75
  /*if the string is not NULL, return an error...*/
76
13.6k
  if (*string != NULL) return GF_BAD_PARAM;
77
78
  /*the len is always on 8 bits*/
79
13.6k
  length = gf_bs_read_int(bs, 8);
80
13.6k
  *readBytes = 1;
81
  /*JLF AMD to MPEG-4 systems :) - This is not conformant at all, just hoping MPEG will accept it soon
82
  since 255bytes URL is a real pain in the neck*/
83
13.6k
  if (!length) {
84
6.05k
    length = gf_bs_read_int(bs, 32);
85
6.05k
    *readBytes += 4;
86
6.05k
    if (length>0xFFFF) return GF_ODF_INVALID_DESCRIPTOR;
87
6.05k
  }
88
  /*we want to use strlen to get rid of "stringLength" => we need an extra 0*/
89
11.0k
  (*string) = (char *) gf_malloc(length + 1);
90
11.0k
  if (! *string) return GF_OUT_OF_MEM;
91
11.0k
  gf_bs_read_data(bs, (*string), length);
92
11.0k
  *readBytes += length;
93
11.0k
  (*string)[length] = 0;
94
11.0k
  return GF_OK;
95
11.0k
}
96
97
/*writes string*/
98
GF_Err gf_odf_write_url_string(GF_BitStream *bs, char *string)
99
1.70k
{
100
1.70k
  u32 len;
101
  /*we accept NULL strings now*/
102
1.70k
  if (!string) {
103
0
    gf_bs_write_int(bs, 0, 8);
104
0
    return GF_OK;
105
0
  }
106
1.70k
  len = (u32) strlen(string);
107
1.70k
  if (len > 255) {
108
0
    gf_bs_write_int(bs, 0, 8);
109
0
    gf_bs_write_int(bs, len, 32);
110
1.70k
  } else {
111
1.70k
    gf_bs_write_int(bs, len, 8);
112
1.70k
  }
113
1.70k
  gf_bs_write_data(bs, string, len);
114
1.70k
  return GF_OK;
115
1.70k
}
116
117
u32 gf_odf_size_url_string(char *string)
118
1.70k
{
119
1.70k
  u32 len = (u32) strlen(string);
120
1.70k
  if (len>255) return len+5;
121
1.70k
  return len+1;
122
1.70k
}
123
124
GF_Descriptor *gf_odf_new_esd()
125
40.9k
{
126
40.9k
  GF_ESD *newDesc = (GF_ESD *) gf_malloc(sizeof(GF_ESD));
127
40.9k
  if (!newDesc) return NULL;
128
40.9k
  memset(newDesc, 0, sizeof(GF_ESD));
129
40.9k
  newDesc->IPIDataSet = gf_list_new();
130
40.9k
  newDesc->IPMPDescriptorPointers = gf_list_new();
131
40.9k
  newDesc->extensionDescriptors = gf_list_new();
132
40.9k
  newDesc->tag = GF_ODF_ESD_TAG;
133
40.9k
  return (GF_Descriptor *) newDesc;
134
40.9k
}
135
136
137
GF_Err gf_odf_del_esd(GF_ESD *esd)
138
40.9k
{
139
40.9k
  GF_Err e;
140
40.9k
  if (!esd) return GF_BAD_PARAM;
141
40.9k
  if (esd->URLString)  gf_free(esd->URLString);
142
143
40.9k
  if (esd->decoderConfig)  {
144
15.2k
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->decoderConfig);
145
15.2k
    if (e) return e;
146
15.2k
  }
147
40.9k
  if (esd->slConfig) {
148
21.7k
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->slConfig);
149
21.7k
    if (e) return e;
150
21.7k
  }
151
40.9k
  if (esd->ipiPtr) {
152
0
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->ipiPtr);
153
0
    if (e) return e;
154
0
  }
155
40.9k
  if (esd->qos) {
156
0
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->qos);
157
0
    if (e) return e;
158
0
  }
159
40.9k
  if (esd->RegDescriptor)  {
160
0
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->RegDescriptor);
161
0
    if (e) return e;
162
0
  }
163
40.9k
  if (esd->langDesc)  {
164
2.87k
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->langDesc);
165
2.87k
    if (e) return e;
166
2.87k
  }
167
168
40.9k
  e = gf_odf_delete_descriptor_list(esd->IPIDataSet);
169
40.9k
  if (e) return e;
170
40.9k
  e = gf_odf_delete_descriptor_list(esd->IPMPDescriptorPointers);
171
40.9k
  if (e) return e;
172
40.9k
  e = gf_odf_delete_descriptor_list(esd->extensionDescriptors);
173
40.9k
  if (e) return e;
174
40.9k
  gf_free(esd);
175
40.9k
  return GF_OK;
176
40.9k
}
177
178
179
GF_Err AddDescriptorToESD(GF_ESD *esd, GF_Descriptor *desc)
180
46.2k
{
181
46.2k
  if (!esd || !desc) return GF_BAD_PARAM;
182
183
46.2k
  switch (desc->tag) {
184
1.17k
  case GF_ODF_DCD_TAG:
185
1.17k
    if (esd->decoderConfig) return GF_ODF_INVALID_DESCRIPTOR;
186
752
    esd->decoderConfig = (GF_DecoderConfig *) desc;
187
752
    break;
188
189
5.38k
  case GF_ODF_SLC_TAG:
190
5.38k
    if (esd->slConfig) return GF_ODF_INVALID_DESCRIPTOR;
191
3.35k
    esd->slConfig = (GF_SLConfig *) desc;
192
3.35k
    break;
193
194
0
  case GF_ODF_MUXINFO_TAG:
195
0
    gf_list_add(esd->extensionDescriptors, desc);
196
0
    break;
197
198
3.48k
  case GF_ODF_LANG_TAG:
199
3.48k
    if (esd->langDesc) return GF_ODF_INVALID_DESCRIPTOR;
200
2.87k
    esd->langDesc = (GF_Language *) desc;
201
2.87k
    break;
202
203
#ifndef GPAC_MINIMAL_ODF
204
  //the GF_ODF_ISOM_IPI_PTR_TAG is only used in the file format and replaces GF_ODF_IPI_PTR_TAG...
205
  case GF_ODF_ISOM_IPI_PTR_TAG:
206
  case GF_ODF_IPI_PTR_TAG:
207
    if (esd->ipiPtr) return GF_ODF_INVALID_DESCRIPTOR;
208
    esd->ipiPtr = (GF_IPIPtr *) desc;
209
    break;
210
211
  case GF_ODF_QOS_TAG:
212
    if (esd->qos) return GF_ODF_INVALID_DESCRIPTOR;
213
    esd->qos  =(GF_QoS_Descriptor *) desc;
214
    break;
215
216
  case GF_ODF_CI_TAG:
217
  case GF_ODF_SCI_TAG:
218
    return gf_list_add(esd->IPIDataSet, desc);
219
220
  //we use the same struct for v1 and v2 IPMP DPs
221
  case GF_ODF_IPMP_PTR_TAG:
222
    return gf_list_add(esd->IPMPDescriptorPointers, desc);
223
224
  case GF_ODF_REG_TAG:
225
    if (esd->RegDescriptor) return GF_ODF_INVALID_DESCRIPTOR;
226
    esd->RegDescriptor =(GF_Registration *) desc;
227
    break;
228
#endif
229
230
36.2k
  default:
231
36.2k
    if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
232
17.4k
            (desc->tag <= GF_ODF_EXT_END_TAG) ) {
233
15.7k
      return gf_list_add(esd->extensionDescriptors, desc);
234
15.7k
    }
235
20.5k
    return GF_BAD_PARAM;
236
46.2k
  }
237
238
6.98k
  return GF_OK;
239
46.2k
}
240
241
GF_Err gf_odf_read_esd(GF_BitStream *bs, GF_ESD *esd, u32 DescSize)
242
26.4k
{
243
26.4k
  GF_Err e = GF_OK;
244
26.4k
  u32 ocrflag, urlflag, streamdependflag, tmp_size, nbBytes, read;
245
246
26.4k
  if (! esd) return GF_BAD_PARAM;
247
248
26.4k
  nbBytes = 0;
249
250
26.4k
  esd->ESID = gf_bs_read_int(bs, 16);
251
26.4k
  streamdependflag = gf_bs_read_int(bs, 1);
252
26.4k
  urlflag = gf_bs_read_int(bs, 1);
253
26.4k
  ocrflag = gf_bs_read_int(bs, 1);
254
26.4k
  esd->streamPriority = gf_bs_read_int(bs, 5);
255
26.4k
  nbBytes += 3;
256
257
26.4k
  if (streamdependflag) {
258
9.20k
    esd->dependsOnESID = gf_bs_read_int(bs, 16);
259
9.20k
    nbBytes += 2;
260
9.20k
  }
261
262
26.4k
  if (urlflag) {
263
4.96k
    e = gf_odf_read_url_string(bs, & esd->URLString, &read);
264
4.96k
    if (e) return e;
265
3.72k
    nbBytes += read;
266
3.72k
  }
267
25.2k
  if (ocrflag) {
268
11.6k
    esd->OCRESID = gf_bs_read_int(bs, 16);
269
11.6k
    nbBytes += 2;
270
11.6k
  }
271
272
41.5k
  while (nbBytes < DescSize) {
273
29.2k
    GF_Descriptor *tmp = NULL;
274
29.2k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
275
    /*fix for iPod files*/
276
29.2k
    if (e==GF_ODF_INVALID_DESCRIPTOR) {
277
9.59k
      nbBytes += tmp_size;
278
9.59k
      if (nbBytes>DescSize) return e;
279
8.12k
      gf_bs_read_int(bs, DescSize-nbBytes);
280
8.12k
      return GF_OK;
281
9.59k
    }
282
19.6k
    if (e) return e;
283
18.2k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
284
18.2k
    e = AddDescriptorToESD(esd, tmp);
285
18.2k
    if (e) {
286
1.92k
      gf_odf_desc_del(tmp);
287
1.92k
      return e;
288
1.92k
    }
289
16.3k
    nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
290
291
    //apple fix
292
16.3k
    if (!tmp_size) nbBytes = DescSize;
293
294
16.3k
  }
295
12.2k
  if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
296
10.7k
  return e;
297
298
12.2k
}
299
300
GF_Err gf_odf_size_esd(GF_ESD *esd, u32 *outSize)
301
4.91k
{
302
4.91k
  GF_Err e;
303
4.91k
  u32 tmpSize;
304
4.91k
  if (! esd) return GF_BAD_PARAM;
305
306
4.91k
  *outSize = 0;
307
4.91k
  *outSize += 3;
308
309
4.91k
  if (esd->dependsOnESID) *outSize += 2;
310
4.91k
  if (esd->URLString) *outSize += gf_odf_size_url_string(esd->URLString);
311
4.91k
  if (esd->OCRESID) *outSize += 2;
312
313
4.91k
  if (esd->decoderConfig) {
314
183
    e = gf_odf_size_descriptor((GF_Descriptor *) esd->decoderConfig, &tmpSize);
315
183
    if (e) return e;
316
183
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
317
183
  }
318
4.91k
  if (esd->slConfig) {
319
1.37k
    e = gf_odf_size_descriptor((GF_Descriptor *) esd->slConfig, &tmpSize);
320
1.37k
    if (e) return e;
321
1.37k
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
322
1.37k
  }
323
4.91k
  if (esd->ipiPtr) {
324
0
    e = gf_odf_size_descriptor((GF_Descriptor *) esd->ipiPtr, &tmpSize);
325
0
    if (e) return e;
326
0
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
327
0
  }
328
4.91k
  if (esd->langDesc) {
329
642
    e = gf_odf_size_descriptor((GF_Descriptor *) esd->langDesc, &tmpSize);
330
642
    if (e) return e;
331
642
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
332
642
  }
333
334
4.91k
  e = gf_odf_size_descriptor_list(esd->IPIDataSet, outSize);
335
4.91k
  if (e) return e;
336
4.91k
  e = gf_odf_size_descriptor_list(esd->IPMPDescriptorPointers, outSize);
337
4.91k
  if (e) return e;
338
4.91k
  if (esd->qos) {
339
0
    e = gf_odf_size_descriptor((GF_Descriptor *) esd->qos, &tmpSize);
340
0
    if (e) return e;
341
0
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
342
0
  }
343
4.91k
  if (esd->RegDescriptor) {
344
0
    e = gf_odf_size_descriptor((GF_Descriptor *) esd->RegDescriptor, &tmpSize);
345
0
    if (e) return e;
346
0
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
347
0
  }
348
4.91k
  return gf_odf_size_descriptor_list(esd->extensionDescriptors, outSize);
349
4.91k
}
350
351
GF_Err gf_odf_write_esd(GF_BitStream *bs, GF_ESD *esd)
352
4.81k
{
353
4.81k
  GF_Err e;
354
4.81k
  u32 size;
355
4.81k
  if (! esd) return GF_BAD_PARAM;
356
357
4.81k
  e = gf_odf_size_descriptor((GF_Descriptor *)esd, &size);
358
4.81k
  if (e) return e;
359
4.81k
  e = gf_odf_write_base_descriptor(bs, esd->tag, size);
360
4.81k
  if (e) return e;
361
362
4.81k
  gf_bs_write_int(bs, esd->ESID, 16);
363
4.81k
  gf_bs_write_int(bs, esd->dependsOnESID ? 1 : 0, 1);
364
4.81k
  gf_bs_write_int(bs, esd->URLString != NULL ? 1 : 0, 1);
365
4.81k
  gf_bs_write_int(bs, esd->OCRESID ? 1 : 0, 1);
366
4.81k
  gf_bs_write_int(bs, esd->streamPriority, 5);
367
368
4.81k
  if (esd->dependsOnESID) {
369
2.55k
    gf_bs_write_int(bs, esd->dependsOnESID, 16);
370
2.55k
  }
371
4.81k
  if (esd->URLString) {
372
742
    e = gf_odf_write_url_string(bs, esd->URLString);
373
742
    if (e) return e;
374
742
  }
375
376
377
4.81k
  if (esd->OCRESID) {
378
3.15k
    gf_bs_write_int(bs, esd->OCRESID, 16);
379
3.15k
  }
380
4.81k
  if (esd->decoderConfig) {
381
183
    e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->decoderConfig);
382
183
    if (e) return e;
383
183
  }
384
4.81k
  if (esd->slConfig) {
385
1.28k
    e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->slConfig);
386
1.28k
    if (e) return e;
387
1.28k
  }
388
4.81k
  if (esd->ipiPtr) {
389
0
    e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->ipiPtr);
390
0
    if (e) return e;
391
0
  }
392
4.81k
  if (esd->langDesc) {
393
642
    e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->langDesc);
394
642
    if (e) return e;
395
642
  }
396
397
4.81k
  e = gf_odf_write_descriptor_list(bs, esd->IPIDataSet);
398
4.81k
  if (e) return e;
399
4.81k
  e = gf_odf_write_descriptor_list(bs, esd->IPMPDescriptorPointers);
400
4.81k
  if (e) return e;
401
4.81k
  if (esd->qos) {
402
0
    e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->qos);
403
0
    if (e) return e;
404
0
  }
405
4.81k
  if (esd->RegDescriptor) {
406
0
    e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->RegDescriptor);
407
0
    if (e) return e;
408
0
  }
409
4.81k
  return gf_odf_write_descriptor_list(bs, esd->extensionDescriptors);
410
4.81k
}
411
412
GF_Descriptor *gf_odf_new_iod()
413
7.56k
{
414
7.56k
  GF_InitialObjectDescriptor *newDesc = (GF_InitialObjectDescriptor *) gf_malloc(sizeof(GF_InitialObjectDescriptor));
415
7.56k
  if (!newDesc) return NULL;
416
7.56k
  memset(newDesc, 0, sizeof(GF_InitialObjectDescriptor));
417
418
7.56k
  newDesc->ESDescriptors = gf_list_new();
419
7.56k
  newDesc->OCIDescriptors = gf_list_new();
420
7.56k
  newDesc->IPMP_Descriptors = gf_list_new();
421
422
7.56k
  newDesc->extensionDescriptors = gf_list_new();
423
7.56k
  newDesc->tag = GF_ODF_IOD_TAG;
424
7.56k
  return (GF_Descriptor *) newDesc;
425
7.56k
}
426
427
GF_Err gf_odf_del_iod(GF_InitialObjectDescriptor *iod)
428
7.56k
{
429
7.56k
  GF_Err e;
430
7.56k
  if (!iod) return GF_BAD_PARAM;
431
7.56k
  if (iod->URLString)  gf_free(iod->URLString);
432
7.56k
  e = gf_odf_delete_descriptor_list(iod->ESDescriptors);
433
7.56k
  if (e) return e;
434
7.56k
  e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
435
7.56k
  if (e) return e;
436
7.56k
  e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
437
7.56k
  if (e) return e;
438
7.56k
  e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
439
7.56k
  if (e) return e;
440
7.56k
  if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList);
441
7.56k
  gf_free(iod);
442
7.56k
  return GF_OK;
443
7.56k
}
444
445
GF_Err AddDescriptorToIOD(GF_InitialObjectDescriptor *iod, GF_Descriptor *desc)
446
11.0k
{
447
11.0k
  if (!iod || !desc) return GF_BAD_PARAM;
448
449
11.0k
  switch (desc->tag) {
450
262
  case GF_ODF_ESD_TAG:
451
262
    return gf_list_add(iod->ESDescriptors, desc);
452
453
  //we use the same struct for v1 and v2 IPMP DPs
454
284
  case GF_ODF_IPMP_PTR_TAG:
455
  /*IPMPX*/
456
1.21k
  case GF_ODF_IPMP_TAG:
457
1.21k
    return gf_list_add(iod->IPMP_Descriptors, desc);
458
459
  /*IPMPX*/
460
2.05k
  case GF_ODF_IPMP_TL_TAG:
461
2.05k
    if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
462
2.05k
    iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
463
2.05k
    return GF_OK;
464
465
7.50k
  default:
466
7.50k
    break;
467
11.0k
  }
468
7.50k
  if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) && (desc->tag <= GF_ODF_OCI_END_TAG) ) return gf_list_add(iod->OCIDescriptors, desc);
469
4.80k
  if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG) ) return gf_list_add(iod->extensionDescriptors, desc);
470
858
  return GF_BAD_PARAM;
471
4.80k
}
472
473
GF_Err gf_odf_read_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod, u32 DescSize)
474
7.56k
{
475
7.56k
  GF_Err e;
476
7.56k
  u32 urlflag, read;
477
7.56k
  u32 tmp_size, nbBytes = 0;
478
7.56k
  if (! iod) return GF_BAD_PARAM;
479
480
7.56k
  iod->objectDescriptorID = gf_bs_read_int(bs, 10);
481
7.56k
  urlflag = gf_bs_read_int(bs, 1);
482
7.56k
  iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
483
7.56k
  /*reserved = */gf_bs_read_int(bs, 4);
484
7.56k
  nbBytes += 2;
485
486
7.56k
  if (urlflag) {
487
1.73k
    e = gf_odf_read_url_string(bs, & iod->URLString, &read);
488
1.73k
    if (e) return e;
489
1.20k
    nbBytes += read;
490
5.83k
  } else {
491
5.83k
    iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
492
5.83k
    iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
493
5.83k
    iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
494
5.83k
    iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
495
5.83k
    iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
496
5.83k
    nbBytes += 5;
497
5.83k
  }
498
499
17.2k
  while (nbBytes < DescSize) {
500
13.9k
    GF_Descriptor *tmp = NULL;
501
13.9k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
502
13.9k
    if (e) return e;
503
11.0k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
504
11.0k
    e = AddDescriptorToIOD(iod, tmp);
505
11.0k
    if (e) {
506
858
      gf_odf_delete_descriptor(tmp);
507
858
      return e;
508
858
    }
509
10.1k
    nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
510
10.1k
  }
511
3.27k
  if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
512
2.20k
  return GF_OK;
513
3.27k
}
514
515
GF_Err gf_odf_size_iod(GF_InitialObjectDescriptor *iod, u32 *outSize)
516
986
{
517
986
  GF_Err e;
518
986
  if (! iod) return GF_BAD_PARAM;
519
520
986
  *outSize = 0;
521
986
  *outSize += 2;
522
986
  if (iod->URLString) {
523
232
    *outSize += gf_odf_size_url_string(iod->URLString);
524
754
  } else {
525
754
    *outSize += 5;
526
754
    e = gf_odf_size_descriptor_list(iod->ESDescriptors, outSize);
527
754
    if (e) return e;
528
754
    e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
529
754
    if (e) return e;
530
754
    e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
531
754
    if (e) return e;
532
533
754
  }
534
986
  e = gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
535
986
  if (e) return e;
536
986
  if (iod->IPMPToolList) {
537
393
    u32 tmpSize;
538
393
    e = gf_odf_size_descriptor((GF_Descriptor *) iod->IPMPToolList, &tmpSize);
539
393
    if (e) return e;
540
393
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
541
393
  }
542
986
  return GF_OK;
543
986
}
544
545
GF_Err gf_odf_write_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod)
546
986
{
547
986
  GF_Err e;
548
986
  u32 size;
549
986
  if (! iod) return GF_BAD_PARAM;
550
551
986
  e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
552
986
  if (e) return e;
553
986
  e = gf_odf_write_base_descriptor(bs, iod->tag, size);
554
986
  if (e) return e;
555
556
986
  gf_bs_write_int(bs, iod->objectDescriptorID, 10);
557
986
  gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
558
986
  gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
559
986
  gf_bs_write_int(bs, 15, 4);   //reserved: 0b1111 == 15
560
561
986
  if (iod->URLString) {
562
232
    gf_odf_write_url_string(bs, iod->URLString);
563
754
  } else {
564
754
    gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
565
754
    gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
566
754
    gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
567
754
    gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
568
754
    gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
569
754
    e = gf_odf_write_descriptor_list(bs, iod->ESDescriptors);
570
754
    if (e) return e;
571
754
    e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
572
754
    if (e) return e;
573
754
    e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
574
754
    if (e) return e;
575
754
    e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
576
754
    if (e) return e;
577
754
    if (iod->IPMPToolList) {
578
393
      e = gf_odf_write_descriptor(bs, (GF_Descriptor *) iod->IPMPToolList);
579
393
      if (e) return e;
580
393
    }
581
754
  }
582
986
  return gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
583
986
}
584
585
586
587
GF_Descriptor *gf_odf_new_od()
588
5.72k
{
589
5.72k
  GF_ObjectDescriptor *newDesc;
590
5.72k
  GF_SAFEALLOC(newDesc, GF_ObjectDescriptor);
591
5.72k
  if (!newDesc) return NULL;
592
593
5.72k
  newDesc->URLString = NULL;
594
5.72k
  newDesc->ESDescriptors = gf_list_new();
595
5.72k
  newDesc->OCIDescriptors = gf_list_new();
596
5.72k
  newDesc->IPMP_Descriptors = gf_list_new();
597
5.72k
  newDesc->extensionDescriptors = gf_list_new();
598
5.72k
  newDesc->objectDescriptorID = 0;
599
5.72k
  newDesc->tag = GF_ODF_OD_TAG;
600
5.72k
  return (GF_Descriptor *) newDesc;
601
5.72k
}
602
603
GF_Err gf_odf_del_od(GF_ObjectDescriptor *od)
604
5.72k
{
605
5.72k
  GF_Err e;
606
5.72k
  if (!od) return GF_BAD_PARAM;
607
5.72k
  if (od->URLString)  gf_free(od->URLString);
608
5.72k
  e = gf_odf_delete_descriptor_list(od->ESDescriptors);
609
5.72k
  if (e) return e;
610
5.72k
  e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
611
5.72k
  if (e) return e;
612
5.72k
  e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
613
5.72k
  if (e) return e;
614
5.72k
  e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
615
5.72k
  if (e) return e;
616
5.72k
  gf_free(od);
617
5.72k
  return GF_OK;
618
5.72k
}
619
620
GF_Err AddDescriptorToOD(GF_ObjectDescriptor *od, GF_Descriptor *desc)
621
6.91k
{
622
6.91k
  if (!od || !desc) return GF_BAD_PARAM;
623
624
  //check if we can handle ContentClassif tags
625
6.91k
  if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
626
1.89k
          (desc->tag <= GF_ODF_OCI_END_TAG) ) {
627
229
    return gf_list_add(od->OCIDescriptors, desc);
628
229
  }
629
630
  //or extensions
631
6.68k
  if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
632
1.66k
          (desc->tag <= GF_ODF_EXT_END_TAG) ) {
633
1.43k
    return gf_list_add(od->extensionDescriptors, desc);
634
1.43k
  }
635
636
  //to cope with envivio
637
5.24k
  switch (desc->tag) {
638
2.30k
  case GF_ODF_ESD_TAG:
639
2.79k
  case GF_ODF_ESD_REF_TAG:
640
2.79k
    return gf_list_add(od->ESDescriptors, desc);
641
642
  //we use the same struct for v1 and v2 IPMP DPs
643
1.64k
  case GF_ODF_IPMP_PTR_TAG:
644
1.95k
  case GF_ODF_IPMP_TAG:
645
1.95k
    return gf_list_add(od->IPMP_Descriptors, desc);
646
647
500
  default:
648
500
    return GF_BAD_PARAM;
649
5.24k
  }
650
5.24k
}
651
652
GF_Err gf_odf_read_od(GF_BitStream *bs, GF_ObjectDescriptor *od, u32 DescSize)
653
5.72k
{
654
5.72k
  GF_Err e;
655
5.72k
  u32 urlflag;
656
5.72k
  u32 tmpSize, nbBytes = 0;
657
5.72k
  if (! od) return GF_BAD_PARAM;
658
659
5.72k
  od->objectDescriptorID = gf_bs_read_int(bs, 10);
660
5.72k
  urlflag = gf_bs_read_int(bs, 1);
661
5.72k
  /*reserved = */gf_bs_read_int(bs, 5);
662
5.72k
  nbBytes += 2;
663
664
5.72k
  if (urlflag) {
665
2.34k
    u32 read;
666
2.34k
    e = gf_odf_read_url_string(bs, & od->URLString, &read);
667
2.34k
    if (e) return e;
668
1.93k
    nbBytes += read;
669
1.93k
  }
670
671
11.7k
  while (nbBytes < DescSize) {
672
7.46k
    GF_Descriptor *tmp = NULL;
673
7.46k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
674
7.46k
    if (e) return e;
675
6.91k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
676
6.91k
    e = AddDescriptorToOD(od, tmp);
677
6.91k
    if (e) {
678
500
      gf_odf_desc_del(tmp);
679
500
      return e;
680
500
    }
681
6.41k
    nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
682
6.41k
  }
683
4.25k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
684
2.18k
  return GF_OK;
685
4.25k
}
686
687
GF_Err gf_odf_size_od(GF_ObjectDescriptor *od, u32 *outSize)
688
1.22k
{
689
1.22k
  GF_Err e;
690
1.22k
  if (! od) return GF_BAD_PARAM;
691
692
1.22k
  *outSize = 2;
693
1.22k
  if (od->URLString) {
694
227
    *outSize += gf_odf_size_url_string(od->URLString);
695
996
  } else {
696
996
    e = gf_odf_size_descriptor_list(od->ESDescriptors, outSize);
697
996
    if (e) return e;
698
996
    e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
699
996
    if (e) return e;
700
996
    e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
701
996
    if (e) return e;
702
996
  }
703
1.22k
  return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
704
1.22k
}
705
706
GF_Err gf_odf_write_od(GF_BitStream *bs, GF_ObjectDescriptor *od)
707
1.22k
{
708
1.22k
  GF_Err e;
709
1.22k
  u32 size;
710
1.22k
  if (! od) return GF_BAD_PARAM;
711
712
1.22k
  e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
713
1.22k
  if (e) return e;
714
1.22k
  e = gf_odf_write_base_descriptor(bs, od->tag, size);
715
1.22k
  if (e) return e;
716
717
1.22k
  gf_bs_write_int(bs, od->objectDescriptorID, 10);
718
1.22k
  gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
719
1.22k
  gf_bs_write_int(bs, 31, 5);   //reserved: 0b1111.1 == 31
720
721
1.22k
  if (od->URLString) {
722
227
    gf_odf_write_url_string(bs, od->URLString);
723
996
  } else {
724
996
    e = gf_odf_write_descriptor_list(bs, od->ESDescriptors);
725
996
    if (e) return e;
726
996
    e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
727
996
    if (e) return e;
728
996
    e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
729
996
    if (e) return e;
730
996
    e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
731
996
    if (e) return e;
732
996
  }
733
1.22k
  return gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
734
1.22k
}
735
736
GF_Descriptor *gf_odf_new_isom_iod()
737
5.66k
{
738
5.66k
  GF_IsomInitialObjectDescriptor *newDesc = (GF_IsomInitialObjectDescriptor *) gf_malloc(sizeof(GF_IsomInitialObjectDescriptor));
739
5.66k
  if (!newDesc) return NULL;
740
5.66k
  memset(newDesc, 0, sizeof(GF_IsomInitialObjectDescriptor));
741
742
5.66k
  newDesc->ES_ID_IncDescriptors = gf_list_new();
743
5.66k
  newDesc->ES_ID_RefDescriptors = gf_list_new();
744
5.66k
  newDesc->OCIDescriptors = gf_list_new();
745
5.66k
  newDesc->IPMP_Descriptors = gf_list_new();
746
5.66k
  newDesc->extensionDescriptors = gf_list_new();
747
5.66k
  newDesc->tag = GF_ODF_ISOM_IOD_TAG;
748
749
  //by default create an IOD with no inline and no capabilities
750
5.66k
  newDesc->audio_profileAndLevel = 0xFF;
751
5.66k
  newDesc->graphics_profileAndLevel = 0xFF;
752
5.66k
  newDesc->scene_profileAndLevel = 0xFF;
753
5.66k
  newDesc->OD_profileAndLevel = 0xFF;
754
5.66k
  newDesc->visual_profileAndLevel = 0xFF;
755
5.66k
  return (GF_Descriptor *) newDesc;
756
5.66k
}
757
758
GF_Err gf_odf_del_isom_iod(GF_IsomInitialObjectDescriptor *iod)
759
5.66k
{
760
5.66k
  GF_Err e;
761
5.66k
  if (!iod) return GF_BAD_PARAM;
762
5.66k
  if (iod->URLString)  gf_free(iod->URLString);
763
5.66k
  e = gf_odf_delete_descriptor_list(iod->ES_ID_IncDescriptors);
764
5.66k
  if (e) return e;
765
5.66k
  e = gf_odf_delete_descriptor_list(iod->ES_ID_RefDescriptors);
766
5.66k
  if (e) return e;
767
5.66k
  e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
768
5.66k
  if (e) return e;
769
5.66k
  e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
770
5.66k
  if (e) return e;
771
5.66k
  e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
772
5.66k
  if (e) return e;
773
5.66k
  if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList);
774
5.66k
  gf_free(iod);
775
5.66k
  return GF_OK;
776
5.66k
}
777
778
GF_Err AddDescriptorToIsomIOD(GF_IsomInitialObjectDescriptor *iod, GF_Descriptor *desc)
779
11.9k
{
780
11.9k
  if (!iod || !desc) return GF_BAD_PARAM;
781
782
11.9k
  switch (desc->tag) {
783
344
  case GF_ODF_ESD_TAG:
784
344
    return GF_ODF_FORBIDDEN_DESCRIPTOR;
785
786
798
  case GF_ODF_ESD_INC_TAG:
787
    //there shouldn't be ref if inc
788
798
    if (gf_list_count(iod->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
789
423
    return gf_list_add(iod->ES_ID_IncDescriptors, desc);
790
791
966
  case GF_ODF_ESD_REF_TAG:
792
    //there shouldn't be inc if ref
793
966
    if (gf_list_count(iod->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
794
742
    return gf_list_add(iod->ES_ID_RefDescriptors, desc);
795
796
  //we use the same struct for v1 and v2 IPMP DPs
797
244
  case GF_ODF_IPMP_PTR_TAG:
798
1.57k
  case GF_ODF_IPMP_TAG:
799
1.57k
    return gf_list_add(iod->IPMP_Descriptors, desc);
800
801
  /*IPMPX*/
802
1.53k
  case GF_ODF_IPMP_TL_TAG:
803
1.53k
    if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
804
1.53k
    iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
805
1.53k
    return GF_OK;
806
807
6.70k
  default:
808
6.70k
    break;
809
11.9k
  }
810
  //check if we can handle ContentClassif tags
811
6.70k
  if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) && (desc->tag <= GF_ODF_OCI_END_TAG) ) return gf_list_add(iod->OCIDescriptors, desc);
812
  //or extensions
813
5.04k
  if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG) ) return gf_list_add(iod->extensionDescriptors, desc);
814
950
  return GF_BAD_PARAM;
815
5.04k
}
816
817
GF_Err gf_odf_read_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod, u32 DescSize)
818
5.66k
{
819
5.66k
  u32 nbBytes = 0, tmpSize;
820
5.66k
  u32 urlflag;
821
5.66k
  GF_Err e;
822
5.66k
  if (! iod) return GF_BAD_PARAM;
823
824
5.66k
  iod->objectDescriptorID = gf_bs_read_int(bs, 10);
825
5.66k
  urlflag = gf_bs_read_int(bs, 1);
826
5.66k
  iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
827
5.66k
  /*reserved = */gf_bs_read_int(bs, 4);
828
5.66k
  nbBytes += 2;
829
830
5.66k
  if (urlflag) {
831
2.13k
    u32 read;
832
2.13k
    e = gf_odf_read_url_string(bs, & iod->URLString, &read);
833
2.13k
    if (e) return e;
834
1.81k
    nbBytes += read;
835
3.53k
  } else {
836
3.53k
    iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
837
3.53k
    iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
838
3.53k
    iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
839
3.53k
    iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
840
3.53k
    iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
841
3.53k
    nbBytes += 5;
842
3.53k
  }
843
844
15.3k
  while (nbBytes < DescSize) {
845
12.7k
    GF_Descriptor *tmp = NULL;
846
12.7k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
847
12.7k
    if (e) {
848
840
      if (tmp) gf_odf_desc_del((GF_Descriptor *) tmp);
849
840
      return e;
850
840
    }
851
11.9k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
852
11.9k
    e = AddDescriptorToIsomIOD(iod, tmp);
853
11.9k
    if (e) {
854
1.89k
      gf_odf_desc_del(tmp);
855
1.89k
      return e;
856
1.89k
    }
857
10.0k
    nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
858
10.0k
  }
859
2.61k
  if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
860
1.75k
  return GF_OK;
861
2.61k
}
862
863
GF_Err gf_odf_size_isom_iod(GF_IsomInitialObjectDescriptor *iod, u32 *outSize)
864
857
{
865
857
  GF_Err e;
866
857
  if (! iod) return GF_BAD_PARAM;
867
868
857
  *outSize = 2;
869
857
  if (iod->URLString) {
870
121
    *outSize += gf_odf_size_url_string(iod->URLString);
871
736
  } else {
872
736
    *outSize += 5;
873
736
    e = gf_odf_size_descriptor_list(iod->ES_ID_IncDescriptors, outSize);
874
736
    if (e) return e;
875
736
    e = gf_odf_size_descriptor_list(iod->ES_ID_RefDescriptors, outSize);
876
736
    if (e) return e;
877
736
    e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
878
736
    if (e) return e;
879
736
    e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
880
736
    if (e) return e;
881
736
  }
882
857
  if (iod->IPMPToolList) {
883
483
    u32 tmpSize;
884
483
    e = gf_odf_size_descriptor((GF_Descriptor *) iod->IPMPToolList, &tmpSize);
885
483
    if (e) return e;
886
483
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
887
483
  }
888
857
  return gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
889
857
}
890
891
GF_Err gf_odf_write_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod)
892
857
{
893
857
  GF_Err e;
894
857
  u32 size;
895
857
  if (! iod) return GF_BAD_PARAM;
896
897
857
  e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
898
857
  if (e) return e;
899
857
  e = gf_odf_write_base_descriptor(bs, iod->tag, size);
900
857
  if (e) return e;
901
902
857
  gf_bs_write_int(bs, iod->objectDescriptorID, 10);
903
857
  gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
904
857
  gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
905
857
  gf_bs_write_int(bs, 15, 4);   //reserved: 0b1111 == 15
906
907
857
  if (iod->URLString) {
908
121
    gf_odf_write_url_string(bs, iod->URLString);
909
736
  } else {
910
736
    gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
911
736
    gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
912
736
    gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
913
736
    gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
914
736
    gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
915
736
    e = gf_odf_write_descriptor_list(bs, iod->ES_ID_IncDescriptors);
916
736
    if (e) return e;
917
736
    e = gf_odf_write_descriptor_list(bs, iod->ES_ID_RefDescriptors);
918
736
    if (e) return e;
919
736
    e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
920
736
    if (e) return e;
921
736
    e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
922
736
    if (e) return e;
923
736
    e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
924
736
    if (e) return e;
925
736
    if (iod->IPMPToolList) {
926
483
      e = gf_odf_write_descriptor(bs, (GF_Descriptor *) iod->IPMPToolList);
927
483
      if (e) return e;
928
483
    }
929
736
  }
930
857
  e = gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
931
857
  if (e) return e;
932
857
  return GF_OK;
933
857
}
934
935
936
GF_Descriptor *gf_odf_new_isom_od()
937
6.82k
{
938
6.82k
  GF_IsomObjectDescriptor *newDesc = (GF_IsomObjectDescriptor *) gf_malloc(sizeof(GF_IsomObjectDescriptor));
939
6.82k
  if (!newDesc) return NULL;
940
941
6.82k
  newDesc->URLString = NULL;
942
6.82k
  newDesc->ES_ID_IncDescriptors = gf_list_new();
943
6.82k
  newDesc->ES_ID_RefDescriptors = gf_list_new();
944
6.82k
  newDesc->OCIDescriptors = gf_list_new();
945
6.82k
  newDesc->IPMP_Descriptors = gf_list_new();
946
6.82k
  newDesc->extensionDescriptors = gf_list_new();
947
6.82k
  newDesc->objectDescriptorID = 0;
948
6.82k
  newDesc->tag = GF_ODF_ISOM_OD_TAG;
949
6.82k
  return (GF_Descriptor *) newDesc;
950
6.82k
}
951
952
GF_Err gf_odf_del_isom_od(GF_IsomObjectDescriptor *od)
953
6.82k
{
954
6.82k
  GF_Err e;
955
6.82k
  if (!od) return GF_BAD_PARAM;
956
6.82k
  if (od->URLString)  gf_free(od->URLString);
957
6.82k
  e = gf_odf_delete_descriptor_list(od->ES_ID_IncDescriptors);
958
6.82k
  if (e) return e;
959
6.82k
  e = gf_odf_delete_descriptor_list(od->ES_ID_RefDescriptors);
960
6.82k
  if (e) return e;
961
6.82k
  e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
962
6.82k
  if (e) return e;
963
6.82k
  e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
964
6.82k
  if (e) return e;
965
6.82k
  e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
966
6.82k
  if (e) return e;
967
6.82k
  gf_free(od);
968
6.82k
  return GF_OK;
969
6.82k
}
970
971
GF_Err AddDescriptorToIsomOD(GF_IsomObjectDescriptor *od, GF_Descriptor *desc)
972
4.40k
{
973
4.40k
  if (!od || !desc) return GF_BAD_PARAM;
974
975
  //check if we can handle ContentClassif tags
976
4.40k
  if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
977
2.06k
          (desc->tag <= GF_ODF_OCI_END_TAG) ) {
978
655
    return gf_list_add(od->OCIDescriptors, desc);
979
655
  }
980
981
  //or extension ...
982
3.75k
  if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
983
1.41k
          (desc->tag <= GF_ODF_EXT_END_TAG) ) {
984
1.20k
    return gf_list_add(od->extensionDescriptors, desc);
985
1.20k
  }
986
987
2.55k
  switch (desc->tag) {
988
306
  case GF_ODF_ESD_TAG:
989
306
    return GF_ODF_FORBIDDEN_DESCRIPTOR;
990
991
665
  case GF_ODF_ESD_INC_TAG:
992
    //there shouldn't be ref if inc
993
665
    if (gf_list_count(od->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
994
384
    return gf_list_add(od->ES_ID_IncDescriptors, desc);
995
996
548
  case GF_ODF_ESD_REF_TAG:
997
    //there shouldn't be inc if ref
998
548
    if (gf_list_count(od->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
999
298
    return gf_list_add(od->ES_ID_RefDescriptors, desc);
1000
1001
  //we use the same struct for v1 and v2 IPMP DPs
1002
142
  case GF_ODF_IPMP_PTR_TAG:
1003
571
  case GF_ODF_IPMP_TAG:
1004
571
    return gf_list_add(od->IPMP_Descriptors, desc);
1005
1006
463
  default:
1007
463
    return GF_BAD_PARAM;
1008
2.55k
  }
1009
2.55k
}
1010
1011
GF_Err gf_odf_read_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od, u32 DescSize)
1012
6.81k
{
1013
6.81k
  GF_Err e;
1014
6.81k
  u32 urlflag;
1015
6.81k
  u32 tmpSize, nbBytes = 0;
1016
6.81k
  if (! od) return GF_BAD_PARAM;
1017
1018
6.81k
  od->objectDescriptorID = gf_bs_read_int(bs, 10);
1019
6.81k
  urlflag = gf_bs_read_int(bs, 1);
1020
6.81k
  /*reserved = */gf_bs_read_int(bs, 5);
1021
6.81k
  nbBytes += 2;
1022
1023
6.81k
  if (urlflag) {
1024
2.42k
    u32 read;
1025
2.42k
    e = gf_odf_read_url_string(bs, & od->URLString, &read);
1026
2.42k
    if (e) return e;
1027
2.35k
    nbBytes += read;
1028
2.35k
  }
1029
1030
9.85k
  while (nbBytes < DescSize) {
1031
6.72k
    GF_Descriptor *tmp = NULL;
1032
6.72k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
1033
6.72k
    if (e) return e;
1034
4.40k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
1035
4.40k
    e = AddDescriptorToIsomOD(od, tmp);
1036
4.40k
    if (e) {
1037
1.30k
      gf_odf_delete_descriptor(tmp);
1038
1.30k
      return e;
1039
1.30k
    }
1040
3.10k
    nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
1041
3.10k
  }
1042
3.13k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1043
2.21k
  return GF_OK;
1044
3.13k
}
1045
1046
GF_Err gf_odf_size_isom_od(GF_IsomObjectDescriptor *od, u32 *outSize)
1047
627
{
1048
627
  GF_Err e;
1049
627
  if (! od) return GF_BAD_PARAM;
1050
1051
627
  *outSize = 2;
1052
627
  if (od->URLString) {
1053
378
    *outSize += gf_odf_size_url_string(od->URLString);
1054
378
  } else {
1055
249
    e = gf_odf_size_descriptor_list(od->ES_ID_IncDescriptors, outSize);
1056
249
    if (e) return e;
1057
249
    e = gf_odf_size_descriptor_list(od->ES_ID_RefDescriptors, outSize);
1058
249
    if (e) return e;
1059
249
    e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
1060
249
    if (e) return e;
1061
249
    e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
1062
249
    if (e) return e;
1063
249
  }
1064
627
  return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
1065
627
}
1066
1067
GF_Err gf_odf_write_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od)
1068
627
{
1069
627
  GF_Err e;
1070
627
  u32 size;
1071
627
  if (! od) return GF_BAD_PARAM;
1072
1073
627
  e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
1074
627
  if (e) return e;
1075
627
  e = gf_odf_write_base_descriptor(bs, od->tag, size);
1076
627
  if (e) return e;
1077
1078
627
  gf_bs_write_int(bs, od->objectDescriptorID, 10);
1079
627
  gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
1080
627
  gf_bs_write_int(bs, 31, 5);   //reserved: 0b1111.1 == 31
1081
1082
627
  if (od->URLString) {
1083
378
    gf_odf_write_url_string(bs, od->URLString);
1084
378
  } else {
1085
249
    e = gf_odf_write_descriptor_list(bs, od->ES_ID_IncDescriptors);
1086
249
    if (e) return e;
1087
249
    e = gf_odf_write_descriptor_list(bs, od->ES_ID_RefDescriptors);
1088
249
    if (e) return e;
1089
249
    e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
1090
249
    if (e) return e;
1091
249
    e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
1092
249
    if (e) return e;
1093
249
    e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
1094
249
    if (e) return e;
1095
249
  }
1096
627
  e = gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
1097
627
  if (e) return e;
1098
627
  return GF_OK;
1099
627
}
1100
1101
1102
1103
GF_Descriptor *gf_odf_new_dcd()
1104
25.5k
{
1105
25.5k
  GF_DecoderConfig *newDesc;
1106
25.5k
  GF_SAFEALLOC(newDesc, GF_DecoderConfig);
1107
25.5k
  if (!newDesc) return NULL;
1108
1109
25.5k
  newDesc->profileLevelIndicationIndexDescriptor = gf_list_new();
1110
25.5k
  newDesc->tag = GF_ODF_DCD_TAG;
1111
25.5k
  return (GF_Descriptor *) newDesc;
1112
25.5k
}
1113
1114
GF_Err gf_odf_del_dcd(GF_DecoderConfig *dcd)
1115
25.5k
{
1116
25.5k
  GF_Err e;
1117
25.5k
  if (!dcd) return GF_BAD_PARAM;
1118
25.5k
  if (dcd->decoderSpecificInfo) {
1119
21.9k
    e = gf_odf_delete_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo);
1120
21.9k
    if (e) return e;
1121
21.9k
  }
1122
25.5k
  if (dcd->rvc_config) {
1123
0
    e = gf_odf_delete_descriptor((GF_Descriptor *) dcd->rvc_config);
1124
0
    if (e) return e;
1125
0
  }
1126
25.5k
  e = gf_odf_delete_descriptor_list(dcd->profileLevelIndicationIndexDescriptor);
1127
25.5k
  if (e) return e;
1128
25.5k
  gf_free(dcd);
1129
25.5k
  return GF_OK;
1130
25.5k
}
1131
1132
GF_Err gf_odf_read_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd, u32 DescSize)
1133
11.0k
{
1134
11.0k
  GF_Err e;
1135
11.0k
  u32 /*reserved, */tmp_size, nbBytes = 0;
1136
11.0k
  if (! dcd) return GF_BAD_PARAM;
1137
1138
11.0k
  dcd->objectTypeIndication = gf_bs_read_int(bs, 8);
1139
11.0k
  dcd->streamType = gf_bs_read_int(bs, 6);
1140
11.0k
  dcd->upstream = gf_bs_read_int(bs, 1);
1141
11.0k
  /*reserved = */gf_bs_read_int(bs, 1);
1142
11.0k
  dcd->bufferSizeDB = gf_bs_read_int(bs, 24);
1143
11.0k
  dcd->maxBitrate = gf_bs_read_int(bs, 32);
1144
11.0k
  dcd->avgBitrate = gf_bs_read_int(bs, 32);
1145
11.0k
  nbBytes += 13;
1146
1147
31.3k
  while (nbBytes < DescSize) {
1148
22.1k
    GF_Descriptor *tmp = NULL;
1149
22.1k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
1150
22.1k
    if (e) return e;
1151
21.1k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
1152
21.1k
    switch (tmp->tag) {
1153
7.63k
    case GF_ODF_DSI_TAG:
1154
7.63k
      if (dcd->decoderSpecificInfo) {
1155
216
        gf_odf_delete_descriptor(tmp);
1156
216
        return GF_ODF_INVALID_DESCRIPTOR;
1157
216
      }
1158
7.41k
      dcd->decoderSpecificInfo = (GF_DefaultDescriptor *) tmp;
1159
7.41k
      break;
1160
1161
231
    case GF_ODF_EXT_PL_TAG:
1162
231
      e = gf_list_add(dcd->profileLevelIndicationIndexDescriptor, tmp);
1163
231
      if (e < GF_OK) {
1164
0
        gf_odf_delete_descriptor(tmp);
1165
0
        return e;
1166
0
      }
1167
231
      break;
1168
1169
    /*iPod fix: delete and aborts, this will create an InvalidDescriptor at the ESD level with a loaded DSI,
1170
    loading will abort with a partially valid ESD which is all the matters*/
1171
659
    case GF_ODF_SLC_TAG:
1172
659
      gf_odf_delete_descriptor(tmp);
1173
659
      return GF_OK;
1174
1175
    //what the hell is this descriptor ?? Don't know, so delete it !
1176
12.6k
    default:
1177
12.6k
      gf_odf_delete_descriptor(tmp);
1178
12.6k
      break;
1179
21.1k
    }
1180
20.3k
    nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
1181
20.3k
  }
1182
9.28k
  if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1183
8.36k
  return GF_OK;
1184
9.28k
}
1185
1186
#include <gpac/constants.h>
1187
1188
GF_Err gf_odf_size_dcd(GF_DecoderConfig *dcd, u32 *outSize)
1189
695
{
1190
695
  GF_Err e;
1191
695
  u32 tmpSize;
1192
695
  u32 oti;
1193
695
  if (! dcd) return GF_BAD_PARAM;
1194
1195
695
  oti = dcd->objectTypeIndication;
1196
695
  if (oti > 0xFF) {
1197
0
    oti = gf_codecid_oti(oti);
1198
0
  }
1199
695
  if (oti > 0xFF) {
1200
0
    GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Attempt to write an internal ESD with codec ID %s (%s) , not mappable to 8 bits MPEG-4 Systems OTI", gf_4cc_to_str(dcd->objectTypeIndication), gf_codecid_name(dcd->objectTypeIndication) ));
1201
0
    return GF_BAD_PARAM;
1202
0
  }
1203
1204
695
  *outSize = 0;
1205
695
  *outSize += 13;
1206
695
  if (dcd->decoderSpecificInfo) {
1207
    //warning: we don't know anything about the structure of a generic DecSpecInfo
1208
    //we check the tag and size of the descriptor, but we most ofthe time can't parse it
1209
    //the decSpecInfo is handle as a defaultDescriptor (opaque data, but same structure....)
1210
96
    e = gf_odf_size_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo , &tmpSize);
1211
96
    if (e) return e;
1212
96
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
1213
96
  }
1214
695
  e = gf_odf_size_descriptor_list(dcd->profileLevelIndicationIndexDescriptor, outSize);
1215
695
  if (e) return e;
1216
695
  return GF_OK;
1217
695
}
1218
1219
GF_Err gf_odf_write_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd)
1220
512
{
1221
512
  GF_Err e;
1222
512
  u32 size, oti;
1223
512
  if (! dcd) return GF_BAD_PARAM;
1224
1225
512
  oti = dcd->objectTypeIndication;
1226
512
  if (oti > 0xFF) {
1227
0
    oti = gf_codecid_oti(oti);
1228
0
  }
1229
512
  if (oti > 0xFF) {
1230
0
    GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Attempt to write an internal ESD with codec ID %s (%s) , not mappable to 8 bits MPEG-4 Systems OTI", gf_4cc_to_str(dcd->objectTypeIndication), gf_codecid_name(dcd->objectTypeIndication) ));
1231
0
    return GF_BAD_PARAM;
1232
0
  }
1233
1234
512
  e = gf_odf_size_descriptor((GF_Descriptor *)dcd, &size);
1235
512
  if (e) return e;
1236
512
  e = gf_odf_write_base_descriptor(bs, dcd->tag, size);
1237
512
  if (e) return e;
1238
1239
512
  gf_bs_write_int(bs, oti, 8);
1240
512
  gf_bs_write_int(bs, dcd->streamType, 6);
1241
512
  gf_bs_write_int(bs, dcd->upstream, 1);
1242
512
  gf_bs_write_int(bs, 1, 1);  //reserved field...
1243
512
  gf_bs_write_int(bs, dcd->bufferSizeDB, 24);
1244
512
  gf_bs_write_int(bs, dcd->maxBitrate, 32);
1245
512
  gf_bs_write_int(bs, dcd->avgBitrate, 32);
1246
1247
512
  if (dcd->decoderSpecificInfo) {
1248
90
    e = gf_odf_write_descriptor(bs, (GF_Descriptor *) dcd->decoderSpecificInfo);
1249
90
    if (e) return e;
1250
90
  }
1251
512
  e = gf_odf_write_descriptor_list(bs, dcd->profileLevelIndicationIndexDescriptor);
1252
512
  return e;
1253
512
}
1254
1255
1256
GF_Descriptor *gf_odf_new_default()
1257
461k
{
1258
461k
  GF_DefaultDescriptor *newDesc = (GF_DefaultDescriptor *) gf_malloc(sizeof(GF_DefaultDescriptor));
1259
461k
  if (!newDesc) return NULL;
1260
1261
461k
  newDesc->dataLength = 0;
1262
461k
  newDesc->data = NULL;
1263
  //set it to the Max allowed
1264
461k
  newDesc->tag = GF_ODF_USER_END_TAG;
1265
461k
  return (GF_Descriptor *) newDesc;
1266
461k
}
1267
1268
GF_Err gf_odf_del_default(GF_DefaultDescriptor *dd)
1269
461k
{
1270
461k
  if (!dd) return GF_BAD_PARAM;
1271
1272
461k
  if (dd->data) gf_free(dd->data);
1273
461k
  gf_free(dd);
1274
461k
  return GF_OK;
1275
461k
}
1276
1277
GF_Err gf_odf_read_default(GF_BitStream *bs, GF_DefaultDescriptor *dd, u32 DescSize)
1278
454k
{
1279
454k
  u32 nbBytes = 0;
1280
454k
  if (! dd) return GF_BAD_PARAM;
1281
1282
454k
  dd->dataLength = DescSize;
1283
454k
  dd->data = NULL;
1284
454k
  if (DescSize) {
1285
36.4k
    dd->data = (char*)gf_malloc(dd->dataLength);
1286
36.4k
    if (! dd->data) return GF_OUT_OF_MEM;
1287
36.4k
    gf_bs_read_data(bs, dd->data, dd->dataLength);
1288
36.4k
    nbBytes += dd->dataLength;
1289
    /* internal tags are read as default but deleted as their own types
1290
       so dd->data would leak here */
1291
36.4k
    if ((dd->tag>=GF_ODF_MUXINFO_TAG) && (dd->tag<=GF_ODF_LASER_CFG_TAG)) {
1292
4.24k
      gf_free(dd->data);
1293
4.24k
      dd->data = NULL;
1294
4.24k
    }
1295
36.4k
  }
1296
454k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1297
454k
  return GF_OK;
1298
454k
}
1299
1300
GF_Err gf_odf_size_default(GF_DefaultDescriptor *dd, u32 *outSize)
1301
79.0k
{
1302
79.0k
  if (! dd) return GF_BAD_PARAM;
1303
79.0k
  *outSize  = dd->dataLength;
1304
79.0k
  return GF_OK;
1305
79.0k
}
1306
1307
GF_Err gf_odf_write_default(GF_BitStream *bs, GF_DefaultDescriptor *dd)
1308
70.6k
{
1309
70.6k
  GF_Err e;
1310
70.6k
  u32 size;
1311
70.6k
  if (! dd) return GF_BAD_PARAM;
1312
1313
70.6k
  e = gf_odf_size_descriptor((GF_Descriptor *)dd, &size);
1314
70.6k
  if (e) return e;
1315
70.6k
  e = gf_odf_write_base_descriptor(bs, dd->tag, size);
1316
70.6k
  if (e) return e;
1317
1318
24.0k
  if (dd->data) {
1319
8.17k
    gf_bs_write_data(bs, dd->data, dd->dataLength);
1320
8.17k
  }
1321
24.0k
  return GF_OK;
1322
70.6k
}
1323
1324
GF_Descriptor *gf_odf_new_esd_inc()
1325
1.96k
{
1326
1.96k
  GF_ES_ID_Inc *newDesc = (GF_ES_ID_Inc *) gf_malloc(sizeof(GF_ES_ID_Inc));
1327
1.96k
  if (!newDesc) return NULL;
1328
1.96k
  newDesc->tag = GF_ODF_ESD_INC_TAG;
1329
1.96k
  newDesc->trackID = 0;
1330
1.96k
  return (GF_Descriptor *) newDesc;
1331
1.96k
}
1332
1333
GF_Err gf_odf_del_esd_inc(GF_ES_ID_Inc *esd_inc)
1334
1.96k
{
1335
1.96k
  if (!esd_inc) return GF_BAD_PARAM;
1336
1.96k
  gf_free(esd_inc);
1337
1.96k
  return GF_OK;
1338
1.96k
}
1339
GF_Err gf_odf_read_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc, u32 DescSize)
1340
1.95k
{
1341
1.95k
  u32 nbBytes = 0;
1342
1.95k
  if (! esd_inc) return GF_BAD_PARAM;
1343
1344
1.95k
  esd_inc->trackID = gf_bs_read_int(bs, 32);
1345
1.95k
  nbBytes += 4;
1346
1.95k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1347
1.66k
  return GF_OK;
1348
1.95k
}
1349
GF_Err gf_odf_size_esd_inc(GF_ES_ID_Inc *esd_inc, u32 *outSize)
1350
88
{
1351
88
  if (! esd_inc) return GF_BAD_PARAM;
1352
88
  *outSize = 4;
1353
88
  return GF_OK;
1354
88
}
1355
GF_Err gf_odf_write_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc)
1356
88
{
1357
88
  GF_Err e;
1358
88
  u32 size;
1359
88
  if (! esd_inc) return GF_BAD_PARAM;
1360
1361
88
  e = gf_odf_size_descriptor((GF_Descriptor *)esd_inc, &size);
1362
88
  if (e) return e;
1363
88
  e = gf_odf_write_base_descriptor(bs, esd_inc->tag, size);
1364
88
  if (e) return e;
1365
88
  gf_bs_write_int(bs, esd_inc->trackID, 32);
1366
88
  return GF_OK;
1367
88
}
1368
1369
GF_Descriptor *gf_odf_new_esd_ref()
1370
5.40k
{
1371
5.40k
  GF_ES_ID_Ref *newDesc = (GF_ES_ID_Ref *) gf_malloc(sizeof(GF_ES_ID_Ref));
1372
5.40k
  if (!newDesc) return NULL;
1373
5.40k
  newDesc->tag = GF_ODF_ESD_REF_TAG;
1374
5.40k
  newDesc->trackRef = 0;
1375
5.40k
  return (GF_Descriptor *) newDesc;
1376
5.40k
}
1377
1378
GF_Err gf_odf_del_esd_ref(GF_ES_ID_Ref *esd_ref)
1379
5.40k
{
1380
5.40k
  if (!esd_ref) return GF_BAD_PARAM;
1381
5.40k
  gf_free(esd_ref);
1382
5.40k
  return GF_OK;
1383
5.40k
}
1384
GF_Err gf_odf_read_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref, u32 DescSize)
1385
5.40k
{
1386
5.40k
  u32 nbBytes = 0;
1387
5.40k
  if (! esd_ref) return GF_BAD_PARAM;
1388
1389
5.40k
  esd_ref->trackRef = gf_bs_read_int(bs, 16);
1390
5.40k
  nbBytes += 2;
1391
5.40k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1392
5.16k
  return GF_OK;
1393
5.40k
}
1394
1395
GF_Err gf_odf_size_esd_ref(GF_ES_ID_Ref *esd_ref, u32 *outSize)
1396
1.88k
{
1397
1.88k
  if (! esd_ref) return GF_BAD_PARAM;
1398
1.88k
  *outSize = 2;
1399
1.88k
  return GF_OK;
1400
1.88k
}
1401
GF_Err gf_odf_write_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref)
1402
1.68k
{
1403
1.68k
  GF_Err e;
1404
1.68k
  u32 size;
1405
1.68k
  if (! esd_ref) return GF_BAD_PARAM;
1406
1407
1.68k
  e = gf_odf_size_descriptor((GF_Descriptor *)esd_ref, &size);
1408
1.68k
  if (e) return e;
1409
1.68k
  e = gf_odf_write_base_descriptor(bs, esd_ref->tag, size);
1410
1.68k
  if (e) return e;
1411
1412
1.68k
  gf_bs_write_int(bs, esd_ref->trackRef, 16);
1413
1.68k
  return GF_OK;
1414
1.68k
}
1415
1416
1417
1418
GF_Descriptor *gf_odf_new_segment()
1419
1.10k
{
1420
1.10k
  GF_Segment *newDesc = (GF_Segment *) gf_malloc(sizeof(GF_Segment));
1421
1.10k
  if (!newDesc) return NULL;
1422
1423
1.10k
  memset(newDesc, 0, sizeof(GF_Segment));
1424
1.10k
  newDesc->tag = GF_ODF_SEGMENT_TAG;
1425
1.10k
  return (GF_Descriptor *) newDesc;
1426
1.10k
}
1427
1428
GF_Err gf_odf_del_segment(GF_Segment *sd)
1429
1.10k
{
1430
1.10k
  if (!sd) return GF_BAD_PARAM;
1431
1432
1.10k
  if (sd->SegmentName) gf_free(sd->SegmentName);
1433
1.10k
  gf_free(sd);
1434
1.10k
  return GF_OK;
1435
1.10k
}
1436
1437
GF_Err gf_odf_read_segment(GF_BitStream *bs, GF_Segment *sd, u32 DescSize)
1438
1.10k
{
1439
1.10k
  u32 size, nbBytes = 0;
1440
1.10k
  if (!sd) return GF_BAD_PARAM;
1441
1442
1.10k
  sd->startTime = gf_bs_read_double(bs);
1443
1.10k
  sd->Duration = gf_bs_read_double(bs);
1444
1.10k
  nbBytes += 16;
1445
1.10k
  size = gf_bs_read_int(bs, 8);
1446
1.10k
  nbBytes += 1;
1447
1.10k
  if (size) {
1448
486
    sd->SegmentName = (char*) gf_malloc(sizeof(char)*(size+1));
1449
486
    if (!sd->SegmentName) return GF_OUT_OF_MEM;
1450
486
    gf_bs_read_data(bs, sd->SegmentName, size);
1451
486
    sd->SegmentName[size] = 0;
1452
486
    nbBytes += size;
1453
486
  }
1454
1.10k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1455
136
  return GF_OK;
1456
1.10k
}
1457
1458
GF_Err gf_odf_size_segment(GF_Segment *sd, u32 *outSize)
1459
23
{
1460
23
  if (!sd) return GF_BAD_PARAM;
1461
23
  *outSize = 17;
1462
23
  if (sd->SegmentName) *outSize += (u32) strlen(sd->SegmentName);
1463
23
  return GF_OK;
1464
23
}
1465
1466
GF_Err gf_odf_write_segment(GF_BitStream *bs, GF_Segment *sd)
1467
23
{
1468
23
  GF_Err e;
1469
23
  u32 size;
1470
23
  if (!sd) return GF_BAD_PARAM;
1471
23
  e = gf_odf_size_descriptor((GF_Descriptor *)sd, &size);
1472
23
  if (e) return e;
1473
23
  e = gf_odf_write_base_descriptor(bs, sd->tag, size);
1474
23
  if (e) return e;
1475
23
  gf_bs_write_double(bs, sd->startTime);
1476
23
  gf_bs_write_double(bs, sd->Duration);
1477
23
  if (sd->SegmentName) {
1478
13
    gf_bs_write_int(bs, (u32) strlen(sd->SegmentName), 8);
1479
13
    gf_bs_write_data(bs, sd->SegmentName, (u32) strlen(sd->SegmentName));
1480
13
  } else {
1481
10
    gf_bs_write_int(bs, 0, 8);
1482
10
  }
1483
23
  return GF_OK;
1484
23
}
1485
1486
1487
1488
GF_Descriptor *gf_odf_new_lang()
1489
6.51k
{
1490
6.51k
  GF_Language *newDesc;
1491
6.51k
  GF_SAFEALLOC(newDesc, GF_Language);
1492
6.51k
  if (!newDesc) return NULL;
1493
6.51k
  newDesc->tag = GF_ODF_LANG_TAG;
1494
6.51k
  return (GF_Descriptor *) newDesc;
1495
6.51k
}
1496
1497
GF_Err gf_odf_del_lang(GF_Language *ld)
1498
6.51k
{
1499
6.51k
  if (!ld) return GF_BAD_PARAM;
1500
6.51k
  if (ld->full_lang_code) gf_free(ld->full_lang_code);
1501
6.51k
  gf_free(ld);
1502
6.51k
  return GF_OK;
1503
6.51k
}
1504
1505
GF_Err gf_odf_read_lang(GF_BitStream *bs, GF_Language *ld, u32 DescSize)
1506
6.51k
{
1507
6.51k
  u32 nbBytes = 0;
1508
6.51k
  if (!ld) return GF_BAD_PARAM;
1509
1510
6.51k
  ld->langCode = gf_bs_read_int(bs, 24);
1511
6.51k
  nbBytes += 3;
1512
6.51k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1513
6.10k
  return GF_OK;
1514
6.51k
}
1515
1516
GF_Err gf_odf_size_lang(GF_Language *ld, u32 *outSize)
1517
3.35k
{
1518
3.35k
  if (!ld) return GF_BAD_PARAM;
1519
3.35k
  *outSize = 3;
1520
3.35k
  return GF_OK;
1521
3.35k
}
1522
1523
GF_Err gf_odf_write_lang(GF_BitStream *bs, GF_Language *ld)
1524
2.71k
{
1525
2.71k
  GF_Err e;
1526
2.71k
  u32 size;
1527
2.71k
  if (!ld) return GF_BAD_PARAM;
1528
1529
2.71k
  e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
1530
2.71k
  if (e) return e;
1531
2.71k
  e = gf_odf_write_base_descriptor(bs, ld->tag, size);
1532
2.71k
  if (e) return e;
1533
2.71k
  gf_bs_write_int(bs, ld->langCode, 24);
1534
2.71k
  return GF_OK;
1535
2.71k
}
1536
1537
1538
1539
GF_Descriptor *gf_odf_new_auxvid()
1540
2.17k
{
1541
2.17k
  GF_AuxVideoDescriptor *newDesc;
1542
2.17k
  GF_SAFEALLOC(newDesc, GF_AuxVideoDescriptor);
1543
2.17k
  if (!newDesc) return NULL;
1544
2.17k
  newDesc->tag = GF_ODF_AUX_VIDEO_DATA;
1545
2.17k
  return (GF_Descriptor *) newDesc;
1546
2.17k
}
1547
1548
GF_Err gf_odf_del_auxvid(GF_AuxVideoDescriptor *ld)
1549
2.17k
{
1550
2.17k
  if (!ld) return GF_BAD_PARAM;
1551
2.17k
  gf_free(ld);
1552
2.17k
  return GF_OK;
1553
2.17k
}
1554
1555
GF_Err gf_odf_read_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld, u32 DescSize)
1556
2.17k
{
1557
2.17k
  u32 nbBytes = 0;
1558
2.17k
  if (!ld) return GF_BAD_PARAM;
1559
1560
2.17k
  ld->aux_video_type = gf_bs_read_int(bs, 8);
1561
2.17k
  ld->position_offset_h = gf_bs_read_int(bs, 8);
1562
2.17k
  ld->position_offset_v = gf_bs_read_int(bs, 8);
1563
2.17k
  nbBytes += 3;
1564
2.17k
  switch (ld->aux_video_type) {
1565
658
  case 0x10:
1566
658
    ld->kfar = gf_bs_read_int(bs, 8);
1567
658
    ld->knear = gf_bs_read_int(bs, 8);
1568
658
    nbBytes += 2;
1569
658
    break;
1570
488
  case 0x11:
1571
488
    ld->parallax_zero = gf_bs_read_int(bs, 16);
1572
488
    ld->parallax_scale = gf_bs_read_int(bs, 16);
1573
488
    ld->dref = gf_bs_read_int(bs, 16);
1574
488
    ld->wref = gf_bs_read_int(bs, 16);
1575
488
    nbBytes += 8;
1576
488
    break;
1577
2.17k
  }
1578
63.3k
  while (nbBytes < DescSize) {
1579
61.1k
    gf_bs_read_int(bs, 8);
1580
61.1k
    nbBytes ++;
1581
61.1k
  }
1582
2.17k
  return GF_OK;
1583
2.17k
}
1584
1585
GF_Err gf_odf_size_auxvid(GF_AuxVideoDescriptor *ld, u32 *outSize)
1586
1.58k
{
1587
1.58k
  if (!ld) return GF_BAD_PARAM;
1588
1.58k
  switch (ld->aux_video_type) {
1589
604
  case 0x10:
1590
604
    *outSize = 5;
1591
604
    break;
1592
465
  case 0x11:
1593
465
    *outSize = 11;
1594
465
    break;
1595
512
  default:
1596
512
    *outSize = 3;
1597
512
    break;
1598
1.58k
  }
1599
1.58k
  return GF_OK;
1600
1.58k
}
1601
1602
GF_Err gf_odf_write_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld)
1603
764
{
1604
764
  GF_Err e;
1605
764
  u32 size;
1606
764
  if (!ld) return GF_BAD_PARAM;
1607
764
  e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
1608
764
  if (e) return e;
1609
764
  e = gf_odf_write_base_descriptor(bs, ld->tag, size);
1610
764
  if (e) return e;
1611
1612
764
  gf_bs_write_int(bs, ld->aux_video_type, 8);
1613
764
  gf_bs_write_int(bs, ld->position_offset_h, 8);
1614
764
  gf_bs_write_int(bs, ld->position_offset_v, 8);
1615
764
  switch (ld->aux_video_type) {
1616
306
  case 0x10:
1617
306
    gf_bs_write_int(bs, ld->kfar, 8);
1618
306
    gf_bs_write_int(bs, ld->knear, 8);
1619
306
    break;
1620
188
  case 0x11:
1621
188
    gf_bs_write_int(bs, ld->parallax_zero, 16);
1622
188
    gf_bs_write_int(bs, ld->parallax_scale, 16);
1623
188
    gf_bs_write_int(bs, ld->dref, 16);
1624
188
    gf_bs_write_int(bs, ld->wref, 16);
1625
188
    break;
1626
764
  }
1627
764
  return GF_OK;
1628
764
}
1629
1630
1631
1632
GF_Descriptor *gf_odf_new_muxinfo()
1633
233
{
1634
233
  GF_MuxInfo *newDesc = (GF_MuxInfo *) gf_malloc(sizeof(GF_MuxInfo));
1635
233
  if (!newDesc) return NULL;
1636
233
  memset(newDesc, 0, sizeof(GF_MuxInfo));
1637
233
  newDesc->tag = GF_ODF_MUXINFO_TAG;
1638
233
  return (GF_Descriptor *) newDesc;
1639
233
}
1640
1641
GF_Err gf_odf_del_muxinfo(GF_MuxInfo *mi)
1642
233
{
1643
233
  if (!mi) return GF_BAD_PARAM;
1644
233
  if (mi->file_name) gf_free(mi->file_name);
1645
233
  if (mi->src_url) gf_free(mi->src_url);
1646
233
  if (mi->streamFormat) gf_free(mi->streamFormat);
1647
233
  if (mi->textNode) gf_free(mi->textNode);
1648
233
  if (mi->fontNode) gf_free(mi->fontNode);
1649
233
  gf_free(mi);
1650
233
  return GF_OK;
1651
233
}
1652
1653
GF_Err gf_odf_size_muxinfo(GF_MuxInfo *mi, u32 *outSize)
1654
0
{
1655
0
  *outSize = 0;
1656
0
  return GF_OK;
1657
0
}
1658
GF_Err gf_odf_write_muxinfo(GF_BitStream *bs, GF_MuxInfo *mi)
1659
0
{
1660
0
  return GF_OK;
1661
0
}
1662
1663
GF_Descriptor *gf_odf_New_ElemMask()
1664
534
{
1665
534
  GF_ElementaryMask *newDesc = (GF_ElementaryMask*) gf_malloc (sizeof(GF_ElementaryMask));
1666
534
  if (!newDesc) return NULL;
1667
534
  memset(newDesc, 0, sizeof(GF_ElementaryMask));
1668
534
  newDesc->tag = GF_ODF_ELEM_MASK_TAG;
1669
534
  return (GF_Descriptor *) newDesc;
1670
534
}
1671
1672
GF_Err gf_odf_del_ElemMask(GF_ElementaryMask *desc)
1673
534
{
1674
534
  if (desc->node_name) gf_free(desc->node_name);
1675
534
  gf_free(desc);
1676
534
  return GF_OK;
1677
534
}
1678
1679
GF_Descriptor *gf_odf_new_bifs_cfg()
1680
298
{
1681
298
  GF_BIFSConfig *newDesc = (GF_BIFSConfig *) gf_malloc(sizeof(GF_BIFSConfig));
1682
298
  if (!newDesc) return NULL;
1683
298
  memset(newDesc, 0, sizeof(GF_BIFSConfig));
1684
298
  newDesc->tag = GF_ODF_BIFS_CFG_TAG;
1685
298
  return (GF_Descriptor *) newDesc;
1686
298
}
1687
1688
GF_Err gf_odf_del_bifs_cfg(GF_BIFSConfig *desc)
1689
298
{
1690
298
  if (desc->elementaryMasks) {
1691
0
    u32 i, count = gf_list_count(desc->elementaryMasks);
1692
0
    for (i=0; i<count; i++) {
1693
0
      GF_ElementaryMask *tmp = (GF_ElementaryMask *)gf_list_get(desc->elementaryMasks, i);
1694
0
      if (tmp->node_name) gf_free(tmp->node_name);
1695
0
      gf_free(tmp);
1696
0
    }
1697
0
    gf_list_del(desc->elementaryMasks);
1698
0
  }
1699
298
  gf_free(desc);
1700
298
  return GF_OK;
1701
298
}
1702
1703
GF_Descriptor *gf_odf_new_laser_cfg()
1704
1.83k
{
1705
1.83k
  GF_LASERConfig *newDesc = (GF_LASERConfig *) gf_malloc(sizeof(GF_LASERConfig));
1706
1.83k
  if (!newDesc) return NULL;
1707
1.83k
  memset(newDesc, 0, sizeof(GF_LASERConfig));
1708
1.83k
  newDesc->tag = GF_ODF_LASER_CFG_TAG;
1709
1.83k
  return (GF_Descriptor *) newDesc;
1710
1.83k
}
1711
1712
GF_Err gf_odf_del_laser_cfg(GF_LASERConfig *desc)
1713
1.83k
{
1714
1.83k
  gf_free(desc);
1715
1.83k
  return GF_OK;
1716
1.83k
}
1717
1718
GF_Descriptor *gf_odf_new_ui_cfg()
1719
251
{
1720
251
  GF_UIConfig *newDesc = (GF_UIConfig *) gf_malloc(sizeof(GF_UIConfig));
1721
251
  if (!newDesc) return NULL;
1722
251
  memset(newDesc, 0, sizeof(GF_UIConfig));
1723
251
  newDesc->tag = GF_ODF_UI_CFG_TAG;
1724
251
  return (GF_Descriptor *) newDesc;
1725
251
}
1726
1727
GF_Err gf_odf_del_ui_cfg(GF_UIConfig *desc)
1728
251
{
1729
251
  if (desc->deviceName) gf_free(desc->deviceName);
1730
251
  if (desc->ui_data) gf_free(desc->ui_data);
1731
251
  gf_free(desc);
1732
251
  return GF_OK;
1733
251
}
1734
1735
#ifndef GPAC_MINIMAL_ODF
1736
1737
GF_Descriptor *gf_odf_new_mediatime()
1738
{
1739
  GF_MediaTime *newDesc = (GF_MediaTime *) gf_malloc(sizeof(GF_MediaTime));
1740
  if (!newDesc) return NULL;
1741
1742
  memset(newDesc, 0, sizeof(GF_MediaTime));
1743
  newDesc->tag = GF_ODF_MEDIATIME_TAG;
1744
  return (GF_Descriptor *) newDesc;
1745
}
1746
GF_Err gf_odf_del_mediatime(GF_MediaTime *mt)
1747
{
1748
  if (!mt) return GF_BAD_PARAM;
1749
  gf_free(mt);
1750
  return GF_OK;
1751
}
1752
GF_Err gf_odf_read_mediatime(GF_BitStream *bs, GF_MediaTime *mt, u32 DescSize)
1753
{
1754
  if (!mt) return GF_BAD_PARAM;
1755
  mt->mediaTimeStamp = gf_bs_read_double(bs);
1756
  return GF_OK;
1757
}
1758
GF_Err gf_odf_size_mediatime(GF_MediaTime *mt, u32 *outSize)
1759
{
1760
  if (!mt) return GF_BAD_PARAM;
1761
  *outSize = 8;
1762
  return GF_OK;
1763
}
1764
GF_Err gf_odf_write_mediatime(GF_BitStream *bs, GF_MediaTime *mt)
1765
{
1766
  GF_Err e;
1767
  u32 size;
1768
  if (!mt) return GF_BAD_PARAM;
1769
  e = gf_odf_size_descriptor((GF_Descriptor *)mt, &size);
1770
  if (e) return e;
1771
  e = gf_odf_write_base_descriptor(bs, mt->tag, size);
1772
  if (e) return e;
1773
  gf_bs_write_double(bs, mt->mediaTimeStamp);
1774
  return GF_OK;
1775
}
1776
1777
GF_Descriptor *gf_odf_new_cc()
1778
{
1779
  GF_CCDescriptor *newDesc = (GF_CCDescriptor *) gf_malloc(sizeof(GF_CCDescriptor));
1780
  if (!newDesc) return NULL;
1781
1782
  newDesc->contentClassificationData = NULL;
1783
  newDesc->dataLength = 0;
1784
  newDesc->classificationEntity = 0;
1785
  newDesc->classificationTable = 0;
1786
  newDesc->tag = GF_ODF_CC_TAG;
1787
  return (GF_Descriptor *) newDesc;
1788
}
1789
1790
GF_Err gf_odf_del_cc(GF_CCDescriptor *ccd)
1791
{
1792
  if (!ccd) return GF_BAD_PARAM;
1793
  if (ccd->contentClassificationData) gf_free(ccd->contentClassificationData);
1794
  gf_free(ccd);
1795
  return GF_OK;
1796
}
1797
1798
GF_Err gf_odf_read_cc(GF_BitStream *bs, GF_CCDescriptor *ccd, u32 DescSize)
1799
{
1800
  u32 nbBytes = 0;
1801
  if (!ccd) return GF_BAD_PARAM;
1802
1803
  ccd->classificationEntity = gf_bs_read_int(bs, 32);
1804
  ccd->classificationTable = gf_bs_read_int(bs, 16);
1805
  nbBytes += 6;
1806
  if (DescSize < 6) return GF_ODF_INVALID_DESCRIPTOR;
1807
1808
  ccd->dataLength = DescSize - 6;
1809
  ccd->contentClassificationData = (char*)gf_malloc(sizeof(char) * ccd->dataLength);
1810
  if (!ccd->contentClassificationData) return GF_OUT_OF_MEM;
1811
  gf_bs_read_data(bs, ccd->contentClassificationData, ccd->dataLength);
1812
  nbBytes += ccd->dataLength;
1813
1814
  if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1815
  return GF_OK;
1816
}
1817
1818
GF_Err gf_odf_size_cc(GF_CCDescriptor *ccd, u32 *outSize)
1819
{
1820
  if (!ccd) return GF_BAD_PARAM;
1821
  *outSize = 6 + ccd->dataLength;
1822
  return GF_OK;
1823
}
1824
1825
GF_Err gf_odf_write_cc(GF_BitStream *bs, GF_CCDescriptor *ccd)
1826
{
1827
  u32 size;
1828
  GF_Err e;
1829
  if (!ccd) return GF_BAD_PARAM;
1830
1831
  e = gf_odf_size_descriptor((GF_Descriptor *)ccd, &size);
1832
  if (e) return e;
1833
  e = gf_odf_write_base_descriptor(bs, ccd->tag, size);
1834
  if (e) return e;
1835
  gf_bs_write_int(bs, ccd->classificationEntity, 32);
1836
  gf_bs_write_int(bs, ccd->classificationTable, 16);
1837
  gf_bs_write_data(bs, ccd->contentClassificationData, ccd->dataLength);
1838
  return GF_OK;
1839
}
1840
1841
GF_Descriptor *gf_odf_new_cc_date()
1842
{
1843
  GF_CC_Date *newDesc = (GF_CC_Date *) gf_malloc(sizeof(GF_CC_Date));
1844
  if (!newDesc) return NULL;
1845
  memset(newDesc->contentCreationDate, 0, 5);
1846
  newDesc->tag = GF_ODF_CC_DATE_TAG;
1847
  return (GF_Descriptor *) newDesc;
1848
}
1849
1850
1851
GF_Err gf_odf_del_cc_date(GF_CC_Date *cdd)
1852
{
1853
  if (!cdd) return GF_BAD_PARAM;
1854
  gf_free(cdd);
1855
  return GF_OK;
1856
}
1857
1858
GF_Err gf_odf_read_cc_date(GF_BitStream *bs, GF_CC_Date *cdd, u32 DescSize)
1859
{
1860
  u32 nbBytes = 0;
1861
  if (!cdd) return GF_BAD_PARAM;
1862
1863
  gf_bs_read_data(bs, cdd->contentCreationDate, DATE_CODING_LEN);
1864
  nbBytes += DATE_CODING_LEN;
1865
  if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1866
  return GF_OK;
1867
}
1868
1869
GF_Err gf_odf_size_cc_date(GF_CC_Date *cdd, u32 *outSize)
1870
{
1871
  if (!cdd) return GF_BAD_PARAM;
1872
  *outSize = DATE_CODING_LEN;
1873
  return GF_OK;
1874
}
1875
1876
GF_Err gf_odf_write_cc_date(GF_BitStream *bs, GF_CC_Date *cdd)
1877
{
1878
  u32 size;
1879
  GF_Err e;
1880
  if (!cdd) return GF_BAD_PARAM;
1881
1882
  e = gf_odf_size_descriptor((GF_Descriptor *)cdd, &size);
1883
  if (e) return e;
1884
  e = gf_odf_write_base_descriptor(bs, cdd->tag, size);
1885
  if (e) return e;
1886
1887
  gf_bs_write_data(bs, cdd->contentCreationDate, DATE_CODING_LEN);
1888
  return GF_OK;
1889
}
1890
1891
GF_Descriptor *gf_odf_new_cc_name()
1892
{
1893
  GF_CC_Name *newDesc = (GF_CC_Name *) gf_malloc(sizeof(GF_CC_Name));
1894
  if (!newDesc) return NULL;
1895
1896
  newDesc->ContentCreators = gf_list_new();
1897
  if (! newDesc->ContentCreators) {
1898
    gf_free(newDesc);
1899
    return NULL;
1900
  }
1901
  newDesc->tag = GF_ODF_CC_NAME_TAG;
1902
  return (GF_Descriptor *) newDesc;
1903
}
1904
1905
GF_Err gf_odf_del_cc_name(GF_CC_Name *cnd)
1906
{
1907
  u32 i;
1908
  GF_ContentCreatorInfo *tmp;
1909
  if (!cnd) return GF_BAD_PARAM;
1910
1911
  i=0;
1912
  while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
1913
    if (tmp->contentCreatorName) gf_free(tmp->contentCreatorName);
1914
    gf_free(tmp);
1915
  }
1916
  gf_list_del(cnd->ContentCreators);
1917
  gf_free(cnd);
1918
  return GF_OK;
1919
}
1920
1921
GF_Err gf_odf_read_cc_name(GF_BitStream *bs, GF_CC_Name *cnd, u32 DescSize)
1922
{
1923
  GF_Err e;
1924
  u32 i, count, len, nbBytes = 0;
1925
  if (!cnd) return GF_BAD_PARAM;
1926
1927
  count = gf_bs_read_int(bs, 8);
1928
  nbBytes += 1;
1929
  for (i = 0; i< count; i++) {
1930
    GF_ContentCreatorInfo *tmp = (GF_ContentCreatorInfo*)gf_malloc(sizeof(GF_ContentCreatorInfo));
1931
    if (! tmp) return GF_OUT_OF_MEM;
1932
    memset(tmp , 0, sizeof(GF_ContentCreatorInfo));
1933
    tmp->langCode = gf_bs_read_int(bs, 24);
1934
    tmp->isUTF8 = gf_bs_read_int(bs, 1);
1935
    /*aligned = */gf_bs_read_int(bs, 7);
1936
    nbBytes += 4;
1937
1938
    e = OD_ReadUTF8String(bs, & tmp->contentCreatorName, tmp->isUTF8, &len);
1939
    if (e) {
1940
      gf_free(tmp);
1941
      return e;
1942
    }
1943
    nbBytes += len;
1944
    e = gf_list_add(cnd->ContentCreators, tmp);
1945
    if (e) return e;
1946
  }
1947
  if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1948
  return GF_OK;
1949
}
1950
1951
GF_Err gf_odf_size_cc_name(GF_CC_Name *cnd, u32 *outSize)
1952
{
1953
  u32 i;
1954
  GF_ContentCreatorInfo *tmp;
1955
  if (!cnd) return GF_BAD_PARAM;
1956
1957
  *outSize = 1;
1958
  i=0;
1959
  while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
1960
    *outSize += 4 + OD_SizeUTF8String(tmp->contentCreatorName, tmp->isUTF8);
1961
  }
1962
  return GF_OK;
1963
}
1964
1965
GF_Err gf_odf_write_cc_name(GF_BitStream *bs, GF_CC_Name *cnd)
1966
{
1967
  GF_Err e;
1968
  GF_ContentCreatorInfo *tmp;
1969
  u32 i, size;
1970
  if (!cnd) return GF_BAD_PARAM;
1971
1972
  e = gf_odf_size_descriptor((GF_Descriptor *)cnd, &size);
1973
  if (e) return e;
1974
  e = gf_odf_write_base_descriptor(bs, cnd->tag, size);
1975
  if (e) return e;
1976
  gf_bs_write_int(bs, gf_list_count(cnd->ContentCreators), 8);
1977
1978
  i=0;
1979
  while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
1980
    gf_bs_write_int(bs, tmp->langCode, 24);
1981
    gf_bs_write_int(bs, tmp->isUTF8, 1);
1982
    gf_bs_write_int(bs, 0, 7);    //aligned
1983
    OD_WriteUTF8String(bs, tmp->contentCreatorName, tmp->isUTF8);
1984
  }
1985
  return GF_OK;
1986
}
1987
1988
1989
GF_Descriptor *gf_odf_new_ci()
1990
{
1991
  GF_CIDesc *newDesc = (GF_CIDesc *) gf_malloc(sizeof(GF_CIDesc));
1992
  if (!newDesc) return NULL;
1993
1994
  newDesc->compatibility = 0;
1995
  newDesc->contentIdentifier = NULL;
1996
  newDesc->tag = GF_ODF_CI_TAG;
1997
  newDesc->contentIdentifierFlag = 0;
1998
  newDesc->contentIdentifierType = 0;
1999
  newDesc->contentType = 0;
2000
  newDesc->contentTypeFlag = 0;
2001
  newDesc->protectedContent = 0;
2002
  return (GF_Descriptor *) newDesc;
2003
}
2004
2005
2006
GF_Err gf_odf_del_ci(GF_CIDesc *cid)
2007
{
2008
  if (!cid) return GF_BAD_PARAM;
2009
2010
  if (cid->contentIdentifier) gf_free(cid->contentIdentifier);
2011
  gf_free(cid);
2012
  return GF_OK;
2013
}
2014
2015
2016
GF_Err gf_odf_read_ci(GF_BitStream *bs, GF_CIDesc *cid, u32 DescSize)
2017
{
2018
  u32 nbBytes = 0;
2019
  if (! cid) return GF_BAD_PARAM;
2020
2021
  cid->compatibility = gf_bs_read_int(bs, 2); //MUST BE NULL
2022
  if (cid->compatibility) return GF_ODF_INVALID_DESCRIPTOR;
2023
2024
  cid->contentTypeFlag = gf_bs_read_int(bs, 1);
2025
  cid->contentIdentifierFlag = gf_bs_read_int(bs, 1);
2026
  cid->protectedContent = gf_bs_read_int(bs, 1);
2027
  /*reserved = */gf_bs_read_int(bs, 3);
2028
  nbBytes += 1;
2029
2030
  if (cid->contentTypeFlag) {
2031
    cid->contentType = gf_bs_read_int(bs, 8);
2032
    nbBytes += 1;
2033
  }
2034
  if (cid->contentIdentifierFlag) {
2035
    cid->contentIdentifierType = gf_bs_read_int(bs, 8);
2036
    if (DescSize < (u32) 2 + cid->contentTypeFlag) return GF_ODF_INVALID_DESCRIPTOR;
2037
    cid->contentIdentifier = (char*)gf_malloc(DescSize - 2 - cid->contentTypeFlag);
2038
    if (! cid->contentIdentifier) return GF_OUT_OF_MEM;
2039
2040
    gf_bs_read_data(bs, cid->contentIdentifier, DescSize - 2 - cid->contentTypeFlag);
2041
    nbBytes += DescSize - 1 - cid->contentTypeFlag;
2042
  }
2043
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2044
  return GF_OK;
2045
}
2046
2047
GF_Err gf_odf_size_ci(GF_CIDesc *cid, u32 *outSize)
2048
{
2049
  if (! cid) return GF_BAD_PARAM;
2050
2051
  *outSize = 1;
2052
  if (cid->contentTypeFlag) *outSize += 1;
2053
2054
  if (cid->contentIdentifierFlag)
2055
    *outSize += (u32) strlen((const char*)cid->contentIdentifier) - 1 - cid->contentTypeFlag;
2056
  return GF_OK;
2057
}
2058
2059
GF_Err gf_odf_write_ci(GF_BitStream *bs, GF_CIDesc *cid)
2060
{
2061
  GF_Err e;
2062
  u32 size;
2063
  if (! cid) return GF_BAD_PARAM;
2064
2065
  e = gf_odf_size_descriptor((GF_Descriptor *)cid, &size);
2066
  if (e) return e;
2067
  e = gf_odf_write_base_descriptor(bs, cid->tag, size);
2068
  if (e) return e;
2069
2070
  gf_bs_write_int(bs, cid->compatibility, 2);
2071
  gf_bs_write_int(bs, cid->contentTypeFlag, 1);
2072
  gf_bs_write_int(bs, cid->contentIdentifierFlag, 1);
2073
  gf_bs_write_int(bs, cid->protectedContent, 1);
2074
  gf_bs_write_int(bs, 7, 3);    //reserved 0b111 = 7
2075
2076
  if (cid->contentTypeFlag) {
2077
    gf_bs_write_int(bs, cid->contentType, 8);
2078
  }
2079
2080
  if (cid->contentIdentifierFlag) {
2081
    gf_bs_write_int(bs, cid->contentIdentifierType, 8);
2082
    gf_bs_write_data(bs, cid->contentIdentifier, size - 2 - cid->contentTypeFlag);
2083
  }
2084
  return GF_OK;
2085
}
2086
2087
GF_Descriptor *gf_odf_new_exp_text()
2088
{
2089
  GF_ExpandedTextual *newDesc = (GF_ExpandedTextual *) gf_malloc(sizeof(GF_ExpandedTextual));
2090
  if (!newDesc) return NULL;
2091
2092
  newDesc->itemDescriptionList = gf_list_new();
2093
  if (! newDesc->itemDescriptionList) {
2094
    gf_free(newDesc);
2095
    return NULL;
2096
  }
2097
  newDesc->itemTextList = gf_list_new();
2098
  if (! newDesc->itemTextList) {
2099
    gf_free(newDesc->itemDescriptionList);
2100
    gf_free(newDesc);
2101
    return NULL;
2102
  }
2103
  newDesc->isUTF8 = 0;
2104
  newDesc->langCode = 0;
2105
  newDesc->NonItemText = NULL;
2106
  newDesc->tag = GF_ODF_TEXT_TAG;
2107
  return (GF_Descriptor *) newDesc;
2108
}
2109
2110
GF_Err gf_odf_del_exp_text(GF_ExpandedTextual *etd)
2111
{
2112
  if (!etd) return GF_BAD_PARAM;
2113
2114
  while (gf_list_count(etd->itemDescriptionList)) {
2115
    GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemDescriptionList, 0);
2116
    if (tmp) {
2117
      if (tmp->text) gf_free(tmp->text);
2118
      gf_free(tmp);
2119
    }
2120
    gf_list_rem(etd->itemDescriptionList, 0);
2121
  }
2122
  gf_list_del(etd->itemDescriptionList);
2123
2124
  while (gf_list_count(etd->itemTextList)) {
2125
    GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, 0);
2126
    if (tmp) {
2127
      if (tmp->text) gf_free(tmp->text);
2128
      gf_free(tmp);
2129
    }
2130
    gf_list_rem(etd->itemTextList, 0);
2131
  }
2132
  gf_list_del(etd->itemTextList);
2133
2134
  if (etd->NonItemText) gf_free(etd->NonItemText);
2135
  gf_free(etd);
2136
  return GF_OK;
2137
}
2138
2139
GF_Err gf_odf_read_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd, u32 DescSize)
2140
{
2141
  GF_Err e;
2142
  u32 nbBytes = 0;
2143
  u32 i, len, nonLen, count;
2144
  if (!etd) return GF_BAD_PARAM;
2145
2146
  etd->langCode = gf_bs_read_int(bs, 24);
2147
  etd->isUTF8 = gf_bs_read_int(bs, 1);
2148
  /*aligned = */gf_bs_read_int(bs, 7);
2149
  count = gf_bs_read_int(bs, 8);
2150
  nbBytes += 5;
2151
2152
  for (i = 0; i< count; i++) {
2153
    //description
2154
    GF_ETD_ItemText *description, *Text;
2155
    description = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText));
2156
    if (! description) return GF_OUT_OF_MEM;
2157
    description->text = NULL;
2158
    e = OD_ReadUTF8String(bs, & description->text, etd->isUTF8, &len);
2159
    if (e) {
2160
      gf_free(description);
2161
      return e;
2162
    }
2163
    e = gf_list_add(etd->itemDescriptionList, description);
2164
    if (e) return e;
2165
    nbBytes += len;
2166
2167
    //text
2168
    Text = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText));
2169
    if (! Text) return GF_OUT_OF_MEM;
2170
    Text->text = NULL;
2171
    e = OD_ReadUTF8String(bs, & Text->text, etd->isUTF8, &len);
2172
    if (e) return e;
2173
    e = gf_list_add(etd->itemTextList, Text);
2174
    if (e) return e;
2175
    nbBytes += len;
2176
  }
2177
  len = gf_bs_read_int(bs, 8);
2178
  nbBytes += 1;
2179
  nonLen = 0;
2180
  while (len == 255) {
2181
    nonLen += len;
2182
    len = gf_bs_read_int(bs, 8);
2183
    nbBytes += 1;
2184
  }
2185
  nonLen += len;
2186
  if (nonLen) {
2187
    //here we have no choice but do the job ourselves
2188
    //because the length is not encoded on 8 bits
2189
    etd->NonItemText = (char *) gf_malloc(sizeof(char) * (1+nonLen) * (etd->isUTF8 ? 1 : 2));
2190
    if (! etd->NonItemText) return GF_OUT_OF_MEM;
2191
    gf_bs_read_data(bs, etd->NonItemText, nonLen * (etd->isUTF8 ? 1 : 2));
2192
    nbBytes += nonLen * (etd->isUTF8 ? 1 : 2);
2193
  }
2194
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2195
  return GF_OK;
2196
}
2197
2198
2199
GF_Err gf_odf_size_exp_text(GF_ExpandedTextual *etd, u32 *outSize)
2200
{
2201
  u32 i, len, nonLen, lentmp, count;
2202
  if (!etd) return GF_BAD_PARAM;
2203
2204
  *outSize = 5;
2205
  if (gf_list_count(etd->itemDescriptionList) != gf_list_count(etd->itemTextList)) return GF_ODF_INVALID_DESCRIPTOR;
2206
2207
  count = gf_list_count(etd->itemDescriptionList);
2208
  for (i=0; i<count; i++) {
2209
    GF_ETD_ItemText *tmp = (GF_ETD_ItemText *)gf_list_get(etd->itemDescriptionList, i);
2210
    *outSize += OD_SizeUTF8String(tmp->text, etd->isUTF8);
2211
    tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, i);
2212
    *outSize += OD_SizeUTF8String(tmp->text, etd->isUTF8);
2213
  }
2214
  *outSize += 1;
2215
  if (etd->NonItemText) {
2216
    if (etd->isUTF8) {
2217
      nonLen = (u32) strlen((const char*)etd->NonItemText);
2218
    } else {
2219
      nonLen = gf_utf8_wcslen((const unsigned short*)etd->NonItemText);
2220
    }
2221
  } else {
2222
    nonLen = 0;
2223
  }
2224
  len = 255;
2225
  lentmp = nonLen;
2226
  if (lentmp < 255) {
2227
    len = lentmp;
2228
  }
2229
  while (len == 255) {
2230
    *outSize += 1;
2231
    lentmp -= 255;
2232
    if (lentmp < 255) {
2233
      len = lentmp;
2234
    }
2235
  }
2236
  *outSize += nonLen * (etd->isUTF8 ? 1 : 2);
2237
  return GF_OK;
2238
}
2239
2240
GF_Err gf_odf_write_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd)
2241
{
2242
  GF_Err e;
2243
  u32 size, i, len, nonLen, lentmp, count;
2244
  if (!etd) return GF_BAD_PARAM;
2245
2246
  if (gf_list_count(etd->itemDescriptionList) != gf_list_count(etd->itemTextList)) return GF_ODF_INVALID_DESCRIPTOR;
2247
2248
  e = gf_odf_size_descriptor((GF_Descriptor *)etd, &size);
2249
  if (e) return e;
2250
  e = gf_odf_write_base_descriptor(bs, etd->tag, size);
2251
  if (e) return e;
2252
2253
  gf_bs_write_int(bs, etd->langCode, 24);
2254
  gf_bs_write_int(bs, etd->isUTF8, 1);
2255
  gf_bs_write_int(bs, 0, 7);    //aligned
2256
  gf_bs_write_int(bs, gf_list_count(etd->itemDescriptionList), 8);
2257
2258
  count = gf_list_count(etd->itemDescriptionList);
2259
  for (i=0; i<count; i++) {
2260
    GF_ETD_ItemText *tmp = (GF_ETD_ItemText *)gf_list_get(etd->itemDescriptionList, i);
2261
    OD_WriteUTF8String(bs, tmp->text, etd->isUTF8);
2262
    tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, i);
2263
    OD_WriteUTF8String(bs, tmp->text, etd->isUTF8);
2264
  }
2265
  if (etd->NonItemText) {
2266
    if (etd->isUTF8) {
2267
      nonLen = (u32) strlen((const char*)etd->NonItemText);
2268
    } else {
2269
      nonLen = gf_utf8_wcslen((const unsigned short*)etd->NonItemText);
2270
    }
2271
  } else {
2272
    nonLen = 0;
2273
  }
2274
  lentmp = nonLen;
2275
  len = lentmp < 255 ? lentmp : 255;
2276
  while (len == 255) {
2277
    gf_bs_write_int(bs, len, 8);
2278
    lentmp -= len;
2279
    len = lentmp < 255 ? lentmp : 255;
2280
  }
2281
  gf_bs_write_int(bs, len, 8);
2282
  gf_bs_write_data(bs, etd->NonItemText, nonLen * (etd->isUTF8 ? 1 : 2));
2283
  return GF_OK;
2284
}
2285
2286
GF_Descriptor *gf_odf_new_pl_ext()
2287
{
2288
  GF_PLExt *newDesc = (GF_PLExt *) gf_malloc(sizeof(GF_PLExt));
2289
  if (!newDesc) return NULL;
2290
  newDesc->AudioProfileLevelIndication = 0;
2291
  newDesc->GraphicsProfileLevelIndication = 0;
2292
  newDesc->MPEGJProfileLevelIndication = 0;
2293
  newDesc->ODProfileLevelIndication = 0;
2294
  newDesc->profileLevelIndicationIndex = 0;
2295
  newDesc->SceneProfileLevelIndication = 0;
2296
  newDesc->VisualProfileLevelIndication = 0;
2297
  newDesc->tag = GF_ODF_EXT_PL_TAG;
2298
  return (GF_Descriptor *) newDesc;
2299
}
2300
2301
GF_Err gf_odf_del_pl_ext(GF_PLExt *pld)
2302
{
2303
  if (!pld) return GF_BAD_PARAM;
2304
2305
  gf_free(pld);
2306
  return GF_OK;
2307
}
2308
2309
GF_Err gf_odf_read_pl_ext(GF_BitStream *bs, GF_PLExt *pld, u32 DescSize)
2310
{
2311
  u32 nbBytes = 0;
2312
  if (!pld) return GF_BAD_PARAM;
2313
2314
  pld->profileLevelIndicationIndex = gf_bs_read_int(bs, 8);
2315
  pld->ODProfileLevelIndication = gf_bs_read_int(bs, 8);
2316
  pld->SceneProfileLevelIndication = gf_bs_read_int(bs, 8);
2317
  pld->AudioProfileLevelIndication = gf_bs_read_int(bs, 8);
2318
  pld->VisualProfileLevelIndication = gf_bs_read_int(bs, 8);
2319
  pld->GraphicsProfileLevelIndication = gf_bs_read_int(bs, 8);
2320
  pld->MPEGJProfileLevelIndication = gf_bs_read_int(bs, 8);
2321
2322
  nbBytes += 7;
2323
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2324
  return GF_OK;
2325
}
2326
2327
GF_Err gf_odf_size_pl_ext(GF_PLExt *pld, u32 *outSize)
2328
{
2329
  if (!pld) return GF_BAD_PARAM;
2330
2331
  *outSize = 7;
2332
  return GF_OK;
2333
}
2334
2335
GF_Err gf_odf_write_pl_ext(GF_BitStream *bs, GF_PLExt *pld)
2336
{
2337
  GF_Err e;
2338
  u32 size;
2339
  if (!pld) return GF_BAD_PARAM;
2340
2341
  e = gf_odf_size_descriptor((GF_Descriptor *)pld, &size);
2342
  if (e) return e;
2343
  e = gf_odf_write_base_descriptor(bs, pld->tag, size);
2344
  if (e) return e;
2345
2346
  gf_bs_write_int(bs, pld->profileLevelIndicationIndex, 8);
2347
  gf_bs_write_int(bs, pld->ODProfileLevelIndication, 8);
2348
  gf_bs_write_int(bs, pld->SceneProfileLevelIndication, 8);
2349
  gf_bs_write_int(bs, pld->AudioProfileLevelIndication, 8);
2350
  gf_bs_write_int(bs, pld->VisualProfileLevelIndication, 8);
2351
  gf_bs_write_int(bs, pld->GraphicsProfileLevelIndication, 8);
2352
  gf_bs_write_int(bs, pld->MPEGJProfileLevelIndication, 8);
2353
  return GF_OK;
2354
}
2355
2356
GF_Descriptor *gf_odf_new_ipi_ptr()
2357
{
2358
  GF_IPIPtr *newDesc = (GF_IPIPtr *) gf_malloc(sizeof(GF_IPIPtr));
2359
  if (!newDesc) return NULL;
2360
  newDesc->IPI_ES_Id = 0;
2361
  newDesc->tag = GF_ODF_IPI_PTR_TAG;
2362
  return (GF_Descriptor *) newDesc;
2363
}
2364
2365
GF_Err gf_odf_del_ipi_ptr(GF_IPIPtr *ipid)
2366
{
2367
  if (!ipid) return GF_BAD_PARAM;
2368
  gf_free(ipid);
2369
  return GF_OK;
2370
}
2371
2372
GF_Err gf_odf_read_ipi_ptr(GF_BitStream *bs, GF_IPIPtr *ipid, u32 DescSize)
2373
{
2374
  u32 nbBytes = 0;
2375
  if (! ipid) return GF_BAD_PARAM;
2376
2377
  ipid->IPI_ES_Id = gf_bs_read_int(bs, 16);
2378
  nbBytes += 2;
2379
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2380
  return GF_OK;
2381
}
2382
2383
GF_Err gf_odf_size_ipi_ptr(GF_IPIPtr *ipid, u32 *outSize)
2384
{
2385
  if (! ipid) return GF_BAD_PARAM;
2386
  *outSize = 2;
2387
  return GF_OK;
2388
}
2389
2390
GF_Err gf_odf_write_ipi_ptr(GF_BitStream *bs, GF_IPIPtr *ipid)
2391
{
2392
  GF_Err e;
2393
  u32 size;
2394
  if (! ipid) return GF_BAD_PARAM;
2395
  e = gf_odf_size_descriptor((GF_Descriptor *)ipid, &size);
2396
  if (e) return e;
2397
  e = gf_odf_write_base_descriptor(bs, ipid->tag, size);
2398
  if (e) return e;
2399
  gf_bs_write_int(bs, ipid->IPI_ES_Id, 16);
2400
  return GF_OK;
2401
}
2402
2403
GF_Descriptor *gf_odf_new_ipmp()
2404
{
2405
  GF_IPMP_Descriptor *newDesc;
2406
  GF_SAFEALLOC(newDesc, GF_IPMP_Descriptor);
2407
  if (!newDesc) return NULL;
2408
2409
  newDesc->ipmpx_data = gf_list_new();
2410
  newDesc->tag = GF_ODF_IPMP_TAG;
2411
  return (GF_Descriptor *) newDesc;
2412
}
2413
GF_Err gf_odf_del_ipmp(GF_IPMP_Descriptor *ipmp)
2414
{
2415
  if (!ipmp) return GF_BAD_PARAM;
2416
  if (ipmp->opaque_data) gf_free(ipmp->opaque_data);
2417
#ifndef GPAC_MINIMAL_ODF
2418
  /*TODO DELETE IPMPX*/
2419
  while (gf_list_count(ipmp->ipmpx_data)) {
2420
    GF_IPMPX_Data *p = (GF_IPMPX_Data *)gf_list_get(ipmp->ipmpx_data, 0);
2421
    gf_list_rem(ipmp->ipmpx_data, 0);
2422
    gf_ipmpx_data_del(p);
2423
  }
2424
#endif
2425
  gf_list_del(ipmp->ipmpx_data);
2426
  gf_free(ipmp);
2427
  return GF_OK;
2428
}
2429
2430
GF_Err gf_odf_read_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp, u32 DescSize)
2431
{
2432
  u32 size;
2433
  u64 nbBytes = 0;
2434
  if (!ipmp) return GF_BAD_PARAM;
2435
2436
  ipmp->IPMP_DescriptorID = gf_bs_read_int(bs, 8);
2437
  ipmp->IPMPS_Type = gf_bs_read_int(bs, 16);
2438
  nbBytes += 3;
2439
  if (DescSize<3) return GF_ODF_INVALID_DESCRIPTOR;
2440
2441
  size = DescSize - 3;
2442
2443
  /*IPMPX escape*/
2444
  if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
2445
    ipmp->IPMP_DescriptorIDEx = gf_bs_read_int(bs, 16);
2446
    if (gf_bs_available(bs) < 16) return GF_ODF_INVALID_DESCRIPTOR;
2447
    gf_bs_read_data(bs, (char*)ipmp->IPMP_ToolID, 16);
2448
    ipmp->control_point = gf_bs_read_int(bs, 8);
2449
    nbBytes += 19;
2450
    if (ipmp->control_point) {
2451
      ipmp->cp_sequence_code = gf_bs_read_int(bs, 8);
2452
      nbBytes += 1;
2453
    }
2454
    while (nbBytes<DescSize) {
2455
      u64 pos;
2456
      GF_Err e;
2457
      GF_IPMPX_Data *p;
2458
      pos = gf_bs_get_position(bs);
2459
      e = gf_ipmpx_data_parse(bs, &p);
2460
      if (e) return e;
2461
      gf_list_add(ipmp->ipmpx_data, p);
2462
      nbBytes += gf_bs_get_position(bs) - pos;
2463
    }
2464
  }
2465
  /*URL*/
2466
  else if (! ipmp->IPMPS_Type) {
2467
    ipmp->opaque_data = (char*)gf_malloc(size + 1);
2468
    if (! ipmp->opaque_data) return GF_OUT_OF_MEM;
2469
    gf_bs_read_data(bs, ipmp->opaque_data, size);
2470
    nbBytes += size;
2471
    ipmp->opaque_data[size] = 0;
2472
    ipmp->opaque_data_size = size;
2473
2474
  }
2475
  /*data*/
2476
  else {
2477
    ipmp->opaque_data_size = size;
2478
    ipmp->opaque_data = (char*)gf_malloc(size);
2479
    if (! ipmp->opaque_data) return GF_OUT_OF_MEM;
2480
    gf_bs_read_data(bs, ipmp->opaque_data, size);
2481
    nbBytes += size;
2482
  }
2483
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2484
  return GF_OK;
2485
}
2486
2487
GF_Err gf_odf_size_ipmp(GF_IPMP_Descriptor *ipmp, u32 *outSize)
2488
{
2489
  u32 i, s;
2490
  if (!ipmp) return GF_BAD_PARAM;
2491
2492
  *outSize = 3;
2493
  /*IPMPX escape*/
2494
  if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
2495
    GF_IPMPX_Data *p;
2496
    *outSize += 19;
2497
    if (ipmp->control_point) *outSize += 1;
2498
    s = 0;
2499
    i=0;
2500
    while ((p = (GF_IPMPX_Data *)gf_list_enum(ipmp->ipmpx_data, &i))) {
2501
      s += gf_ipmpx_data_full_size(p);
2502
    }
2503
    (*outSize) += s;
2504
  }
2505
  else if (! ipmp->IPMPS_Type) {
2506
    if (!ipmp->opaque_data) return GF_ODF_INVALID_DESCRIPTOR;
2507
    *outSize += (u32) strlen(ipmp->opaque_data);
2508
  } else {
2509
    *outSize += ipmp->opaque_data_size;
2510
  }
2511
  return GF_OK;
2512
}
2513
2514
GF_Err gf_odf_write_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp)
2515
{
2516
  GF_Err e;
2517
  u32 size, i;
2518
  if (!ipmp) return GF_BAD_PARAM;
2519
2520
  e = gf_odf_size_descriptor((GF_Descriptor *)ipmp, &size);
2521
  if (e) return e;
2522
  e = gf_odf_write_base_descriptor(bs, ipmp->tag, size);
2523
  if (e) return e;
2524
  gf_bs_write_int(bs, ipmp->IPMP_DescriptorID, 8);
2525
  gf_bs_write_int(bs, ipmp->IPMPS_Type, 16);
2526
2527
  if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
2528
    GF_IPMPX_Data *p;
2529
    gf_bs_write_int(bs, ipmp->IPMP_DescriptorIDEx, 16);
2530
    gf_bs_write_data(bs, (char*)ipmp->IPMP_ToolID, 16);
2531
    gf_bs_write_int(bs, ipmp->control_point, 8);
2532
    if (ipmp->control_point) gf_bs_write_int(bs, ipmp->cp_sequence_code, 8);
2533
2534
    i=0;
2535
    while ((p = (GF_IPMPX_Data *) gf_list_enum(ipmp->ipmpx_data, &i))) {
2536
      gf_ipmpx_data_write(bs, p);
2537
    }
2538
  }
2539
  else if (!ipmp->IPMPS_Type) {
2540
    if (!ipmp->opaque_data) return GF_ODF_INVALID_DESCRIPTOR;
2541
    gf_bs_write_data(bs, ipmp->opaque_data, (u32) strlen(ipmp->opaque_data));
2542
  } else {
2543
    gf_bs_write_data(bs, ipmp->opaque_data, ipmp->opaque_data_size);
2544
  }
2545
  return GF_OK;
2546
}
2547
2548
GF_Descriptor *gf_odf_new_ipmp_ptr()
2549
{
2550
  GF_IPMPPtr *newDesc;
2551
  GF_SAFEALLOC(newDesc, GF_IPMPPtr);
2552
  if (!newDesc) return NULL;
2553
  newDesc->tag = GF_ODF_IPMP_PTR_TAG;
2554
  return (GF_Descriptor *) newDesc;
2555
}
2556
GF_Err gf_odf_del_ipmp_ptr(GF_IPMPPtr *ipmpd)
2557
{
2558
  if (!ipmpd) return GF_BAD_PARAM;
2559
  gf_free(ipmpd);
2560
  return GF_OK;
2561
}
2562
2563
GF_Err gf_odf_read_ipmp_ptr(GF_BitStream *bs, GF_IPMPPtr *ipmpd, u32 DescSize)
2564
{
2565
  u32 nbBytes = 0;
2566
  if (! ipmpd) return GF_BAD_PARAM;
2567
  ipmpd->IPMP_DescriptorID = gf_bs_read_int(bs, 8);
2568
  nbBytes += 1;
2569
  if (ipmpd->IPMP_DescriptorID == 0xFF) {
2570
    ipmpd->IPMP_DescriptorIDEx = gf_bs_read_int(bs, 16);
2571
    ipmpd->IPMP_ES_ID = gf_bs_read_int(bs, 16);
2572
    nbBytes += 4;
2573
  }
2574
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2575
  return GF_OK;
2576
}
2577
GF_Err gf_odf_size_ipmp_ptr(GF_IPMPPtr *ipmpd, u32 *outSize)
2578
{
2579
  if (! ipmpd) return GF_BAD_PARAM;
2580
  *outSize = 1;
2581
  if (ipmpd->IPMP_DescriptorID == 0xFF) *outSize += 4;
2582
  return GF_OK;
2583
}
2584
GF_Err gf_odf_write_ipmp_ptr(GF_BitStream *bs, GF_IPMPPtr *ipmpd)
2585
{
2586
  GF_Err e;
2587
  u32 size;
2588
  if (! ipmpd) return GF_BAD_PARAM;
2589
2590
  e = gf_odf_size_descriptor((GF_Descriptor *)ipmpd, &size);
2591
  if (e) return e;
2592
  e = gf_odf_write_base_descriptor(bs, ipmpd->tag, size);
2593
  if (e) return e;
2594
  gf_bs_write_int(bs, ipmpd->IPMP_DescriptorID, 8);
2595
  if (ipmpd->IPMP_DescriptorID == 0xFF) {
2596
    gf_bs_write_int(bs, ipmpd->IPMP_DescriptorIDEx, 16);
2597
    gf_bs_write_int(bs, ipmpd->IPMP_ES_ID, 16);
2598
  }
2599
  return GF_OK;
2600
}
2601
2602
GF_Descriptor *gf_odf_new_kw()
2603
{
2604
  GF_KeyWord *newDesc = (GF_KeyWord *) gf_malloc(sizeof(GF_KeyWord));
2605
  if (!newDesc) return NULL;
2606
2607
  newDesc->keyWordsList = gf_list_new();
2608
  if (! newDesc->keyWordsList) {
2609
    gf_free(newDesc);
2610
    return NULL;
2611
  }
2612
  newDesc->isUTF8 = 0;
2613
  newDesc->languageCode = 0;
2614
  newDesc->tag = GF_ODF_KW_TAG;
2615
  return (GF_Descriptor *) newDesc;
2616
}
2617
2618
GF_Err gf_odf_del_kw(GF_KeyWord *kwd)
2619
{
2620
  if (!kwd) return GF_BAD_PARAM;
2621
2622
  while (gf_list_count(kwd->keyWordsList)) {
2623
    GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_list_get(kwd->keyWordsList, 0);
2624
    if (tmp) {
2625
      if (tmp->keyWord) gf_free(tmp->keyWord);
2626
      tmp->keyWord = NULL;
2627
      gf_list_rem(kwd->keyWordsList, 0);
2628
      gf_free(tmp);
2629
    }
2630
  }
2631
  gf_list_del(kwd->keyWordsList);
2632
  gf_free(kwd);
2633
  return GF_OK;
2634
}
2635
2636
GF_Err gf_odf_read_kw(GF_BitStream *bs, GF_KeyWord *kwd, u32 DescSize)
2637
{
2638
  GF_Err e;
2639
  u32 nbBytes = 0, i, kwcount, len;
2640
  if (!kwd) return GF_BAD_PARAM;
2641
2642
  kwd->languageCode = gf_bs_read_int(bs, 24);
2643
  kwd->isUTF8 = gf_bs_read_int(bs, 1);
2644
  /*aligned = */gf_bs_read_int(bs, 7);
2645
  kwcount = gf_bs_read_int(bs, 8);
2646
  nbBytes += 5;
2647
2648
  for (i = 0 ; i < kwcount; i++) {
2649
    GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_malloc(sizeof(GF_KeyWordItem));
2650
    if (! tmp) return GF_OUT_OF_MEM;
2651
    e = OD_ReadUTF8String(bs, & tmp->keyWord, kwd->isUTF8, &len);
2652
    if (e) {
2653
      if (tmp->keyWord) gf_free(tmp->keyWord);
2654
      gf_free(tmp);
2655
      return e;
2656
    }
2657
    nbBytes += len;
2658
    if (nbBytes > DescSize) {
2659
      gf_free(tmp->keyWord);
2660
      gf_free(tmp);
2661
      return GF_ODF_INVALID_DESCRIPTOR;
2662
    }
2663
    e = gf_list_add(kwd->keyWordsList, tmp);
2664
    if (e) {
2665
      if (tmp) gf_free(tmp);
2666
      return e;
2667
    }
2668
  }
2669
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2670
  return GF_OK;
2671
}
2672
2673
2674
GF_Err gf_odf_size_kw(GF_KeyWord *kwd, u32 *outSize)
2675
{
2676
  u32 i;
2677
  GF_KeyWordItem *tmp;
2678
  if (!kwd) return GF_BAD_PARAM;
2679
2680
  *outSize = 5;
2681
  i=0;
2682
  while ((tmp = (GF_KeyWordItem *)gf_list_enum(kwd->keyWordsList, &i))) {
2683
    *outSize += OD_SizeUTF8String(tmp->keyWord, kwd->isUTF8);
2684
  }
2685
  return GF_OK;
2686
}
2687
GF_Err gf_odf_write_kw(GF_BitStream *bs, GF_KeyWord *kwd)
2688
{
2689
  GF_Err e;
2690
  u32 size, i;
2691
  GF_KeyWordItem *tmp;
2692
  if (!kwd) return GF_BAD_PARAM;
2693
2694
  e = gf_odf_size_descriptor((GF_Descriptor *)kwd, &size);
2695
  if (e) return e;
2696
  e = gf_odf_write_base_descriptor(bs, kwd->tag, size);
2697
  if (e) return e;
2698
2699
  gf_bs_write_int(bs, kwd->languageCode, 24);
2700
  gf_bs_write_int(bs, kwd->isUTF8, 1);
2701
  gf_bs_write_int(bs, 0, 7);    //aligned(8)
2702
  gf_bs_write_int(bs, gf_list_count(kwd->keyWordsList), 8);
2703
2704
  i=0;
2705
  while ((tmp = (GF_KeyWordItem *)gf_list_enum(kwd->keyWordsList, &i))) {
2706
    OD_WriteUTF8String(bs, tmp->keyWord, kwd->isUTF8);
2707
  }
2708
  return GF_OK;
2709
}
2710
2711
GF_Descriptor *gf_odf_new_oci_date()
2712
{
2713
  GF_OCI_Data *newDesc = (GF_OCI_Data *) gf_malloc(sizeof(GF_OCI_Data));
2714
  if (!newDesc) return NULL;
2715
  memset(newDesc->OCICreationDate, 0, 5);
2716
  newDesc->tag = GF_ODF_OCI_DATE_TAG;
2717
  return (GF_Descriptor *) newDesc;
2718
}
2719
2720
GF_Err gf_odf_del_oci_date(GF_OCI_Data *ocd)
2721
{
2722
  if (!ocd) return GF_BAD_PARAM;
2723
  gf_free(ocd);
2724
  return GF_OK;
2725
}
2726
2727
GF_Err gf_odf_read_oci_date(GF_BitStream *bs, GF_OCI_Data *ocd, u32 DescSize)
2728
{
2729
  u32 nbBytes = 0;
2730
  if (!ocd) return GF_BAD_PARAM;
2731
2732
  gf_bs_read_data(bs, ocd->OCICreationDate, DATE_CODING_LEN);
2733
  nbBytes += DATE_CODING_LEN;
2734
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2735
  return GF_OK;
2736
}
2737
2738
GF_Err gf_odf_size_oci_date(GF_OCI_Data *ocd, u32 *outSize)
2739
{
2740
  if (!ocd) return GF_BAD_PARAM;
2741
  *outSize = DATE_CODING_LEN;
2742
  return GF_OK;
2743
}
2744
2745
GF_Err gf_odf_write_oci_date(GF_BitStream *bs, GF_OCI_Data *ocd)
2746
{
2747
  GF_Err e;
2748
  u32 size;
2749
  if (!ocd) return GF_BAD_PARAM;
2750
2751
  e = gf_odf_size_descriptor((GF_Descriptor *)ocd, &size);
2752
  if (e) return e;
2753
  e = gf_odf_write_base_descriptor(bs, ocd->tag, size);
2754
  if (e) return e;
2755
  gf_bs_write_data(bs, ocd->OCICreationDate, DATE_CODING_LEN);
2756
  return GF_OK;
2757
}
2758
2759
GF_Descriptor *gf_odf_new_oci_name()
2760
{
2761
  GF_OCICreators *newDesc = (GF_OCICreators *) gf_malloc(sizeof(GF_OCICreators));
2762
  if (!newDesc) return NULL;
2763
2764
  newDesc->OCICreators = gf_list_new();
2765
  if (! newDesc->OCICreators) {
2766
    gf_free(newDesc);
2767
    return NULL;
2768
  }
2769
  newDesc->tag = GF_ODF_OCI_NAME_TAG;
2770
  return (GF_Descriptor *) newDesc;
2771
}
2772
GF_Err gf_odf_del_oci_name(GF_OCICreators *ocn)
2773
{
2774
  u32 i;
2775
  GF_OCICreator_item *tmp;
2776
  if (!ocn) return GF_BAD_PARAM;
2777
2778
  i=0;
2779
  while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
2780
    if (tmp->OCICreatorName) gf_free(tmp->OCICreatorName);
2781
    gf_free(tmp);
2782
  }
2783
  gf_list_del(ocn->OCICreators);
2784
  gf_free(ocn);
2785
  return GF_OK;
2786
}
2787
2788
GF_Err gf_odf_read_oci_name(GF_BitStream *bs, GF_OCICreators *ocn, u32 DescSize)
2789
{
2790
  GF_Err e;
2791
  u32 nbBytes = 0;
2792
  u32 i, count, len;
2793
  if (!ocn) return GF_BAD_PARAM;
2794
2795
  count = gf_bs_read_int(bs, 8);
2796
  nbBytes += 1;
2797
  for (i = 0; i< count; i++) {
2798
    GF_OCICreator_item *tmp = (GF_OCICreator_item*)gf_malloc(sizeof(GF_OCICreator_item));
2799
    if (! tmp) return GF_OUT_OF_MEM;
2800
    tmp->langCode = gf_bs_read_int(bs, 24);
2801
    tmp->isUTF8 = gf_bs_read_int(bs, 1);
2802
    /*aligned = */gf_bs_read_int(bs, 7);
2803
    nbBytes += 4;
2804
    e = OD_ReadUTF8String(bs, & tmp->OCICreatorName, tmp->isUTF8, &len);
2805
    if (e) {
2806
      gf_free(tmp);
2807
      return e;
2808
    }
2809
    nbBytes += len;
2810
    e = gf_list_add(ocn->OCICreators, tmp);
2811
    if (e) return e;
2812
  }
2813
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2814
  return GF_OK;
2815
}
2816
2817
GF_Err gf_odf_size_oci_name(GF_OCICreators *ocn, u32 *outSize)
2818
{
2819
  u32 i;
2820
  GF_OCICreator_item *tmp;
2821
  if (!ocn) return GF_BAD_PARAM;
2822
2823
  *outSize = 1;
2824
  i=0;
2825
  while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
2826
    *outSize += 4 + OD_SizeUTF8String(tmp->OCICreatorName, tmp->isUTF8);
2827
  }
2828
  return GF_OK;
2829
}
2830
2831
GF_Err gf_odf_write_oci_name(GF_BitStream *bs, GF_OCICreators *ocn)
2832
{
2833
  GF_Err e;
2834
  u32 size;
2835
  u32 i;
2836
  GF_OCICreator_item *tmp;
2837
  if (!ocn) return GF_BAD_PARAM;
2838
2839
  e = gf_odf_size_descriptor((GF_Descriptor *)ocn, &size);
2840
  if (e) return e;
2841
  e = gf_odf_write_base_descriptor(bs, ocn->tag, size);
2842
  if (e) return e;
2843
  gf_bs_write_int(bs, gf_list_count(ocn->OCICreators), 8);
2844
2845
  i=0;
2846
  while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
2847
    gf_bs_write_int(bs, tmp->langCode, 24);
2848
    gf_bs_write_int(bs, tmp->isUTF8, 1);
2849
    gf_bs_write_int(bs, 0, 7);    //aligned
2850
    gf_bs_write_int(bs, (u32) strlen(tmp->OCICreatorName) , 8);
2851
    OD_WriteUTF8String(bs, tmp->OCICreatorName, tmp->isUTF8);
2852
  }
2853
  return GF_OK;
2854
}
2855
2856
2857
GF_Descriptor *gf_odf_new_pl_idx()
2858
{
2859
  GF_PL_IDX *newDesc = (GF_PL_IDX *) gf_malloc(sizeof(GF_PL_IDX));
2860
  if (!newDesc) return NULL;
2861
  newDesc->profileLevelIndicationIndex = 0;
2862
  newDesc->tag = GF_ODF_PL_IDX_TAG;
2863
  return (GF_Descriptor *) newDesc;
2864
}
2865
2866
GF_Err gf_odf_del_pl_idx(GF_PL_IDX *plid)
2867
{
2868
  if (!plid) return GF_BAD_PARAM;
2869
  gf_free(plid);
2870
  return GF_OK;
2871
}
2872
2873
GF_Err gf_odf_read_pl_idx(GF_BitStream *bs, GF_PL_IDX *plid, u32 DescSize)
2874
{
2875
  u32 nbBytes = 0;
2876
  if (!plid) return GF_BAD_PARAM;
2877
2878
  plid->profileLevelIndicationIndex = gf_bs_read_int(bs, 8);
2879
  nbBytes += 1;
2880
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2881
  return GF_OK;
2882
}
2883
GF_Err gf_odf_size_pl_idx(GF_PL_IDX *plid, u32 *outSize)
2884
{
2885
  if (!plid) return GF_BAD_PARAM;
2886
  *outSize = 1;
2887
  return GF_OK;
2888
}
2889
GF_Err gf_odf_write_pl_idx(GF_BitStream *bs, GF_PL_IDX *plid)
2890
{
2891
  GF_Err e;
2892
  u32 size;
2893
  if (!plid) return GF_BAD_PARAM;
2894
  e = gf_odf_size_descriptor((GF_Descriptor *)plid, &size);
2895
  if (e) return e;
2896
  e = gf_odf_write_base_descriptor(bs, plid->tag, size);
2897
  if (e) return e;
2898
  gf_bs_write_int(bs, plid->profileLevelIndicationIndex, 8);
2899
  return GF_OK;
2900
}
2901
2902
2903
GF_Descriptor *gf_odf_new_rating()
2904
{
2905
  GF_Rating *newDesc = (GF_Rating *) gf_malloc(sizeof(GF_Rating));
2906
  if (!newDesc) return NULL;
2907
2908
  newDesc->infoLength = 0;
2909
  newDesc->ratingInfo = NULL;
2910
  newDesc->ratingCriteria = 0;
2911
  newDesc->ratingEntity = 0;
2912
  newDesc->tag = GF_ODF_RATING_TAG;
2913
  return (GF_Descriptor *) newDesc;
2914
}
2915
2916
GF_Err gf_odf_del_rating(GF_Rating *rd)
2917
{
2918
  if (!rd) return GF_BAD_PARAM;
2919
2920
  if (rd->ratingInfo) gf_free(rd->ratingInfo);
2921
  gf_free(rd);
2922
  return GF_OK;
2923
}
2924
2925
GF_Err gf_odf_read_rating(GF_BitStream *bs, GF_Rating *rd, u32 DescSize)
2926
{
2927
  u32 nbBytes = 0;
2928
  if (!rd) return GF_BAD_PARAM;
2929
2930
  rd->ratingEntity = gf_bs_read_int(bs, 32);
2931
  rd->ratingCriteria = gf_bs_read_int(bs, 16);
2932
  if (DescSize<6) return GF_ODF_INVALID_DESCRIPTOR;
2933
  rd->infoLength = DescSize - 6;
2934
  nbBytes += 6;
2935
2936
  rd->ratingInfo = (char*)gf_malloc(rd->infoLength);
2937
  if (! rd->ratingInfo) return GF_OUT_OF_MEM;
2938
  gf_bs_read_data(bs, rd->ratingInfo, rd->infoLength);
2939
  nbBytes += rd->infoLength;
2940
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2941
  return GF_OK;
2942
}
2943
2944
GF_Err gf_odf_size_rating(GF_Rating *rd, u32 *outSize)
2945
{
2946
  if (!rd) return GF_BAD_PARAM;
2947
2948
  *outSize = 6 + rd->infoLength;
2949
  return GF_OK;
2950
}
2951
2952
GF_Err gf_odf_write_rating(GF_BitStream *bs, GF_Rating *rd)
2953
{
2954
  GF_Err e;
2955
  u32 size;
2956
  if (!rd) return GF_BAD_PARAM;
2957
  e = gf_odf_size_descriptor((GF_Descriptor *)rd, &size);
2958
  if (e) return e;
2959
  e = gf_odf_write_base_descriptor(bs, rd->tag, size);
2960
  if (e) return e;
2961
  gf_bs_write_int(bs, rd->ratingEntity, 32);
2962
  gf_bs_write_int(bs, rd->ratingCriteria, 16);
2963
  gf_bs_write_data(bs, rd->ratingInfo, rd->infoLength);
2964
  return GF_OK;
2965
}
2966
2967
2968
GF_Descriptor *gf_odf_new_reg()
2969
{
2970
  GF_Registration *newDesc = (GF_Registration *) gf_malloc(sizeof(GF_Registration));
2971
  if (!newDesc) return NULL;
2972
  newDesc->additionalIdentificationInfo = NULL;
2973
  newDesc->dataLength = 0;
2974
  newDesc->formatIdentifier = 0;
2975
  newDesc->tag = GF_ODF_REG_TAG;
2976
  return (GF_Descriptor *) newDesc;
2977
}
2978
2979
GF_Err gf_odf_del_reg(GF_Registration *reg)
2980
{
2981
  if (!reg) return GF_BAD_PARAM;
2982
2983
  if (reg->additionalIdentificationInfo) gf_free(reg->additionalIdentificationInfo);
2984
  gf_free(reg);
2985
  return GF_OK;
2986
}
2987
2988
GF_Err gf_odf_read_reg(GF_BitStream *bs, GF_Registration *reg, u32 DescSize)
2989
{
2990
  u32 nbBytes = 0;
2991
  if (!reg) return GF_BAD_PARAM;
2992
2993
  reg->formatIdentifier = gf_bs_read_int(bs, 32);
2994
  if (DescSize<4) return GF_ODF_INVALID_DESCRIPTOR;
2995
  reg->dataLength = DescSize - 4;
2996
  reg->additionalIdentificationInfo = (char*)gf_malloc(reg->dataLength);
2997
  if (! reg->additionalIdentificationInfo) return GF_OUT_OF_MEM;
2998
  gf_bs_read_data(bs, reg->additionalIdentificationInfo, reg->dataLength);
2999
  nbBytes += reg->dataLength + 4;
3000
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3001
  return GF_OK;
3002
}
3003
3004
3005
GF_Err gf_odf_size_reg(GF_Registration *reg, u32 *outSize)
3006
{
3007
  if (!reg) return GF_BAD_PARAM;
3008
3009
  *outSize = 4 + reg->dataLength;
3010
  return GF_OK;
3011
}
3012
3013
GF_Err gf_odf_write_reg(GF_BitStream *bs, GF_Registration *reg)
3014
{
3015
  GF_Err e;
3016
  u32 size;
3017
  if (!reg) return GF_BAD_PARAM;
3018
3019
  e = gf_odf_size_descriptor((GF_Descriptor *)reg, &size);
3020
  if (e) return e;
3021
  e = gf_odf_write_base_descriptor(bs, reg->tag, size);
3022
  if (e) return e;
3023
3024
  gf_bs_write_int(bs, reg->formatIdentifier, 32);
3025
  gf_bs_write_data(bs, reg->additionalIdentificationInfo, reg->dataLength);
3026
  return GF_OK;
3027
}
3028
3029
GF_Descriptor *gf_odf_new_short_text()
3030
{
3031
  GF_ShortTextual *newDesc = (GF_ShortTextual *) gf_malloc(sizeof(GF_ShortTextual));
3032
  if (!newDesc) return NULL;
3033
3034
  newDesc->eventName = NULL;
3035
  newDesc->eventText = NULL;
3036
  newDesc->isUTF8 = 0;
3037
  newDesc->langCode = 0;
3038
  newDesc->tag = GF_ODF_SHORT_TEXT_TAG;
3039
  return (GF_Descriptor *) newDesc;
3040
}
3041
3042
GF_Err gf_odf_del_short_text(GF_ShortTextual *std)
3043
{
3044
  if (!std) return GF_BAD_PARAM;
3045
3046
  if (std->eventName) gf_free(std->eventName);
3047
  if (std->eventText) gf_free(std->eventText);
3048
  gf_free(std);
3049
  return GF_OK;
3050
}
3051
3052
GF_Err gf_odf_read_short_text(GF_BitStream *bs, GF_ShortTextual *std, u32 DescSize)
3053
{
3054
  GF_Err e;
3055
  u32 nbBytes = 0, len;
3056
  if (!std) return GF_BAD_PARAM;
3057
3058
  std->langCode = gf_bs_read_int(bs, 24);
3059
  std->isUTF8 = gf_bs_read_int(bs, 1);
3060
  /*aligned = */gf_bs_read_int(bs, 7);
3061
  nbBytes += 4;
3062
3063
  e = OD_ReadUTF8String(bs, & std->eventName, std->isUTF8, &len);
3064
  if (e) return e;
3065
  nbBytes += len;
3066
  e = OD_ReadUTF8String(bs, & std->eventText, std->isUTF8, &len);
3067
  if (e) return e;
3068
  nbBytes += len;
3069
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3070
  return GF_OK;
3071
}
3072
3073
GF_Err gf_odf_size_short_text(GF_ShortTextual *std, u32 *outSize)
3074
{
3075
  if (!std) return GF_BAD_PARAM;
3076
  *outSize = 4;
3077
  *outSize += OD_SizeUTF8String(std->eventName, std->isUTF8) + OD_SizeUTF8String(std->eventText, std->isUTF8);
3078
  return GF_OK;
3079
}
3080
3081
GF_Err gf_odf_write_short_text(GF_BitStream *bs, GF_ShortTextual *std)
3082
{
3083
  GF_Err e;
3084
  u32 size;
3085
  if (!std) return GF_BAD_PARAM;
3086
3087
  e = gf_odf_size_descriptor((GF_Descriptor *)std, &size);
3088
  if (e) return e;
3089
  e = gf_odf_write_base_descriptor(bs, std->tag, size);
3090
  if (e) return e;
3091
  gf_bs_write_int(bs, std->langCode, 24);
3092
  gf_bs_write_int(bs, std->isUTF8, 1);
3093
  gf_bs_write_int(bs, 0, 7);
3094
  OD_WriteUTF8String(bs, std->eventName, std->isUTF8);
3095
  OD_WriteUTF8String(bs, std->eventText, std->isUTF8);
3096
  return GF_OK;
3097
}
3098
3099
GF_Descriptor *gf_odf_new_smpte_camera()
3100
{
3101
  GF_SMPTECamera *newDesc = (GF_SMPTECamera *) gf_malloc(sizeof(GF_SMPTECamera));
3102
  if (!newDesc) return NULL;
3103
3104
  newDesc->ParamList = gf_list_new();
3105
  if (! newDesc->ParamList) {
3106
    gf_free(newDesc);
3107
    return NULL;
3108
  }
3109
  newDesc->cameraID = 0;
3110
  newDesc->tag = GF_ODF_SMPTE_TAG;
3111
  return (GF_Descriptor *) newDesc;
3112
}
3113
3114
GF_Err gf_odf_del_smpte_camera(GF_SMPTECamera *cpd)
3115
{
3116
  u32 i;
3117
  GF_SmpteParam *tmp;
3118
  if (!cpd) return GF_BAD_PARAM;
3119
3120
  i=0;
3121
  while ((tmp = (GF_SmpteParam *)gf_list_enum(cpd->ParamList, &i))) {
3122
    gf_free(tmp);
3123
  }
3124
  gf_list_del(cpd->ParamList);
3125
  gf_free(cpd);
3126
  return GF_OK;
3127
}
3128
GF_Err gf_odf_read_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd, u32 DescSize)
3129
{
3130
  GF_Err e;
3131
  u32 nbBytes = 0, i, count;
3132
  if (!cpd) return GF_BAD_PARAM;
3133
3134
  cpd->cameraID = gf_bs_read_int(bs, 8);
3135
  count = gf_bs_read_int(bs, 8);
3136
  nbBytes += 2;
3137
3138
  for (i=0; i< count ; i++) {
3139
    GF_SmpteParam *tmp = (GF_SmpteParam*)gf_malloc(sizeof(GF_SmpteParam));
3140
    if (! tmp) return GF_OUT_OF_MEM;
3141
    tmp->paramID = gf_bs_read_int(bs, 8);
3142
    tmp->param = gf_bs_read_int(bs, 32);
3143
    nbBytes += 5;
3144
    e = gf_list_add(cpd->ParamList, tmp);
3145
    if (e) return e;
3146
  }
3147
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3148
  return GF_OK;
3149
}
3150
3151
GF_Err gf_odf_size_smpte_camera(GF_SMPTECamera *cpd, u32 *outSize)
3152
{
3153
  if (!cpd) return GF_BAD_PARAM;
3154
  *outSize = 2 + 5 * gf_list_count(cpd->ParamList);
3155
  return GF_OK;
3156
}
3157
3158
GF_Err gf_odf_write_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd)
3159
{
3160
  GF_Err e;
3161
  GF_SmpteParam *tmp;
3162
  u32 size, i;
3163
  if (!cpd) return GF_BAD_PARAM;
3164
3165
  e = gf_odf_size_descriptor((GF_Descriptor *)cpd, &size);
3166
  if (e) return e;
3167
  e = gf_odf_write_base_descriptor(bs, cpd->tag, size);
3168
  if (e) return e;
3169
  gf_bs_write_int(bs, cpd->cameraID, 8);
3170
  gf_bs_write_int(bs, gf_list_count(cpd->ParamList), 8);
3171
3172
  i=0;
3173
  while ((tmp = (GF_SmpteParam *)gf_list_enum(cpd->ParamList, &i))) {
3174
    gf_bs_write_int(bs, tmp->paramID, 8);
3175
    gf_bs_write_int(bs, tmp->param, 32);
3176
  }
3177
  return GF_OK;
3178
}
3179
3180
GF_Descriptor *gf_odf_new_sup_cid()
3181
{
3182
  GF_SCIDesc *newDesc = (GF_SCIDesc *) gf_malloc(sizeof(GF_SCIDesc));
3183
  if (!newDesc) return NULL;
3184
  newDesc->supplContentIdentifierTitle = NULL;
3185
  newDesc->supplContentIdentifierValue  =NULL;
3186
  newDesc->languageCode = 0;
3187
  newDesc->tag = GF_ODF_SCI_TAG;
3188
  return (GF_Descriptor *) newDesc;
3189
}
3190
3191
GF_Err gf_odf_del_sup_cid(GF_SCIDesc *scid)
3192
{
3193
  if (!scid) return GF_BAD_PARAM;
3194
3195
  if (scid->supplContentIdentifierTitle) gf_free(scid->supplContentIdentifierTitle);
3196
  if (scid->supplContentIdentifierValue) gf_free(scid->supplContentIdentifierValue);
3197
  gf_free(scid);
3198
  return GF_OK;
3199
}
3200
3201
GF_Err gf_odf_read_sup_cid(GF_BitStream *bs, GF_SCIDesc *scid, u32 DescSize)
3202
{
3203
  GF_Err e;
3204
  u32 nbBytes = 0, len;
3205
  if (! scid) return GF_BAD_PARAM;
3206
3207
  scid->languageCode = gf_bs_read_int(bs, 24);
3208
  nbBytes += 3;
3209
  e = OD_ReadUTF8String(bs, & scid->supplContentIdentifierTitle, GF_TRUE, &len);
3210
  if (e) return e;
3211
  nbBytes += len;
3212
  e = OD_ReadUTF8String(bs, & scid->supplContentIdentifierValue, GF_TRUE, &len);
3213
  if (e) return e;
3214
  nbBytes += len;
3215
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3216
  return GF_OK;
3217
}
3218
3219
3220
GF_Err gf_odf_size_sup_cid(GF_SCIDesc *scid, u32 *outSize)
3221
{
3222
  if (! scid) return GF_BAD_PARAM;
3223
  *outSize = 3 + OD_SizeUTF8String(scid->supplContentIdentifierTitle, GF_TRUE) + OD_SizeUTF8String(scid->supplContentIdentifierValue, GF_TRUE);
3224
  return GF_OK;
3225
}
3226
GF_Err gf_odf_write_sup_cid(GF_BitStream *bs, GF_SCIDesc *scid)
3227
{
3228
  GF_Err e;
3229
  u32 size;
3230
  if (! scid) return GF_BAD_PARAM;
3231
  e = gf_odf_size_descriptor((GF_Descriptor *)scid, &size);
3232
  if (e) return e;
3233
  e = gf_odf_write_base_descriptor(bs, scid->tag, size);
3234
  if (e) return e;
3235
  gf_bs_write_int(bs, scid->languageCode, 24);
3236
  OD_WriteUTF8String(bs, scid->supplContentIdentifierTitle, GF_TRUE);
3237
  OD_WriteUTF8String(bs, scid->supplContentIdentifierValue, GF_TRUE);
3238
  return GF_OK;
3239
}
3240
3241
3242
/*IPMPX stuff*/
3243
GF_Descriptor *gf_odf_new_ipmp_tool_list()
3244
{
3245
  GF_IPMP_ToolList*newDesc = (GF_IPMP_ToolList*) gf_malloc(sizeof(GF_IPMP_ToolList));
3246
  if (!newDesc) return NULL;
3247
  newDesc->ipmp_tools = gf_list_new();
3248
  newDesc->tag = GF_ODF_IPMP_TL_TAG;
3249
  return (GF_Descriptor *) newDesc;
3250
}
3251
3252
GF_Err gf_odf_del_ipmp_tool_list(GF_IPMP_ToolList *ipmptl)
3253
{
3254
  if (!ipmptl) return GF_BAD_PARAM;
3255
3256
  while (gf_list_count(ipmptl->ipmp_tools)) {
3257
    GF_Descriptor *t = (GF_Descriptor *) gf_list_get(ipmptl->ipmp_tools, 0);
3258
    gf_list_rem(ipmptl->ipmp_tools, 0);
3259
    gf_odf_delete_descriptor(t);
3260
  }
3261
  gf_list_del(ipmptl->ipmp_tools);
3262
  gf_free(ipmptl);
3263
  return GF_OK;
3264
}
3265
3266
GF_Err gf_odf_read_ipmp_tool_list(GF_BitStream *bs, GF_IPMP_ToolList *ipmptl, u32 DescSize)
3267
{
3268
  GF_Err e;
3269
  u32 tmpSize;
3270
  u32 nbBytes = 0;
3271
  if (! ipmptl) return GF_BAD_PARAM;
3272
3273
  while (nbBytes < DescSize) {
3274
    GF_Descriptor *tmp = NULL;
3275
    e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
3276
    if (e) return e;
3277
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
3278
    e = gf_list_add(ipmptl->ipmp_tools, tmp);
3279
    if (e) return e;
3280
    nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
3281
  }
3282
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3283
  return GF_OK;
3284
}
3285
3286
3287
GF_Err gf_odf_size_ipmp_tool_list(GF_IPMP_ToolList *ipmptl, u32 *outSize)
3288
{
3289
  if (!ipmptl) return GF_BAD_PARAM;
3290
  *outSize = 0;
3291
  return gf_odf_size_descriptor_list(ipmptl->ipmp_tools, outSize);
3292
}
3293
3294
GF_Err gf_odf_write_ipmp_tool_list(GF_BitStream *bs, GF_IPMP_ToolList *ipmptl)
3295
{
3296
  GF_Err e;
3297
  u32 size;
3298
  if (!ipmptl) return GF_BAD_PARAM;
3299
  e = gf_odf_size_descriptor((GF_Descriptor *)ipmptl, &size);
3300
  if (e) return e;
3301
  e = gf_odf_write_base_descriptor(bs, ipmptl->tag, size);
3302
  if (e) return e;
3303
  return gf_odf_write_descriptor_list(bs, ipmptl->ipmp_tools);
3304
}
3305
3306
GF_Descriptor *gf_odf_new_ipmp_tool()
3307
{
3308
  GF_IPMP_Tool *newDesc = (GF_IPMP_Tool*) gf_malloc(sizeof(GF_IPMP_Tool));
3309
  if (!newDesc) return NULL;
3310
  memset(newDesc, 0, sizeof(GF_IPMP_Tool));
3311
  newDesc->tag = GF_ODF_IPMP_TL_TAG;
3312
  return (GF_Descriptor *) newDesc;
3313
}
3314
3315
GF_Err gf_odf_del_ipmp_tool(GF_IPMP_Tool *ipmpt)
3316
{
3317
  if (!ipmpt) return GF_BAD_PARAM;
3318
  if (ipmpt->tool_url) gf_free(ipmpt->tool_url);
3319
  gf_free(ipmpt);
3320
  return GF_OK;
3321
}
3322
3323
GF_Err gf_odf_read_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt, u32 DescSize)
3324
{
3325
  Bool is_alt, is_param;
3326
  u32 nbBytes = 0;
3327
  if (! ipmpt) return GF_BAD_PARAM;
3328
  gf_bs_read_data(bs, (char*) ipmpt->IPMP_ToolID, 16);
3329
  is_alt = (Bool)gf_bs_read_int(bs, 1);
3330
  is_param = (Bool)gf_bs_read_int(bs, 1);
3331
  gf_bs_read_int(bs, 6);
3332
  nbBytes = 17;
3333
3334
  if (is_alt) {
3335
    u32 i;
3336
    ipmpt->num_alternate = gf_bs_read_int(bs, 8);
3337
    nbBytes += 1;
3338
    for (i=0; i<ipmpt->num_alternate; i++) {
3339
      if (nbBytes + 16 > DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3340
      gf_bs_read_data(bs, (char*)ipmpt->specificToolID[i], 16);
3341
      nbBytes += 16;
3342
    }
3343
  }
3344
  if (nbBytes>DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3345
3346
  if (is_param) { }
3347
3348
  if (nbBytes<DescSize) {
3349
    u32 s;
3350
    nbBytes += gf_ipmpx_array_size(bs, &s);
3351
    if (s>0xFFFFFF) return GF_ODF_INVALID_DESCRIPTOR;
3352
3353
    if (s) {
3354
      ipmpt->tool_url = (char*)gf_malloc(sizeof(char)*(s+1));
3355
      gf_bs_read_data(bs, ipmpt->tool_url, s);
3356
      ipmpt->tool_url[s] = 0;
3357
      nbBytes += s;
3358
    }
3359
  }
3360
3361
  if (nbBytes!=DescSize) return GF_NON_COMPLIANT_BITSTREAM;
3362
  return GF_OK;
3363
}
3364
3365
3366
GF_Err gf_odf_size_ipmp_tool(GF_IPMP_Tool *ipmpt, u32 *outSize)
3367
{
3368
  if (!ipmpt) return GF_BAD_PARAM;
3369
  *outSize = 17;
3370
  if (ipmpt->num_alternate) *outSize += 1 + 16*ipmpt->num_alternate;
3371
3372
  if (ipmpt->tool_url) {
3373
    u32 s = (u32) strlen(ipmpt->tool_url);
3374
    *outSize += gf_odf_size_field_size(s) - 1 + s;
3375
  }
3376
  return GF_OK;
3377
}
3378
3379
GF_Err gf_odf_write_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt)
3380
{
3381
  GF_Err e;
3382
  u32 size;
3383
  if (!ipmpt) return GF_BAD_PARAM;
3384
  e = gf_odf_size_descriptor((GF_Descriptor *)ipmpt, &size);
3385
  if (e) return e;
3386
  e = gf_odf_write_base_descriptor(bs, ipmpt->tag, size);
3387
  if (e) return e;
3388
3389
  gf_bs_write_data(bs, (char*)ipmpt->IPMP_ToolID, 16);
3390
  gf_bs_write_int(bs, ipmpt->num_alternate ? 1 : 0, 1);
3391
  gf_bs_write_int(bs, 0, 1);
3392
  gf_bs_write_int(bs, 0, 6);
3393
3394
  if (ipmpt->num_alternate) {
3395
    u32 i;
3396
    gf_bs_write_int(bs, ipmpt->num_alternate, 8);
3397
    for (i=0; i<ipmpt->num_alternate; i++) gf_bs_write_data(bs, (char*)ipmpt->specificToolID[i], 16);
3398
  }
3399
  if (ipmpt->tool_url) gf_ipmpx_write_array(bs, ipmpt->tool_url, (u32) strlen(ipmpt->tool_url));
3400
  return GF_OK;
3401
}
3402
3403
#endif /*GPAC_MINIMAL_ODF*/