Coverage Report

Created: 2026-02-26 07:15

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
11.0k
{
72
11.0k
  u32 length;
73
11.0k
  *readBytes = 0;
74
75
  /*if the string is not NULL, return an error...*/
76
11.0k
  if (*string != NULL) return GF_BAD_PARAM;
77
78
  /*the len is always on 8 bits*/
79
11.0k
  length = gf_bs_read_int(bs, 8);
80
11.0k
  *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
11.0k
  if (!length) {
84
7.53k
    length = gf_bs_read_int(bs, 32);
85
7.53k
    *readBytes += 4;
86
7.53k
    if (length>0xFFFF) return GF_ODF_INVALID_DESCRIPTOR;
87
7.53k
  }
88
  /*we want to use strlen to get rid of "stringLength" => we need an extra 0*/
89
9.02k
  (*string) = (char *) gf_malloc(length + 1);
90
9.02k
  if (! *string) return GF_OUT_OF_MEM;
91
9.02k
  gf_bs_read_data(bs, (*string), length);
92
9.02k
  *readBytes += length;
93
9.02k
  (*string)[length] = 0;
94
9.02k
  return GF_OK;
95
9.02k
}
96
97
/*writes string*/
98
GF_Err gf_odf_write_url_string(GF_BitStream *bs, char *string)
99
1.82k
{
100
1.82k
  u32 len;
101
  /*we accept NULL strings now*/
102
1.82k
  if (!string) {
103
0
    gf_bs_write_int(bs, 0, 8);
104
0
    return GF_OK;
105
0
  }
106
1.82k
  len = (u32) strlen(string);
107
1.82k
  if (len > 255) {
108
0
    gf_bs_write_int(bs, 0, 8);
109
0
    gf_bs_write_int(bs, len, 32);
110
1.82k
  } else {
111
1.82k
    gf_bs_write_int(bs, len, 8);
112
1.82k
  }
113
1.82k
  gf_bs_write_data(bs, string, len);
114
1.82k
  return GF_OK;
115
1.82k
}
116
117
u32 gf_odf_size_url_string(char *string)
118
1.82k
{
119
1.82k
  u32 len = (u32) strlen(string);
120
1.82k
  if (len>255) return len+5;
121
1.82k
  return len+1;
122
1.82k
}
123
124
GF_Descriptor *gf_odf_new_esd()
125
34.5k
{
126
34.5k
  GF_ESD *newDesc = (GF_ESD *) gf_malloc(sizeof(GF_ESD));
127
34.5k
  if (!newDesc) return NULL;
128
34.5k
  memset(newDesc, 0, sizeof(GF_ESD));
129
34.5k
  newDesc->IPIDataSet = gf_list_new();
130
34.5k
  newDesc->IPMPDescriptorPointers = gf_list_new();
131
34.5k
  newDesc->extensionDescriptors = gf_list_new();
132
34.5k
  newDesc->tag = GF_ODF_ESD_TAG;
133
34.5k
  return (GF_Descriptor *) newDesc;
134
34.5k
}
135
136
137
GF_Err gf_odf_del_esd(GF_ESD *esd)
138
34.5k
{
139
34.5k
  GF_Err e;
140
34.5k
  if (!esd) return GF_BAD_PARAM;
141
34.5k
  if (esd->URLString)  gf_free(esd->URLString);
142
143
34.5k
  if (esd->decoderConfig)  {
144
13.4k
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->decoderConfig);
145
13.4k
    if (e) return e;
146
13.4k
  }
147
34.5k
  if (esd->slConfig) {
148
20.1k
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->slConfig);
149
20.1k
    if (e) return e;
150
20.1k
  }
151
34.5k
  if (esd->ipiPtr) {
152
0
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->ipiPtr);
153
0
    if (e) return e;
154
0
  }
155
34.5k
  if (esd->qos) {
156
0
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->qos);
157
0
    if (e) return e;
158
0
  }
159
34.5k
  if (esd->RegDescriptor)  {
160
0
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->RegDescriptor);
161
0
    if (e) return e;
162
0
  }
163
34.5k
  if (esd->langDesc)  {
164
2.18k
    e = gf_odf_delete_descriptor((GF_Descriptor *) esd->langDesc);
165
2.18k
    if (e) return e;
166
2.18k
  }
167
168
34.5k
  e = gf_odf_delete_descriptor_list(esd->IPIDataSet);
169
34.5k
  if (e) return e;
170
34.5k
  e = gf_odf_delete_descriptor_list(esd->IPMPDescriptorPointers);
171
34.5k
  if (e) return e;
172
34.5k
  e = gf_odf_delete_descriptor_list(esd->extensionDescriptors);
173
34.5k
  if (e) return e;
174
34.5k
  gf_free(esd);
175
34.5k
  return GF_OK;
176
34.5k
}
177
178
179
GF_Err AddDescriptorToESD(GF_ESD *esd, GF_Descriptor *desc)
180
43.5k
{
181
43.5k
  if (!esd || !desc) return GF_BAD_PARAM;
182
183
43.5k
  switch (desc->tag) {
184
1.30k
  case GF_ODF_DCD_TAG:
185
1.30k
    if (esd->decoderConfig) return GF_ODF_INVALID_DESCRIPTOR;
186
938
    esd->decoderConfig = (GF_DecoderConfig *) desc;
187
938
    break;
188
189
5.39k
  case GF_ODF_SLC_TAG:
190
5.39k
    if (esd->slConfig) return GF_ODF_INVALID_DESCRIPTOR;
191
3.72k
    esd->slConfig = (GF_SLConfig *) desc;
192
3.72k
    break;
193
194
0
  case GF_ODF_MUXINFO_TAG:
195
0
    gf_list_add(esd->extensionDescriptors, desc);
196
0
    break;
197
198
2.51k
  case GF_ODF_LANG_TAG:
199
2.51k
    if (esd->langDesc) return GF_ODF_INVALID_DESCRIPTOR;
200
2.18k
    esd->langDesc = (GF_Language *) desc;
201
2.18k
    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
34.3k
  default:
231
34.3k
    if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
232
17.2k
            (desc->tag <= GF_ODF_EXT_END_TAG) ) {
233
16.1k
      return gf_list_add(esd->extensionDescriptors, desc);
234
16.1k
    }
235
18.1k
    return GF_BAD_PARAM;
236
43.5k
  }
237
238
6.84k
  return GF_OK;
239
43.5k
}
240
241
GF_Err gf_odf_read_esd(GF_BitStream *bs, GF_ESD *esd, u32 DescSize)
242
21.9k
{
243
21.9k
  GF_Err e = GF_OK;
244
21.9k
  u32 ocrflag, urlflag, streamdependflag, tmp_size, nbBytes, read;
245
246
21.9k
  if (! esd) return GF_BAD_PARAM;
247
248
21.9k
  nbBytes = 0;
249
250
21.9k
  esd->ESID = gf_bs_read_int(bs, 16);
251
21.9k
  streamdependflag = gf_bs_read_int(bs, 1);
252
21.9k
  urlflag = gf_bs_read_int(bs, 1);
253
21.9k
  ocrflag = gf_bs_read_int(bs, 1);
254
21.9k
  esd->streamPriority = gf_bs_read_int(bs, 5);
255
21.9k
  nbBytes += 3;
256
257
21.9k
  if (streamdependflag) {
258
9.47k
    esd->dependsOnESID = gf_bs_read_int(bs, 16);
259
9.47k
    nbBytes += 2;
260
9.47k
  }
261
262
21.9k
  if (urlflag) {
263
2.85k
    e = gf_odf_read_url_string(bs, & esd->URLString, &read);
264
2.85k
    if (e) return e;
265
2.22k
    nbBytes += read;
266
2.22k
  }
267
21.3k
  if (ocrflag) {
268
10.1k
    esd->OCRESID = gf_bs_read_int(bs, 16);
269
10.1k
    nbBytes += 2;
270
10.1k
  }
271
272
39.2k
  while (nbBytes < DescSize) {
273
30.1k
    GF_Descriptor *tmp = NULL;
274
30.1k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
275
    /*fix for iPod files*/
276
30.1k
    if (e==GF_ODF_INVALID_DESCRIPTOR) {
277
9.24k
      nbBytes += tmp_size;
278
9.24k
      if (nbBytes>DescSize) return e;
279
6.98k
      gf_bs_read_int(bs, DescSize-nbBytes);
280
6.98k
      return GF_OK;
281
9.24k
    }
282
20.9k
    if (e) return e;
283
19.7k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
284
19.7k
    e = AddDescriptorToESD(esd, tmp);
285
19.7k
    if (e) {
286
1.83k
      gf_odf_desc_del(tmp);
287
1.83k
      return e;
288
1.83k
    }
289
17.8k
    nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
290
291
    //apple fix
292
17.8k
    if (!tmp_size) nbBytes = DescSize;
293
294
17.8k
  }
295
9.07k
  if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
296
7.44k
  return e;
297
298
9.07k
}
299
300
GF_Err gf_odf_size_esd(GF_ESD *esd, u32 *outSize)
301
4.55k
{
302
4.55k
  GF_Err e;
303
4.55k
  u32 tmpSize;
304
4.55k
  if (! esd) return GF_BAD_PARAM;
305
306
4.55k
  *outSize = 0;
307
4.55k
  *outSize += 3;
308
309
4.55k
  if (esd->dependsOnESID) *outSize += 2;
310
4.55k
  if (esd->URLString) *outSize += gf_odf_size_url_string(esd->URLString);
311
4.55k
  if (esd->OCRESID) *outSize += 2;
312
313
4.55k
  if (esd->decoderConfig) {
314
329
    e = gf_odf_size_descriptor((GF_Descriptor *) esd->decoderConfig, &tmpSize);
315
329
    if (e) return e;
316
329
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
317
329
  }
318
4.55k
  if (esd->slConfig) {
319
1.45k
    e = gf_odf_size_descriptor((GF_Descriptor *) esd->slConfig, &tmpSize);
320
1.45k
    if (e) return e;
321
1.45k
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
322
1.45k
  }
323
4.55k
  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.55k
  if (esd->langDesc) {
329
338
    e = gf_odf_size_descriptor((GF_Descriptor *) esd->langDesc, &tmpSize);
330
338
    if (e) return e;
331
338
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
332
338
  }
333
334
4.55k
  e = gf_odf_size_descriptor_list(esd->IPIDataSet, outSize);
335
4.55k
  if (e) return e;
336
4.55k
  e = gf_odf_size_descriptor_list(esd->IPMPDescriptorPointers, outSize);
337
4.55k
  if (e) return e;
338
4.55k
  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.55k
  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.55k
  return gf_odf_size_descriptor_list(esd->extensionDescriptors, outSize);
349
4.55k
}
350
351
GF_Err gf_odf_write_esd(GF_BitStream *bs, GF_ESD *esd)
352
4.26k
{
353
4.26k
  GF_Err e;
354
4.26k
  u32 size;
355
4.26k
  if (! esd) return GF_BAD_PARAM;
356
357
4.26k
  e = gf_odf_size_descriptor((GF_Descriptor *)esd, &size);
358
4.26k
  if (e) return e;
359
4.26k
  e = gf_odf_write_base_descriptor(bs, esd->tag, size);
360
4.26k
  if (e) return e;
361
362
4.26k
  gf_bs_write_int(bs, esd->ESID, 16);
363
4.26k
  gf_bs_write_int(bs, esd->dependsOnESID ? 1 : 0, 1);
364
4.26k
  gf_bs_write_int(bs, esd->URLString != NULL ? 1 : 0, 1);
365
4.26k
  gf_bs_write_int(bs, esd->OCRESID ? 1 : 0, 1);
366
4.26k
  gf_bs_write_int(bs, esd->streamPriority, 5);
367
368
4.26k
  if (esd->dependsOnESID) {
369
2.65k
    gf_bs_write_int(bs, esd->dependsOnESID, 16);
370
2.65k
  }
371
4.26k
  if (esd->URLString) {
372
416
    e = gf_odf_write_url_string(bs, esd->URLString);
373
416
    if (e) return e;
374
416
  }
375
376
377
4.26k
  if (esd->OCRESID) {
378
2.73k
    gf_bs_write_int(bs, esd->OCRESID, 16);
379
2.73k
  }
380
4.26k
  if (esd->decoderConfig) {
381
329
    e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->decoderConfig);
382
329
    if (e) return e;
383
329
  }
384
4.26k
  if (esd->slConfig) {
385
1.29k
    e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->slConfig);
386
1.29k
    if (e) return e;
387
1.29k
  }
388
4.26k
  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.26k
  if (esd->langDesc) {
393
338
    e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->langDesc);
394
338
    if (e) return e;
395
338
  }
396
397
4.26k
  e = gf_odf_write_descriptor_list(bs, esd->IPIDataSet);
398
4.26k
  if (e) return e;
399
4.26k
  e = gf_odf_write_descriptor_list(bs, esd->IPMPDescriptorPointers);
400
4.26k
  if (e) return e;
401
4.26k
  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.26k
  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.26k
  return gf_odf_write_descriptor_list(bs, esd->extensionDescriptors);
410
4.26k
}
411
412
GF_Descriptor *gf_odf_new_iod()
413
4.32k
{
414
4.32k
  GF_InitialObjectDescriptor *newDesc = (GF_InitialObjectDescriptor *) gf_malloc(sizeof(GF_InitialObjectDescriptor));
415
4.32k
  if (!newDesc) return NULL;
416
4.32k
  memset(newDesc, 0, sizeof(GF_InitialObjectDescriptor));
417
418
4.32k
  newDesc->ESDescriptors = gf_list_new();
419
4.32k
  newDesc->OCIDescriptors = gf_list_new();
420
4.32k
  newDesc->IPMP_Descriptors = gf_list_new();
421
422
4.32k
  newDesc->extensionDescriptors = gf_list_new();
423
4.32k
  newDesc->tag = GF_ODF_IOD_TAG;
424
4.32k
  return (GF_Descriptor *) newDesc;
425
4.32k
}
426
427
GF_Err gf_odf_del_iod(GF_InitialObjectDescriptor *iod)
428
4.32k
{
429
4.32k
  GF_Err e;
430
4.32k
  if (!iod) return GF_BAD_PARAM;
431
4.32k
  if (iod->URLString)  gf_free(iod->URLString);
432
4.32k
  e = gf_odf_delete_descriptor_list(iod->ESDescriptors);
433
4.32k
  if (e) return e;
434
4.32k
  e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
435
4.32k
  if (e) return e;
436
4.32k
  e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
437
4.32k
  if (e) return e;
438
4.32k
  e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
439
4.32k
  if (e) return e;
440
4.32k
  if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList);
441
4.32k
  gf_free(iod);
442
4.32k
  return GF_OK;
443
4.32k
}
444
445
GF_Err AddDescriptorToIOD(GF_InitialObjectDescriptor *iod, GF_Descriptor *desc)
446
5.66k
{
447
5.66k
  if (!iod || !desc) return GF_BAD_PARAM;
448
449
5.66k
  switch (desc->tag) {
450
357
  case GF_ODF_ESD_TAG:
451
357
    return gf_list_add(iod->ESDescriptors, desc);
452
453
  //we use the same struct for v1 and v2 IPMP DPs
454
282
  case GF_ODF_IPMP_PTR_TAG:
455
  /*IPMPX*/
456
1.22k
  case GF_ODF_IPMP_TAG:
457
1.22k
    return gf_list_add(iod->IPMP_Descriptors, desc);
458
459
  /*IPMPX*/
460
858
  case GF_ODF_IPMP_TL_TAG:
461
858
    if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
462
858
    iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
463
858
    return GF_OK;
464
465
3.23k
  default:
466
3.23k
    break;
467
5.66k
  }
468
3.23k
  if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) && (desc->tag <= GF_ODF_OCI_END_TAG) ) return gf_list_add(iod->OCIDescriptors, desc);
469
2.30k
  if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG) ) return gf_list_add(iod->extensionDescriptors, desc);
470
607
  return GF_BAD_PARAM;
471
2.30k
}
472
473
GF_Err gf_odf_read_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod, u32 DescSize)
474
4.32k
{
475
4.32k
  GF_Err e;
476
4.32k
  u32 urlflag, read;
477
4.32k
  u32 tmp_size, nbBytes = 0;
478
4.32k
  if (! iod) return GF_BAD_PARAM;
479
480
4.32k
  iod->objectDescriptorID = gf_bs_read_int(bs, 10);
481
4.32k
  urlflag = gf_bs_read_int(bs, 1);
482
4.32k
  iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
483
4.32k
  /*reserved = */gf_bs_read_int(bs, 4);
484
4.32k
  nbBytes += 2;
485
486
4.32k
  if (urlflag) {
487
1.26k
    e = gf_odf_read_url_string(bs, & iod->URLString, &read);
488
1.26k
    if (e) return e;
489
788
    nbBytes += read;
490
3.06k
  } else {
491
3.06k
    iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
492
3.06k
    iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
493
3.06k
    iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
494
3.06k
    iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
495
3.06k
    iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
496
3.06k
    nbBytes += 5;
497
3.06k
  }
498
499
8.91k
  while (nbBytes < DescSize) {
500
6.65k
    GF_Descriptor *tmp = NULL;
501
6.65k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
502
6.65k
    if (e) return e;
503
5.66k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
504
5.66k
    e = AddDescriptorToIOD(iod, tmp);
505
5.66k
    if (e) {
506
607
      gf_odf_delete_descriptor(tmp);
507
607
      return e;
508
607
    }
509
5.06k
    nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
510
5.06k
  }
511
2.26k
  if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
512
1.62k
  return GF_OK;
513
2.26k
}
514
515
GF_Err gf_odf_size_iod(GF_InitialObjectDescriptor *iod, u32 *outSize)
516
842
{
517
842
  GF_Err e;
518
842
  if (! iod) return GF_BAD_PARAM;
519
520
842
  *outSize = 0;
521
842
  *outSize += 2;
522
842
  if (iod->URLString) {
523
232
    *outSize += gf_odf_size_url_string(iod->URLString);
524
610
  } else {
525
610
    *outSize += 5;
526
610
    e = gf_odf_size_descriptor_list(iod->ESDescriptors, outSize);
527
610
    if (e) return e;
528
610
    e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
529
610
    if (e) return e;
530
610
    e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
531
610
    if (e) return e;
532
533
610
  }
534
842
  e = gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
535
842
  if (e) return e;
536
842
  if (iod->IPMPToolList) {
537
384
    u32 tmpSize;
538
384
    e = gf_odf_size_descriptor((GF_Descriptor *) iod->IPMPToolList, &tmpSize);
539
384
    if (e) return e;
540
384
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
541
384
  }
542
842
  return GF_OK;
543
842
}
544
545
GF_Err gf_odf_write_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod)
546
842
{
547
842
  GF_Err e;
548
842
  u32 size;
549
842
  if (! iod) return GF_BAD_PARAM;
550
551
842
  e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
552
842
  if (e) return e;
553
842
  e = gf_odf_write_base_descriptor(bs, iod->tag, size);
554
842
  if (e) return e;
555
556
842
  gf_bs_write_int(bs, iod->objectDescriptorID, 10);
557
842
  gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
558
842
  gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
559
842
  gf_bs_write_int(bs, 15, 4);   //reserved: 0b1111 == 15
560
561
842
  if (iod->URLString) {
562
232
    gf_odf_write_url_string(bs, iod->URLString);
563
610
  } else {
564
610
    gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
565
610
    gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
566
610
    gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
567
610
    gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
568
610
    gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
569
610
    e = gf_odf_write_descriptor_list(bs, iod->ESDescriptors);
570
610
    if (e) return e;
571
610
    e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
572
610
    if (e) return e;
573
610
    e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
574
610
    if (e) return e;
575
610
    e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
576
610
    if (e) return e;
577
610
    if (iod->IPMPToolList) {
578
384
      e = gf_odf_write_descriptor(bs, (GF_Descriptor *) iod->IPMPToolList);
579
384
      if (e) return e;
580
384
    }
581
610
  }
582
842
  return gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
583
842
}
584
585
586
587
GF_Descriptor *gf_odf_new_od()
588
4.73k
{
589
4.73k
  GF_ObjectDescriptor *newDesc;
590
4.73k
  GF_SAFEALLOC(newDesc, GF_ObjectDescriptor);
591
4.73k
  if (!newDesc) return NULL;
592
593
4.73k
  newDesc->URLString = NULL;
594
4.73k
  newDesc->ESDescriptors = gf_list_new();
595
4.73k
  newDesc->OCIDescriptors = gf_list_new();
596
4.73k
  newDesc->IPMP_Descriptors = gf_list_new();
597
4.73k
  newDesc->extensionDescriptors = gf_list_new();
598
4.73k
  newDesc->objectDescriptorID = 0;
599
4.73k
  newDesc->tag = GF_ODF_OD_TAG;
600
4.73k
  return (GF_Descriptor *) newDesc;
601
4.73k
}
602
603
GF_Err gf_odf_del_od(GF_ObjectDescriptor *od)
604
4.73k
{
605
4.73k
  GF_Err e;
606
4.73k
  if (!od) return GF_BAD_PARAM;
607
4.73k
  if (od->URLString)  gf_free(od->URLString);
608
4.73k
  e = gf_odf_delete_descriptor_list(od->ESDescriptors);
609
4.73k
  if (e) return e;
610
4.73k
  e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
611
4.73k
  if (e) return e;
612
4.73k
  e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
613
4.73k
  if (e) return e;
614
4.73k
  e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
615
4.73k
  if (e) return e;
616
4.73k
  gf_free(od);
617
4.73k
  return GF_OK;
618
4.73k
}
619
620
GF_Err AddDescriptorToOD(GF_ObjectDescriptor *od, GF_Descriptor *desc)
621
4.64k
{
622
4.64k
  if (!od || !desc) return GF_BAD_PARAM;
623
624
  //check if we can handle ContentClassif tags
625
4.64k
  if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
626
1.58k
          (desc->tag <= GF_ODF_OCI_END_TAG) ) {
627
426
    return gf_list_add(od->OCIDescriptors, desc);
628
426
  }
629
630
  //or extensions
631
4.22k
  if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
632
1.16k
          (desc->tag <= GF_ODF_EXT_END_TAG) ) {
633
1.09k
    return gf_list_add(od->extensionDescriptors, desc);
634
1.09k
  }
635
636
  //to cope with envivio
637
3.13k
  switch (desc->tag) {
638
607
  case GF_ODF_ESD_TAG:
639
883
  case GF_ODF_ESD_REF_TAG:
640
883
    return gf_list_add(od->ESDescriptors, desc);
641
642
  //we use the same struct for v1 and v2 IPMP DPs
643
1.76k
  case GF_ODF_IPMP_PTR_TAG:
644
1.86k
  case GF_ODF_IPMP_TAG:
645
1.86k
    return gf_list_add(od->IPMP_Descriptors, desc);
646
647
387
  default:
648
387
    return GF_BAD_PARAM;
649
3.13k
  }
650
3.13k
}
651
652
GF_Err gf_odf_read_od(GF_BitStream *bs, GF_ObjectDescriptor *od, u32 DescSize)
653
4.73k
{
654
4.73k
  GF_Err e;
655
4.73k
  u32 urlflag;
656
4.73k
  u32 tmpSize, nbBytes = 0;
657
4.73k
  if (! od) return GF_BAD_PARAM;
658
659
4.73k
  od->objectDescriptorID = gf_bs_read_int(bs, 10);
660
4.73k
  urlflag = gf_bs_read_int(bs, 1);
661
4.73k
  /*reserved = */gf_bs_read_int(bs, 5);
662
4.73k
  nbBytes += 2;
663
664
4.73k
  if (urlflag) {
665
1.40k
    u32 read;
666
1.40k
    e = gf_odf_read_url_string(bs, & od->URLString, &read);
667
1.40k
    if (e) return e;
668
1.20k
    nbBytes += read;
669
1.20k
  }
670
671
8.78k
  while (nbBytes < DescSize) {
672
5.35k
    GF_Descriptor *tmp = NULL;
673
5.35k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
674
5.35k
    if (e) return e;
675
4.64k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
676
4.64k
    e = AddDescriptorToOD(od, tmp);
677
4.64k
    if (e) {
678
387
      gf_odf_desc_del(tmp);
679
387
      return e;
680
387
    }
681
4.26k
    nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
682
4.26k
  }
683
3.43k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
684
2.14k
  return GF_OK;
685
3.43k
}
686
687
GF_Err gf_odf_size_od(GF_ObjectDescriptor *od, u32 *outSize)
688
1.30k
{
689
1.30k
  GF_Err e;
690
1.30k
  if (! od) return GF_BAD_PARAM;
691
692
1.30k
  *outSize = 2;
693
1.30k
  if (od->URLString) {
694
271
    *outSize += gf_odf_size_url_string(od->URLString);
695
1.03k
  } else {
696
1.03k
    e = gf_odf_size_descriptor_list(od->ESDescriptors, outSize);
697
1.03k
    if (e) return e;
698
1.03k
    e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
699
1.03k
    if (e) return e;
700
1.03k
    e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
701
1.03k
    if (e) return e;
702
1.03k
  }
703
1.30k
  return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
704
1.30k
}
705
706
GF_Err gf_odf_write_od(GF_BitStream *bs, GF_ObjectDescriptor *od)
707
1.30k
{
708
1.30k
  GF_Err e;
709
1.30k
  u32 size;
710
1.30k
  if (! od) return GF_BAD_PARAM;
711
712
1.30k
  e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
713
1.30k
  if (e) return e;
714
1.30k
  e = gf_odf_write_base_descriptor(bs, od->tag, size);
715
1.30k
  if (e) return e;
716
717
1.30k
  gf_bs_write_int(bs, od->objectDescriptorID, 10);
718
1.30k
  gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
719
1.30k
  gf_bs_write_int(bs, 31, 5);   //reserved: 0b1111.1 == 31
720
721
1.30k
  if (od->URLString) {
722
271
    gf_odf_write_url_string(bs, od->URLString);
723
1.03k
  } else {
724
1.03k
    e = gf_odf_write_descriptor_list(bs, od->ESDescriptors);
725
1.03k
    if (e) return e;
726
1.03k
    e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
727
1.03k
    if (e) return e;
728
1.03k
    e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
729
1.03k
    if (e) return e;
730
1.03k
    e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
731
1.03k
    if (e) return e;
732
1.03k
  }
733
1.30k
  return gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
734
1.30k
}
735
736
GF_Descriptor *gf_odf_new_isom_iod()
737
7.81k
{
738
7.81k
  GF_IsomInitialObjectDescriptor *newDesc = (GF_IsomInitialObjectDescriptor *) gf_malloc(sizeof(GF_IsomInitialObjectDescriptor));
739
7.81k
  if (!newDesc) return NULL;
740
7.81k
  memset(newDesc, 0, sizeof(GF_IsomInitialObjectDescriptor));
741
742
7.81k
  newDesc->ES_ID_IncDescriptors = gf_list_new();
743
7.81k
  newDesc->ES_ID_RefDescriptors = gf_list_new();
744
7.81k
  newDesc->OCIDescriptors = gf_list_new();
745
7.81k
  newDesc->IPMP_Descriptors = gf_list_new();
746
7.81k
  newDesc->extensionDescriptors = gf_list_new();
747
7.81k
  newDesc->tag = GF_ODF_ISOM_IOD_TAG;
748
749
  //by default create an IOD with no inline and no capabilities
750
7.81k
  newDesc->audio_profileAndLevel = 0xFF;
751
7.81k
  newDesc->graphics_profileAndLevel = 0xFF;
752
7.81k
  newDesc->scene_profileAndLevel = 0xFF;
753
7.81k
  newDesc->OD_profileAndLevel = 0xFF;
754
7.81k
  newDesc->visual_profileAndLevel = 0xFF;
755
7.81k
  return (GF_Descriptor *) newDesc;
756
7.81k
}
757
758
GF_Err gf_odf_del_isom_iod(GF_IsomInitialObjectDescriptor *iod)
759
7.81k
{
760
7.81k
  GF_Err e;
761
7.81k
  if (!iod) return GF_BAD_PARAM;
762
7.81k
  if (iod->URLString)  gf_free(iod->URLString);
763
7.81k
  e = gf_odf_delete_descriptor_list(iod->ES_ID_IncDescriptors);
764
7.81k
  if (e) return e;
765
7.81k
  e = gf_odf_delete_descriptor_list(iod->ES_ID_RefDescriptors);
766
7.81k
  if (e) return e;
767
7.81k
  e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
768
7.81k
  if (e) return e;
769
7.81k
  e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
770
7.81k
  if (e) return e;
771
7.81k
  e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
772
7.81k
  if (e) return e;
773
7.81k
  if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList);
774
7.81k
  gf_free(iod);
775
7.81k
  return GF_OK;
776
7.81k
}
777
778
GF_Err AddDescriptorToIsomIOD(GF_IsomInitialObjectDescriptor *iod, GF_Descriptor *desc)
779
26.3k
{
780
26.3k
  if (!iod || !desc) return GF_BAD_PARAM;
781
782
26.3k
  switch (desc->tag) {
783
375
  case GF_ODF_ESD_TAG:
784
375
    return GF_ODF_FORBIDDEN_DESCRIPTOR;
785
786
685
  case GF_ODF_ESD_INC_TAG:
787
    //there shouldn't be ref if inc
788
685
    if (gf_list_count(iod->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
789
507
    return gf_list_add(iod->ES_ID_IncDescriptors, desc);
790
791
487
  case GF_ODF_ESD_REF_TAG:
792
    //there shouldn't be inc if ref
793
487
    if (gf_list_count(iod->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
794
261
    return gf_list_add(iod->ES_ID_RefDescriptors, desc);
795
796
  //we use the same struct for v1 and v2 IPMP DPs
797
268
  case GF_ODF_IPMP_PTR_TAG:
798
2.16k
  case GF_ODF_IPMP_TAG:
799
2.16k
    return gf_list_add(iod->IPMP_Descriptors, desc);
800
801
  /*IPMPX*/
802
3.87k
  case GF_ODF_IPMP_TL_TAG:
803
3.87k
    if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
804
3.87k
    iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
805
3.87k
    return GF_OK;
806
807
18.7k
  default:
808
18.7k
    break;
809
26.3k
  }
810
  //check if we can handle ContentClassif tags
811
18.7k
  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
15.9k
  if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG) ) return gf_list_add(iod->extensionDescriptors, desc);
814
2.07k
  return GF_BAD_PARAM;
815
15.9k
}
816
817
GF_Err gf_odf_read_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod, u32 DescSize)
818
7.81k
{
819
7.81k
  u32 nbBytes = 0, tmpSize;
820
7.81k
  u32 urlflag;
821
7.81k
  GF_Err e;
822
7.81k
  if (! iod) return GF_BAD_PARAM;
823
824
7.81k
  iod->objectDescriptorID = gf_bs_read_int(bs, 10);
825
7.81k
  urlflag = gf_bs_read_int(bs, 1);
826
7.81k
  iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
827
7.81k
  /*reserved = */gf_bs_read_int(bs, 4);
828
7.81k
  nbBytes += 2;
829
830
7.81k
  if (urlflag) {
831
1.67k
    u32 read;
832
1.67k
    e = gf_odf_read_url_string(bs, & iod->URLString, &read);
833
1.67k
    if (e) return e;
834
1.33k
    nbBytes += read;
835
6.13k
  } else {
836
6.13k
    iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
837
6.13k
    iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
838
6.13k
    iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
839
6.13k
    iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
840
6.13k
    iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
841
6.13k
    nbBytes += 5;
842
6.13k
  }
843
844
31.0k
  while (nbBytes < DescSize) {
845
28.0k
    GF_Descriptor *tmp = NULL;
846
28.0k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
847
28.0k
    if (e) {
848
1.63k
      if (tmp) gf_odf_desc_del((GF_Descriptor *) tmp);
849
1.63k
      return e;
850
1.63k
    }
851
26.3k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
852
26.3k
    e = AddDescriptorToIsomIOD(iod, tmp);
853
26.3k
    if (e) {
854
2.85k
      gf_odf_desc_del(tmp);
855
2.85k
      return e;
856
2.85k
    }
857
23.5k
    nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
858
23.5k
  }
859
2.98k
  if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
860
1.79k
  return GF_OK;
861
2.98k
}
862
863
GF_Err gf_odf_size_isom_iod(GF_IsomInitialObjectDescriptor *iod, u32 *outSize)
864
1.04k
{
865
1.04k
  GF_Err e;
866
1.04k
  if (! iod) return GF_BAD_PARAM;
867
868
1.04k
  *outSize = 2;
869
1.04k
  if (iod->URLString) {
870
381
    *outSize += gf_odf_size_url_string(iod->URLString);
871
666
  } else {
872
666
    *outSize += 5;
873
666
    e = gf_odf_size_descriptor_list(iod->ES_ID_IncDescriptors, outSize);
874
666
    if (e) return e;
875
666
    e = gf_odf_size_descriptor_list(iod->ES_ID_RefDescriptors, outSize);
876
666
    if (e) return e;
877
666
    e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
878
666
    if (e) return e;
879
666
    e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
880
666
    if (e) return e;
881
666
  }
882
1.04k
  if (iod->IPMPToolList) {
883
397
    u32 tmpSize;
884
397
    e = gf_odf_size_descriptor((GF_Descriptor *) iod->IPMPToolList, &tmpSize);
885
397
    if (e) return e;
886
397
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
887
397
  }
888
1.04k
  return gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
889
1.04k
}
890
891
GF_Err gf_odf_write_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod)
892
1.04k
{
893
1.04k
  GF_Err e;
894
1.04k
  u32 size;
895
1.04k
  if (! iod) return GF_BAD_PARAM;
896
897
1.04k
  e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
898
1.04k
  if (e) return e;
899
1.04k
  e = gf_odf_write_base_descriptor(bs, iod->tag, size);
900
1.04k
  if (e) return e;
901
902
1.04k
  gf_bs_write_int(bs, iod->objectDescriptorID, 10);
903
1.04k
  gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
904
1.04k
  gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
905
1.04k
  gf_bs_write_int(bs, 15, 4);   //reserved: 0b1111 == 15
906
907
1.04k
  if (iod->URLString) {
908
381
    gf_odf_write_url_string(bs, iod->URLString);
909
666
  } else {
910
666
    gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
911
666
    gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
912
666
    gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
913
666
    gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
914
666
    gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
915
666
    e = gf_odf_write_descriptor_list(bs, iod->ES_ID_IncDescriptors);
916
666
    if (e) return e;
917
666
    e = gf_odf_write_descriptor_list(bs, iod->ES_ID_RefDescriptors);
918
666
    if (e) return e;
919
666
    e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
920
666
    if (e) return e;
921
666
    e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
922
666
    if (e) return e;
923
666
    e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
924
666
    if (e) return e;
925
666
    if (iod->IPMPToolList) {
926
397
      e = gf_odf_write_descriptor(bs, (GF_Descriptor *) iod->IPMPToolList);
927
397
      if (e) return e;
928
397
    }
929
666
  }
930
1.04k
  e = gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
931
1.04k
  if (e) return e;
932
1.04k
  return GF_OK;
933
1.04k
}
934
935
936
GF_Descriptor *gf_odf_new_isom_od()
937
8.57k
{
938
8.57k
  GF_IsomObjectDescriptor *newDesc = (GF_IsomObjectDescriptor *) gf_malloc(sizeof(GF_IsomObjectDescriptor));
939
8.57k
  if (!newDesc) return NULL;
940
941
8.57k
  newDesc->URLString = NULL;
942
8.57k
  newDesc->ES_ID_IncDescriptors = gf_list_new();
943
8.57k
  newDesc->ES_ID_RefDescriptors = gf_list_new();
944
8.57k
  newDesc->OCIDescriptors = gf_list_new();
945
8.57k
  newDesc->IPMP_Descriptors = gf_list_new();
946
8.57k
  newDesc->extensionDescriptors = gf_list_new();
947
8.57k
  newDesc->objectDescriptorID = 0;
948
8.57k
  newDesc->tag = GF_ODF_ISOM_OD_TAG;
949
8.57k
  return (GF_Descriptor *) newDesc;
950
8.57k
}
951
952
GF_Err gf_odf_del_isom_od(GF_IsomObjectDescriptor *od)
953
8.57k
{
954
8.57k
  GF_Err e;
955
8.57k
  if (!od) return GF_BAD_PARAM;
956
8.57k
  if (od->URLString)  gf_free(od->URLString);
957
8.57k
  e = gf_odf_delete_descriptor_list(od->ES_ID_IncDescriptors);
958
8.57k
  if (e) return e;
959
8.57k
  e = gf_odf_delete_descriptor_list(od->ES_ID_RefDescriptors);
960
8.57k
  if (e) return e;
961
8.57k
  e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
962
8.57k
  if (e) return e;
963
8.57k
  e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
964
8.57k
  if (e) return e;
965
8.57k
  e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
966
8.57k
  if (e) return e;
967
8.57k
  gf_free(od);
968
8.57k
  return GF_OK;
969
8.57k
}
970
971
GF_Err AddDescriptorToIsomOD(GF_IsomObjectDescriptor *od, GF_Descriptor *desc)
972
7.66k
{
973
7.66k
  if (!od || !desc) return GF_BAD_PARAM;
974
975
  //check if we can handle ContentClassif tags
976
7.66k
  if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
977
3.98k
          (desc->tag <= GF_ODF_OCI_END_TAG) ) {
978
597
    return gf_list_add(od->OCIDescriptors, desc);
979
597
  }
980
981
  //or extension ...
982
7.06k
  if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
983
3.39k
          (desc->tag <= GF_ODF_EXT_END_TAG) ) {
984
3.14k
    return gf_list_add(od->extensionDescriptors, desc);
985
3.14k
  }
986
987
3.92k
  switch (desc->tag) {
988
291
  case GF_ODF_ESD_TAG:
989
291
    return GF_ODF_FORBIDDEN_DESCRIPTOR;
990
991
357
  case GF_ODF_ESD_INC_TAG:
992
    //there shouldn't be ref if inc
993
357
    if (gf_list_count(od->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
994
239
    return gf_list_add(od->ES_ID_IncDescriptors, desc);
995
996
258
  case GF_ODF_ESD_REF_TAG:
997
    //there shouldn't be inc if ref
998
258
    if (gf_list_count(od->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
999
118
    return gf_list_add(od->ES_ID_RefDescriptors, desc);
1000
1001
  //we use the same struct for v1 and v2 IPMP DPs
1002
423
  case GF_ODF_IPMP_PTR_TAG:
1003
2.24k
  case GF_ODF_IPMP_TAG:
1004
2.24k
    return gf_list_add(od->IPMP_Descriptors, desc);
1005
1006
775
  default:
1007
775
    return GF_BAD_PARAM;
1008
3.92k
  }
1009
3.92k
}
1010
1011
GF_Err gf_odf_read_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od, u32 DescSize)
1012
8.57k
{
1013
8.57k
  GF_Err e;
1014
8.57k
  u32 urlflag;
1015
8.57k
  u32 tmpSize, nbBytes = 0;
1016
8.57k
  if (! od) return GF_BAD_PARAM;
1017
1018
8.57k
  od->objectDescriptorID = gf_bs_read_int(bs, 10);
1019
8.57k
  urlflag = gf_bs_read_int(bs, 1);
1020
8.57k
  /*reserved = */gf_bs_read_int(bs, 5);
1021
8.57k
  nbBytes += 2;
1022
1023
8.57k
  if (urlflag) {
1024
3.87k
    u32 read;
1025
3.87k
    e = gf_odf_read_url_string(bs, & od->URLString, &read);
1026
3.87k
    if (e) return e;
1027
3.47k
    nbBytes += read;
1028
3.47k
  }
1029
1030
14.5k
  while (nbBytes < DescSize) {
1031
10.8k
    GF_Descriptor *tmp = NULL;
1032
10.8k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
1033
10.8k
    if (e) return e;
1034
7.66k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
1035
7.66k
    e = AddDescriptorToIsomOD(od, tmp);
1036
7.66k
    if (e) {
1037
1.32k
      gf_odf_delete_descriptor(tmp);
1038
1.32k
      return e;
1039
1.32k
    }
1040
6.33k
    nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
1041
6.33k
  }
1042
3.65k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1043
2.55k
  return GF_OK;
1044
3.65k
}
1045
1046
GF_Err gf_odf_size_isom_od(GF_IsomObjectDescriptor *od, u32 *outSize)
1047
1.04k
{
1048
1.04k
  GF_Err e;
1049
1.04k
  if (! od) return GF_BAD_PARAM;
1050
1051
1.04k
  *outSize = 2;
1052
1.04k
  if (od->URLString) {
1053
528
    *outSize += gf_odf_size_url_string(od->URLString);
1054
528
  } else {
1055
518
    e = gf_odf_size_descriptor_list(od->ES_ID_IncDescriptors, outSize);
1056
518
    if (e) return e;
1057
518
    e = gf_odf_size_descriptor_list(od->ES_ID_RefDescriptors, outSize);
1058
518
    if (e) return e;
1059
518
    e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
1060
518
    if (e) return e;
1061
518
    e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
1062
518
    if (e) return e;
1063
518
  }
1064
1.04k
  return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
1065
1.04k
}
1066
1067
GF_Err gf_odf_write_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od)
1068
1.04k
{
1069
1.04k
  GF_Err e;
1070
1.04k
  u32 size;
1071
1.04k
  if (! od) return GF_BAD_PARAM;
1072
1073
1.04k
  e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
1074
1.04k
  if (e) return e;
1075
1.04k
  e = gf_odf_write_base_descriptor(bs, od->tag, size);
1076
1.04k
  if (e) return e;
1077
1078
1.04k
  gf_bs_write_int(bs, od->objectDescriptorID, 10);
1079
1.04k
  gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
1080
1.04k
  gf_bs_write_int(bs, 31, 5);   //reserved: 0b1111.1 == 31
1081
1082
1.04k
  if (od->URLString) {
1083
528
    gf_odf_write_url_string(bs, od->URLString);
1084
528
  } else {
1085
518
    e = gf_odf_write_descriptor_list(bs, od->ES_ID_IncDescriptors);
1086
518
    if (e) return e;
1087
518
    e = gf_odf_write_descriptor_list(bs, od->ES_ID_RefDescriptors);
1088
518
    if (e) return e;
1089
518
    e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
1090
518
    if (e) return e;
1091
518
    e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
1092
518
    if (e) return e;
1093
518
    e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
1094
518
    if (e) return e;
1095
518
  }
1096
1.04k
  e = gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
1097
1.04k
  if (e) return e;
1098
1.04k
  return GF_OK;
1099
1.04k
}
1100
1101
1102
1103
GF_Descriptor *gf_odf_new_dcd()
1104
23.5k
{
1105
23.5k
  GF_DecoderConfig *newDesc;
1106
23.5k
  GF_SAFEALLOC(newDesc, GF_DecoderConfig);
1107
23.5k
  if (!newDesc) return NULL;
1108
1109
23.5k
  newDesc->profileLevelIndicationIndexDescriptor = gf_list_new();
1110
23.5k
  newDesc->tag = GF_ODF_DCD_TAG;
1111
23.5k
  return (GF_Descriptor *) newDesc;
1112
23.5k
}
1113
1114
GF_Err gf_odf_del_dcd(GF_DecoderConfig *dcd)
1115
23.5k
{
1116
23.5k
  GF_Err e;
1117
23.5k
  if (!dcd) return GF_BAD_PARAM;
1118
23.5k
  if (dcd->decoderSpecificInfo) {
1119
19.9k
    e = gf_odf_delete_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo);
1120
19.9k
    if (e) return e;
1121
19.9k
  }
1122
23.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
23.5k
  e = gf_odf_delete_descriptor_list(dcd->profileLevelIndicationIndexDescriptor);
1127
23.5k
  if (e) return e;
1128
23.5k
  gf_free(dcd);
1129
23.5k
  return GF_OK;
1130
23.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
29.4k
  while (nbBytes < DescSize) {
1148
21.1k
    GF_Descriptor *tmp = NULL;
1149
21.1k
    e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
1150
21.1k
    if (e) return e;
1151
19.2k
    if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
1152
19.2k
    switch (tmp->tag) {
1153
7.69k
    case GF_ODF_DSI_TAG:
1154
7.69k
      if (dcd->decoderSpecificInfo) {
1155
219
        gf_odf_delete_descriptor(tmp);
1156
219
        return GF_ODF_INVALID_DESCRIPTOR;
1157
219
      }
1158
7.47k
      dcd->decoderSpecificInfo = (GF_DefaultDescriptor *) tmp;
1159
7.47k
      break;
1160
1161
787
    case GF_ODF_EXT_PL_TAG:
1162
787
      e = gf_list_add(dcd->profileLevelIndicationIndexDescriptor, tmp);
1163
787
      if (e < GF_OK) {
1164
0
        gf_odf_delete_descriptor(tmp);
1165
0
        return e;
1166
0
      }
1167
787
      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
787
    case GF_ODF_SLC_TAG:
1172
606
      gf_odf_delete_descriptor(tmp);
1173
606
      return GF_OK;
1174
1175
    //what the hell is this descriptor ?? Don't know, so delete it !
1176
10.1k
    default:
1177
10.1k
      gf_odf_delete_descriptor(tmp);
1178
10.1k
      break;
1179
19.2k
    }
1180
18.4k
    nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
1181
18.4k
  }
1182
8.27k
  if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1183
7.84k
  return GF_OK;
1184
8.27k
}
1185
1186
#include <gpac/constants.h>
1187
1188
GF_Err gf_odf_size_dcd(GF_DecoderConfig *dcd, u32 *outSize)
1189
997
{
1190
997
  GF_Err e;
1191
997
  u32 tmpSize;
1192
997
  u32 oti;
1193
997
  if (! dcd) return GF_BAD_PARAM;
1194
1195
997
  oti = dcd->objectTypeIndication;
1196
997
  if (oti > 0xFF) {
1197
0
    oti = gf_codecid_oti(oti);
1198
0
  }
1199
997
  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
997
  *outSize = 0;
1205
997
  *outSize += 13;
1206
997
  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
241
    e = gf_odf_size_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo , &tmpSize);
1211
241
    if (e) return e;
1212
241
    *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
1213
241
  }
1214
997
  e = gf_odf_size_descriptor_list(dcd->profileLevelIndicationIndexDescriptor, outSize);
1215
997
  if (e) return e;
1216
997
  return GF_OK;
1217
997
}
1218
1219
GF_Err gf_odf_write_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd)
1220
668
{
1221
668
  GF_Err e;
1222
668
  u32 size, oti;
1223
668
  if (! dcd) return GF_BAD_PARAM;
1224
1225
668
  oti = dcd->objectTypeIndication;
1226
668
  if (oti > 0xFF) {
1227
0
    oti = gf_codecid_oti(oti);
1228
0
  }
1229
668
  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
668
  e = gf_odf_size_descriptor((GF_Descriptor *)dcd, &size);
1235
668
  if (e) return e;
1236
668
  e = gf_odf_write_base_descriptor(bs, dcd->tag, size);
1237
668
  if (e) return e;
1238
1239
668
  gf_bs_write_int(bs, oti, 8);
1240
668
  gf_bs_write_int(bs, dcd->streamType, 6);
1241
668
  gf_bs_write_int(bs, dcd->upstream, 1);
1242
668
  gf_bs_write_int(bs, 1, 1);  //reserved field...
1243
668
  gf_bs_write_int(bs, dcd->bufferSizeDB, 24);
1244
668
  gf_bs_write_int(bs, dcd->maxBitrate, 32);
1245
668
  gf_bs_write_int(bs, dcd->avgBitrate, 32);
1246
1247
668
  if (dcd->decoderSpecificInfo) {
1248
241
    e = gf_odf_write_descriptor(bs, (GF_Descriptor *) dcd->decoderSpecificInfo);
1249
241
    if (e) return e;
1250
241
  }
1251
668
  e = gf_odf_write_descriptor_list(bs, dcd->profileLevelIndicationIndexDescriptor);
1252
668
  return e;
1253
668
}
1254
1255
1256
GF_Descriptor *gf_odf_new_default()
1257
444k
{
1258
444k
  GF_DefaultDescriptor *newDesc = (GF_DefaultDescriptor *) gf_malloc(sizeof(GF_DefaultDescriptor));
1259
444k
  if (!newDesc) return NULL;
1260
1261
444k
  newDesc->dataLength = 0;
1262
444k
  newDesc->data = NULL;
1263
  //set it to the Max allowed
1264
444k
  newDesc->tag = GF_ODF_USER_END_TAG;
1265
444k
  return (GF_Descriptor *) newDesc;
1266
444k
}
1267
1268
GF_Err gf_odf_del_default(GF_DefaultDescriptor *dd)
1269
444k
{
1270
444k
  if (!dd) return GF_BAD_PARAM;
1271
1272
444k
  if (dd->data) gf_free(dd->data);
1273
444k
  gf_free(dd);
1274
444k
  return GF_OK;
1275
444k
}
1276
1277
GF_Err gf_odf_read_default(GF_BitStream *bs, GF_DefaultDescriptor *dd, u32 DescSize)
1278
444k
{
1279
444k
  u32 nbBytes = 0;
1280
444k
  if (! dd) return GF_BAD_PARAM;
1281
1282
444k
  dd->dataLength = DescSize;
1283
444k
  dd->data = NULL;
1284
444k
  if (DescSize) {
1285
39.3k
    dd->data = (char*)gf_malloc(dd->dataLength);
1286
39.3k
    if (! dd->data) return GF_OUT_OF_MEM;
1287
39.3k
    gf_bs_read_data(bs, dd->data, dd->dataLength);
1288
39.3k
    nbBytes += dd->dataLength;
1289
    /* internal tags are read as default but deleted as their own types
1290
       so dd->data would leak here */
1291
39.3k
    if ((dd->tag>=GF_ODF_MUXINFO_TAG) && (dd->tag<=GF_ODF_LASER_CFG_TAG)) {
1292
5.57k
      gf_free(dd->data);
1293
5.57k
      dd->data = NULL;
1294
5.57k
    }
1295
39.3k
  }
1296
444k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1297
444k
  return GF_OK;
1298
444k
}
1299
1300
GF_Err gf_odf_size_default(GF_DefaultDescriptor *dd, u32 *outSize)
1301
65.1k
{
1302
65.1k
  if (! dd) return GF_BAD_PARAM;
1303
65.1k
  *outSize  = dd->dataLength;
1304
65.1k
  return GF_OK;
1305
65.1k
}
1306
1307
GF_Err gf_odf_write_default(GF_BitStream *bs, GF_DefaultDescriptor *dd)
1308
56.9k
{
1309
56.9k
  GF_Err e;
1310
56.9k
  u32 size;
1311
56.9k
  if (! dd) return GF_BAD_PARAM;
1312
1313
56.9k
  e = gf_odf_size_descriptor((GF_Descriptor *)dd, &size);
1314
56.9k
  if (e) return e;
1315
56.9k
  e = gf_odf_write_base_descriptor(bs, dd->tag, size);
1316
56.9k
  if (e) return e;
1317
1318
21.4k
  if (dd->data) {
1319
7.31k
    gf_bs_write_data(bs, dd->data, dd->dataLength);
1320
7.31k
  }
1321
21.4k
  return GF_OK;
1322
56.9k
}
1323
1324
GF_Descriptor *gf_odf_new_esd_inc()
1325
1.52k
{
1326
1.52k
  GF_ES_ID_Inc *newDesc = (GF_ES_ID_Inc *) gf_malloc(sizeof(GF_ES_ID_Inc));
1327
1.52k
  if (!newDesc) return NULL;
1328
1.52k
  newDesc->tag = GF_ODF_ESD_INC_TAG;
1329
1.52k
  newDesc->trackID = 0;
1330
1.52k
  return (GF_Descriptor *) newDesc;
1331
1.52k
}
1332
1333
GF_Err gf_odf_del_esd_inc(GF_ES_ID_Inc *esd_inc)
1334
1.52k
{
1335
1.52k
  if (!esd_inc) return GF_BAD_PARAM;
1336
1.52k
  gf_free(esd_inc);
1337
1.52k
  return GF_OK;
1338
1.52k
}
1339
GF_Err gf_odf_read_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc, u32 DescSize)
1340
1.52k
{
1341
1.52k
  u32 nbBytes = 0;
1342
1.52k
  if (! esd_inc) return GF_BAD_PARAM;
1343
1344
1.52k
  esd_inc->trackID = gf_bs_read_int(bs, 32);
1345
1.52k
  nbBytes += 4;
1346
1.52k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1347
1.30k
  return GF_OK;
1348
1.52k
}
1349
GF_Err gf_odf_size_esd_inc(GF_ES_ID_Inc *esd_inc, u32 *outSize)
1350
107
{
1351
107
  if (! esd_inc) return GF_BAD_PARAM;
1352
107
  *outSize = 4;
1353
107
  return GF_OK;
1354
107
}
1355
GF_Err gf_odf_write_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc)
1356
107
{
1357
107
  GF_Err e;
1358
107
  u32 size;
1359
107
  if (! esd_inc) return GF_BAD_PARAM;
1360
1361
107
  e = gf_odf_size_descriptor((GF_Descriptor *)esd_inc, &size);
1362
107
  if (e) return e;
1363
107
  e = gf_odf_write_base_descriptor(bs, esd_inc->tag, size);
1364
107
  if (e) return e;
1365
107
  gf_bs_write_int(bs, esd_inc->trackID, 32);
1366
107
  return GF_OK;
1367
107
}
1368
1369
GF_Descriptor *gf_odf_new_esd_ref()
1370
4.82k
{
1371
4.82k
  GF_ES_ID_Ref *newDesc = (GF_ES_ID_Ref *) gf_malloc(sizeof(GF_ES_ID_Ref));
1372
4.82k
  if (!newDesc) return NULL;
1373
4.82k
  newDesc->tag = GF_ODF_ESD_REF_TAG;
1374
4.82k
  newDesc->trackRef = 0;
1375
4.82k
  return (GF_Descriptor *) newDesc;
1376
4.82k
}
1377
1378
GF_Err gf_odf_del_esd_ref(GF_ES_ID_Ref *esd_ref)
1379
4.82k
{
1380
4.82k
  if (!esd_ref) return GF_BAD_PARAM;
1381
4.82k
  gf_free(esd_ref);
1382
4.82k
  return GF_OK;
1383
4.82k
}
1384
GF_Err gf_odf_read_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref, u32 DescSize)
1385
4.82k
{
1386
4.82k
  u32 nbBytes = 0;
1387
4.82k
  if (! esd_ref) return GF_BAD_PARAM;
1388
1389
4.82k
  esd_ref->trackRef = gf_bs_read_int(bs, 16);
1390
4.82k
  nbBytes += 2;
1391
4.82k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1392
4.47k
  return GF_OK;
1393
4.82k
}
1394
1395
GF_Err gf_odf_size_esd_ref(GF_ES_ID_Ref *esd_ref, u32 *outSize)
1396
1.72k
{
1397
1.72k
  if (! esd_ref) return GF_BAD_PARAM;
1398
1.72k
  *outSize = 2;
1399
1.72k
  return GF_OK;
1400
1.72k
}
1401
GF_Err gf_odf_write_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref)
1402
1.62k
{
1403
1.62k
  GF_Err e;
1404
1.62k
  u32 size;
1405
1.62k
  if (! esd_ref) return GF_BAD_PARAM;
1406
1407
1.62k
  e = gf_odf_size_descriptor((GF_Descriptor *)esd_ref, &size);
1408
1.62k
  if (e) return e;
1409
1.62k
  e = gf_odf_write_base_descriptor(bs, esd_ref->tag, size);
1410
1.62k
  if (e) return e;
1411
1412
1.62k
  gf_bs_write_int(bs, esd_ref->trackRef, 16);
1413
1.62k
  return GF_OK;
1414
1.62k
}
1415
1416
1417
1418
GF_Descriptor *gf_odf_new_segment()
1419
1.26k
{
1420
1.26k
  GF_Segment *newDesc = (GF_Segment *) gf_malloc(sizeof(GF_Segment));
1421
1.26k
  if (!newDesc) return NULL;
1422
1423
1.26k
  memset(newDesc, 0, sizeof(GF_Segment));
1424
1.26k
  newDesc->tag = GF_ODF_SEGMENT_TAG;
1425
1.26k
  return (GF_Descriptor *) newDesc;
1426
1.26k
}
1427
1428
GF_Err gf_odf_del_segment(GF_Segment *sd)
1429
1.26k
{
1430
1.26k
  if (!sd) return GF_BAD_PARAM;
1431
1432
1.26k
  if (sd->SegmentName) gf_free(sd->SegmentName);
1433
1.26k
  gf_free(sd);
1434
1.26k
  return GF_OK;
1435
1.26k
}
1436
1437
GF_Err gf_odf_read_segment(GF_BitStream *bs, GF_Segment *sd, u32 DescSize)
1438
1.26k
{
1439
1.26k
  u32 size, nbBytes = 0;
1440
1.26k
  if (!sd) return GF_BAD_PARAM;
1441
1442
1.26k
  sd->startTime = gf_bs_read_double(bs);
1443
1.26k
  sd->Duration = gf_bs_read_double(bs);
1444
1.26k
  nbBytes += 16;
1445
1.26k
  size = gf_bs_read_int(bs, 8);
1446
1.26k
  nbBytes += 1;
1447
1.26k
  if (size) {
1448
791
    sd->SegmentName = (char*) gf_malloc(sizeof(char)*(size+1));
1449
791
    if (!sd->SegmentName) return GF_OUT_OF_MEM;
1450
791
    gf_bs_read_data(bs, sd->SegmentName, size);
1451
791
    sd->SegmentName[size] = 0;
1452
791
    nbBytes += size;
1453
791
  }
1454
1.26k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1455
189
  return GF_OK;
1456
1.26k
}
1457
1458
GF_Err gf_odf_size_segment(GF_Segment *sd, u32 *outSize)
1459
37
{
1460
37
  if (!sd) return GF_BAD_PARAM;
1461
37
  *outSize = 17;
1462
37
  if (sd->SegmentName) *outSize += (u32) strlen(sd->SegmentName);
1463
37
  return GF_OK;
1464
37
}
1465
1466
GF_Err gf_odf_write_segment(GF_BitStream *bs, GF_Segment *sd)
1467
37
{
1468
37
  GF_Err e;
1469
37
  u32 size;
1470
37
  if (!sd) return GF_BAD_PARAM;
1471
37
  e = gf_odf_size_descriptor((GF_Descriptor *)sd, &size);
1472
37
  if (e) return e;
1473
37
  e = gf_odf_write_base_descriptor(bs, sd->tag, size);
1474
37
  if (e) return e;
1475
37
  gf_bs_write_double(bs, sd->startTime);
1476
37
  gf_bs_write_double(bs, sd->Duration);
1477
37
  if (sd->SegmentName) {
1478
27
    gf_bs_write_int(bs, (u32) strlen(sd->SegmentName), 8);
1479
27
    gf_bs_write_data(bs, sd->SegmentName, (u32) strlen(sd->SegmentName));
1480
27
  } else {
1481
10
    gf_bs_write_int(bs, 0, 8);
1482
10
  }
1483
37
  return GF_OK;
1484
37
}
1485
1486
1487
1488
GF_Descriptor *gf_odf_new_lang()
1489
4.30k
{
1490
4.30k
  GF_Language *newDesc;
1491
4.30k
  GF_SAFEALLOC(newDesc, GF_Language);
1492
4.30k
  if (!newDesc) return NULL;
1493
4.30k
  newDesc->tag = GF_ODF_LANG_TAG;
1494
4.30k
  return (GF_Descriptor *) newDesc;
1495
4.30k
}
1496
1497
GF_Err gf_odf_del_lang(GF_Language *ld)
1498
4.30k
{
1499
4.30k
  if (!ld) return GF_BAD_PARAM;
1500
4.30k
  if (ld->full_lang_code) gf_free(ld->full_lang_code);
1501
4.30k
  gf_free(ld);
1502
4.30k
  return GF_OK;
1503
4.30k
}
1504
1505
GF_Err gf_odf_read_lang(GF_BitStream *bs, GF_Language *ld, u32 DescSize)
1506
4.30k
{
1507
4.30k
  u32 nbBytes = 0;
1508
4.30k
  if (!ld) return GF_BAD_PARAM;
1509
1510
4.30k
  ld->langCode = gf_bs_read_int(bs, 24);
1511
4.30k
  nbBytes += 3;
1512
4.30k
  if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1513
3.52k
  return GF_OK;
1514
4.30k
}
1515
1516
GF_Err gf_odf_size_lang(GF_Language *ld, u32 *outSize)
1517
1.52k
{
1518
1.52k
  if (!ld) return GF_BAD_PARAM;
1519
1.52k
  *outSize = 3;
1520
1.52k
  return GF_OK;
1521
1.52k
}
1522
1523
GF_Err gf_odf_write_lang(GF_BitStream *bs, GF_Language *ld)
1524
1.18k
{
1525
1.18k
  GF_Err e;
1526
1.18k
  u32 size;
1527
1.18k
  if (!ld) return GF_BAD_PARAM;
1528
1529
1.18k
  e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
1530
1.18k
  if (e) return e;
1531
1.18k
  e = gf_odf_write_base_descriptor(bs, ld->tag, size);
1532
1.18k
  if (e) return e;
1533
1.18k
  gf_bs_write_int(bs, ld->langCode, 24);
1534
1.18k
  return GF_OK;
1535
1.18k
}
1536
1537
1538
1539
GF_Descriptor *gf_odf_new_auxvid()
1540
2.14k
{
1541
2.14k
  GF_AuxVideoDescriptor *newDesc;
1542
2.14k
  GF_SAFEALLOC(newDesc, GF_AuxVideoDescriptor);
1543
2.14k
  if (!newDesc) return NULL;
1544
2.14k
  newDesc->tag = GF_ODF_AUX_VIDEO_DATA;
1545
2.14k
  return (GF_Descriptor *) newDesc;
1546
2.14k
}
1547
1548
GF_Err gf_odf_del_auxvid(GF_AuxVideoDescriptor *ld)
1549
2.14k
{
1550
2.14k
  if (!ld) return GF_BAD_PARAM;
1551
2.14k
  gf_free(ld);
1552
2.14k
  return GF_OK;
1553
2.14k
}
1554
1555
GF_Err gf_odf_read_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld, u32 DescSize)
1556
2.14k
{
1557
2.14k
  u32 nbBytes = 0;
1558
2.14k
  if (!ld) return GF_BAD_PARAM;
1559
1560
2.14k
  ld->aux_video_type = gf_bs_read_int(bs, 8);
1561
2.14k
  ld->position_offset_h = gf_bs_read_int(bs, 8);
1562
2.14k
  ld->position_offset_v = gf_bs_read_int(bs, 8);
1563
2.14k
  nbBytes += 3;
1564
2.14k
  switch (ld->aux_video_type) {
1565
699
  case 0x10:
1566
699
    ld->kfar = gf_bs_read_int(bs, 8);
1567
699
    ld->knear = gf_bs_read_int(bs, 8);
1568
699
    nbBytes += 2;
1569
699
    break;
1570
888
  case 0x11:
1571
888
    ld->parallax_zero = gf_bs_read_int(bs, 16);
1572
888
    ld->parallax_scale = gf_bs_read_int(bs, 16);
1573
888
    ld->dref = gf_bs_read_int(bs, 16);
1574
888
    ld->wref = gf_bs_read_int(bs, 16);
1575
888
    nbBytes += 8;
1576
888
    break;
1577
2.14k
  }
1578
87.0k
  while (nbBytes < DescSize) {
1579
84.9k
    gf_bs_read_int(bs, 8);
1580
84.9k
    nbBytes ++;
1581
84.9k
  }
1582
2.14k
  return GF_OK;
1583
2.14k
}
1584
1585
GF_Err gf_odf_size_auxvid(GF_AuxVideoDescriptor *ld, u32 *outSize)
1586
1.92k
{
1587
1.92k
  if (!ld) return GF_BAD_PARAM;
1588
1.92k
  switch (ld->aux_video_type) {
1589
469
  case 0x10:
1590
469
    *outSize = 5;
1591
469
    break;
1592
1.08k
  case 0x11:
1593
1.08k
    *outSize = 11;
1594
1.08k
    break;
1595
372
  default:
1596
372
    *outSize = 3;
1597
372
    break;
1598
1.92k
  }
1599
1.92k
  return GF_OK;
1600
1.92k
}
1601
1602
GF_Err gf_odf_write_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld)
1603
924
{
1604
924
  GF_Err e;
1605
924
  u32 size;
1606
924
  if (!ld) return GF_BAD_PARAM;
1607
924
  e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
1608
924
  if (e) return e;
1609
924
  e = gf_odf_write_base_descriptor(bs, ld->tag, size);
1610
924
  if (e) return e;
1611
1612
924
  gf_bs_write_int(bs, ld->aux_video_type, 8);
1613
924
  gf_bs_write_int(bs, ld->position_offset_h, 8);
1614
924
  gf_bs_write_int(bs, ld->position_offset_v, 8);
1615
924
  switch (ld->aux_video_type) {
1616
323
  case 0x10:
1617
323
    gf_bs_write_int(bs, ld->kfar, 8);
1618
323
    gf_bs_write_int(bs, ld->knear, 8);
1619
323
    break;
1620
409
  case 0x11:
1621
409
    gf_bs_write_int(bs, ld->parallax_zero, 16);
1622
409
    gf_bs_write_int(bs, ld->parallax_scale, 16);
1623
409
    gf_bs_write_int(bs, ld->dref, 16);
1624
409
    gf_bs_write_int(bs, ld->wref, 16);
1625
409
    break;
1626
924
  }
1627
924
  return GF_OK;
1628
924
}
1629
1630
1631
1632
GF_Descriptor *gf_odf_new_muxinfo()
1633
210
{
1634
210
  GF_MuxInfo *newDesc = (GF_MuxInfo *) gf_malloc(sizeof(GF_MuxInfo));
1635
210
  if (!newDesc) return NULL;
1636
210
  memset(newDesc, 0, sizeof(GF_MuxInfo));
1637
210
  newDesc->tag = GF_ODF_MUXINFO_TAG;
1638
210
  return (GF_Descriptor *) newDesc;
1639
210
}
1640
1641
GF_Err gf_odf_del_muxinfo(GF_MuxInfo *mi)
1642
210
{
1643
210
  if (!mi) return GF_BAD_PARAM;
1644
210
  if (mi->file_name) gf_free(mi->file_name);
1645
210
  if (mi->src_url) gf_free(mi->src_url);
1646
210
  if (mi->streamFormat) gf_free(mi->streamFormat);
1647
210
  if (mi->textNode) gf_free(mi->textNode);
1648
210
  if (mi->fontNode) gf_free(mi->fontNode);
1649
210
  gf_free(mi);
1650
210
  return GF_OK;
1651
210
}
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
205
{
1665
205
  GF_ElementaryMask *newDesc = (GF_ElementaryMask*) gf_malloc (sizeof(GF_ElementaryMask));
1666
205
  if (!newDesc) return NULL;
1667
205
  memset(newDesc, 0, sizeof(GF_ElementaryMask));
1668
205
  newDesc->tag = GF_ODF_ELEM_MASK_TAG;
1669
205
  return (GF_Descriptor *) newDesc;
1670
205
}
1671
1672
GF_Err gf_odf_del_ElemMask(GF_ElementaryMask *desc)
1673
205
{
1674
205
  if (desc->node_name) gf_free(desc->node_name);
1675
205
  gf_free(desc);
1676
205
  return GF_OK;
1677
205
}
1678
1679
GF_Descriptor *gf_odf_new_bifs_cfg()
1680
1.90k
{
1681
1.90k
  GF_BIFSConfig *newDesc = (GF_BIFSConfig *) gf_malloc(sizeof(GF_BIFSConfig));
1682
1.90k
  if (!newDesc) return NULL;
1683
1.90k
  memset(newDesc, 0, sizeof(GF_BIFSConfig));
1684
1.90k
  newDesc->tag = GF_ODF_BIFS_CFG_TAG;
1685
1.90k
  return (GF_Descriptor *) newDesc;
1686
1.90k
}
1687
1688
GF_Err gf_odf_del_bifs_cfg(GF_BIFSConfig *desc)
1689
1.90k
{
1690
1.90k
  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
1.90k
  gf_free(desc);
1700
1.90k
  return GF_OK;
1701
1.90k
}
1702
1703
GF_Descriptor *gf_odf_new_laser_cfg()
1704
3.81k
{
1705
3.81k
  GF_LASERConfig *newDesc = (GF_LASERConfig *) gf_malloc(sizeof(GF_LASERConfig));
1706
3.81k
  if (!newDesc) return NULL;
1707
3.81k
  memset(newDesc, 0, sizeof(GF_LASERConfig));
1708
3.81k
  newDesc->tag = GF_ODF_LASER_CFG_TAG;
1709
3.81k
  return (GF_Descriptor *) newDesc;
1710
3.81k
}
1711
1712
GF_Err gf_odf_del_laser_cfg(GF_LASERConfig *desc)
1713
3.81k
{
1714
3.81k
  gf_free(desc);
1715
3.81k
  return GF_OK;
1716
3.81k
}
1717
1718
GF_Descriptor *gf_odf_new_ui_cfg()
1719
870
{
1720
870
  GF_UIConfig *newDesc = (GF_UIConfig *) gf_malloc(sizeof(GF_UIConfig));
1721
870
  if (!newDesc) return NULL;
1722
870
  memset(newDesc, 0, sizeof(GF_UIConfig));
1723
870
  newDesc->tag = GF_ODF_UI_CFG_TAG;
1724
870
  return (GF_Descriptor *) newDesc;
1725
870
}
1726
1727
GF_Err gf_odf_del_ui_cfg(GF_UIConfig *desc)
1728
870
{
1729
870
  if (desc->deviceName) gf_free(desc->deviceName);
1730
870
  if (desc->ui_data) gf_free(desc->ui_data);
1731
870
  gf_free(desc);
1732
870
  return GF_OK;
1733
870
}
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*/