Coverage Report

Created: 2026-01-25 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpac/src/odf/descriptors.c
Line
Count
Source
1
/*
2
 *      GPAC - Multimedia Framework C SDK
3
 *
4
 *      Authors: Jean Le Feuvre
5
 *      Copyright (c) Telecom ParisTech 2000-2025
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/constants.h>
28
29
#include <gpac/avparse.h>
30
#include <gpac/internal/media_dev.h>
31
32
s32 gf_odf_size_field_size(u32 size_desc)
33
812k
{
34
812k
  if (size_desc < 0x00000080) {
35
810k
    return 1 + 1;
36
810k
  } else if (size_desc < 0x00004000) {
37
807
    return 2 + 1;
38
807
  } else if (size_desc < 0x00200000) {
39
303
    return 3 + 1;
40
303
  } else if (size_desc < 0x10000000) {
41
290
    return 4 + 1;
42
290
  } else {
43
0
    return -1;
44
0
  }
45
46
812k
}
47
48
49
GF_EXPORT
50
GF_Err gf_odf_parse_descriptor(GF_BitStream *bs, GF_Descriptor **desc, u32 *desc_size)
51
421k
{
52
421k
  u32 val, size, sizeHeader;
53
421k
  u8 tag;
54
421k
  GF_Err err;
55
421k
  GF_Descriptor *newDesc;
56
421k
  if (!bs) return GF_BAD_PARAM;
57
58
421k
  *desc_size = 0;
59
60
  //tag
61
421k
  tag = (u8) gf_bs_read_int(bs, 8);
62
421k
  sizeHeader = 1;
63
64
  //size
65
421k
  size = 0;
66
436k
  do {
67
436k
    val = gf_bs_read_int(bs, 8);
68
436k
    sizeHeader++;
69
436k
    if (sizeHeader > 5) {
70
1.14k
      GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Descriptor size on more than 4 bytes\n"));
71
1.14k
      return GF_ODF_INVALID_DESCRIPTOR;
72
1.14k
    }
73
435k
    size <<= 7;
74
435k
    size |= val & 0x7F;
75
435k
  } while ( val & 0x80);
76
420k
  *desc_size = size;
77
78
420k
  if (gf_bs_available(bs) < size) {
79
3.65k
    GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Not enough bytes (%d) to read descriptor (size=%d)\n", gf_bs_available(bs), size));
80
3.65k
    return GF_ODF_INVALID_DESCRIPTOR;
81
3.65k
  }
82
83
416k
  GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[ODF] Reading descriptor (tag %d size %d)\n", tag, size ));
84
85
416k
  newDesc = gf_odf_create_descriptor(tag);
86
416k
  if (! newDesc) {
87
645
    *desc = NULL;
88
645
    *desc_size = sizeHeader;
89
645
    if ( (tag >= GF_ODF_ISO_RES_BEGIN_TAG) &&
90
645
            (tag <= GF_ODF_ISO_RES_END_TAG) ) {
91
645
      return GF_ODF_FORBIDDEN_DESCRIPTOR;
92
645
    }
93
0
    else if (!tag || (tag == 0xFF)) {
94
0
      return GF_ODF_INVALID_DESCRIPTOR;
95
0
    }
96
#ifndef GPAC_MINIMAL_ODF
97
    return GF_OUT_OF_MEM;
98
#else
99
0
    gf_bs_skip_bytes(bs, size);
100
0
    *desc_size = size + sizeHeader - gf_odf_size_field_size(*desc_size);
101
0
    return GF_OK;
102
645
#endif
103
645
  }
104
105
415k
  newDesc->tag = tag;
106
415k
  err = gf_odf_read_descriptor(bs, newDesc, *desc_size);
107
108
  /*FFmpeg fix*/
109
415k
  if ((tag==GF_ODF_SLC_TAG) && (((GF_SLConfig*)newDesc)->predefined==2)) {
110
3.48k
    if (*desc_size==3) {
111
538
      *desc_size = 1;
112
538
      err = GF_OK;
113
538
    }
114
3.48k
  }
115
116
  //little trick to handle lazy bitstreams that encode
117
  //SizeOfInstance on a fix number of bytes
118
  //This nb of bytes is added in Read methods
119
415k
  *desc_size += sizeHeader - gf_odf_size_field_size(*desc_size);
120
415k
  *desc = newDesc;
121
415k
  if (err) {
122
31.4k
    GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Error reading descriptor (tag %d size %d): %s\n", tag, size, gf_error_to_string(err) ));
123
31.4k
    gf_odf_delete_descriptor(newDesc);
124
31.4k
    *desc = NULL;
125
31.4k
  }
126
415k
  return err;
127
416k
}
128
129
130
131
GF_Err gf_odf_delete_descriptor_list(GF_List *descList)
132
238k
{
133
238k
  GF_Err e;
134
238k
  GF_Descriptor*tmp;
135
238k
  u32 i;
136
  //no error if NULL chain...
137
238k
  if (! descList) return GF_OK;
138
238k
  i=0;
139
277k
  while ((tmp = (GF_Descriptor*)gf_list_enum(descList, &i))) {
140
39.2k
    e = gf_odf_delete_descriptor(tmp);
141
39.2k
    if (e) return e;
142
39.2k
  }
143
238k
  gf_list_del(descList);
144
238k
  return GF_OK;
145
238k
}
146
147
GF_Err gf_odf_write_base_descriptor(GF_BitStream *bs, u8 tag, u32 size)
148
64.9k
{
149
64.9k
  u32 length;
150
64.9k
  unsigned char vals[4];
151
152
64.9k
  if (!tag ) return GF_BAD_PARAM;
153
154
38.1k
  length = size;
155
38.1k
  vals[3] = (unsigned char) (length & 0x7f);
156
38.1k
  length >>= 7;
157
38.1k
  vals[2] = (unsigned char) ((length & 0x7f) | 0x80);
158
38.1k
  length >>= 7;
159
38.1k
  vals[1] = (unsigned char) ((length & 0x7f) | 0x80);
160
38.1k
  length >>= 7;
161
38.1k
  vals[0] = (unsigned char) ((length & 0x7f) | 0x80);
162
163
38.1k
  gf_bs_write_int(bs, tag, 8);
164
38.1k
  if (size < 0x00000080) {
165
38.1k
    gf_bs_write_int(bs, vals[3], 8);
166
38.1k
  } else if (size < 0x00004000) {
167
21
    gf_bs_write_int(bs, vals[2], 8);
168
21
    gf_bs_write_int(bs, vals[3], 8);
169
21
  } else if (size < 0x00200000) {
170
0
    gf_bs_write_int(bs, vals[1], 8);
171
0
    gf_bs_write_int(bs, vals[2], 8);
172
0
    gf_bs_write_int(bs, vals[3], 8);
173
0
  } else if (size < 0x10000000) {
174
0
    gf_bs_write_int(bs, vals[0], 8);
175
0
    gf_bs_write_int(bs, vals[1], 8);
176
0
    gf_bs_write_int(bs, vals[2], 8);
177
0
    gf_bs_write_int(bs, vals[3], 8);
178
0
  } else {
179
0
    return GF_ODF_INVALID_DESCRIPTOR;
180
0
  }
181
38.1k
  return GF_OK;
182
38.1k
}
183
184
185
GF_Err gf_odf_size_descriptor_list(GF_List *descList, u32 *outSize)
186
29.2k
{
187
29.2k
  GF_Err e;
188
29.2k
  u32 tmpSize, count, i;
189
29.2k
  if (! descList) return GF_OK;
190
191
29.2k
  count = gf_list_count(descList);
192
39.0k
  for ( i = 0; i < count; i++ ) {
193
9.76k
    GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(descList, i);
194
9.76k
    if (tmp) {
195
9.76k
      e = gf_odf_size_descriptor(tmp, &tmpSize);
196
9.76k
      if (e) return e;
197
9.76k
      if (tmpSize) *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
198
9.76k
    }
199
9.76k
  }
200
29.2k
  return GF_OK;
201
29.2k
}
202
203
GF_Err gf_odf_write_descriptor_list(GF_BitStream *bs, GF_List *descList)
204
25.5k
{
205
25.5k
  GF_Err e;
206
25.5k
  u32 count, i;
207
208
25.5k
  if (! descList) return GF_OK;
209
25.5k
  count = gf_list_count(descList);
210
32.1k
  for ( i = 0; i < count; i++ ) {
211
6.68k
    GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(descList, i);
212
6.68k
    if (tmp) {
213
6.68k
      e = gf_odf_write_descriptor(bs, tmp);
214
6.68k
      if (e) return e;
215
6.68k
    }
216
6.68k
  }
217
25.5k
  return GF_OK;
218
25.5k
}
219
220
GF_Err gf_odf_write_descriptor_list_filter(GF_BitStream *bs, GF_List *descList, u8 only_tag)
221
5.70k
{
222
5.70k
  GF_Err e;
223
5.70k
  u32 count, i;
224
225
5.70k
  if (! descList) return GF_OK;
226
5.70k
  count = gf_list_count(descList);
227
11.4k
  for ( i = 0; i < count; i++ ) {
228
5.79k
    GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(descList, i);
229
5.79k
    if (tmp && (tmp->tag==only_tag) ) {
230
2.89k
      e = gf_odf_write_descriptor(bs, tmp);
231
2.89k
      if (e) return e;
232
2.89k
    }
233
5.79k
  }
234
5.70k
  return GF_OK;
235
5.70k
}
236
237
#ifndef GPAC_MINIMAL_ODF
238
239
u32 gf_ipmpx_array_size(GF_BitStream *bs, u32 *array_size)
240
{
241
  u32 val, size, io_size;
242
243
  io_size = size = 0;
244
  do {
245
    val = gf_bs_read_int(bs, 8);
246
    io_size ++;
247
    size <<= 7;
248
    size |= val & 0x7F;
249
  } while ( val & 0x80 );
250
  *array_size = size;
251
  return io_size;
252
}
253
254
void gf_ipmpx_write_array(GF_BitStream *bs, u8 *data, u32 data_len)
255
{
256
  u32 length;
257
  unsigned char vals[4];
258
259
  if (!data || !data_len) return;
260
261
  length = data_len;
262
  vals[3] = (unsigned char) (length & 0x7f);
263
  length >>= 7;
264
  vals[2] = (unsigned char) ((length & 0x7f) | 0x80);
265
  length >>= 7;
266
  vals[1] = (unsigned char) ((length & 0x7f) | 0x80);
267
  length >>= 7;
268
  vals[0] = (unsigned char) ((length & 0x7f) | 0x80);
269
270
  if (data_len < 0x00000080) {
271
    gf_bs_write_int(bs, vals[3], 8);
272
  } else if (data_len < 0x00004000) {
273
    gf_bs_write_int(bs, vals[2], 8);
274
    gf_bs_write_int(bs, vals[3], 8);
275
  } else if (data_len < 0x00200000) {
276
    gf_bs_write_int(bs, vals[1], 8);
277
    gf_bs_write_int(bs, vals[2], 8);
278
    gf_bs_write_int(bs, vals[3], 8);
279
  } else if (data_len < 0x10000000) {
280
    gf_bs_write_int(bs, vals[0], 8);
281
    gf_bs_write_int(bs, vals[1], 8);
282
    gf_bs_write_int(bs, vals[2], 8);
283
    gf_bs_write_int(bs, vals[3], 8);
284
  } else {
285
    return;
286
  }
287
  gf_bs_write_data(bs, data, data_len);
288
}
289
290
291
#endif /*GPAC_MINIMAL_ODF*/
292
293
/*special authoring functions*/
294
GF_EXPORT
295
GF_BIFSConfig *gf_odf_get_bifs_config(GF_DefaultDescriptor *dsi, u32 oti)
296
0
{
297
0
  Bool hasSize, cmd_stream;
298
0
  GF_BitStream *bs;
299
0
  GF_BIFSConfig *cfg;
300
301
0
  if (oti>=GF_CODECID_BIFS_EXTENDED) return NULL;
302
303
0
  if (!dsi || !dsi->data || !dsi->dataLength ) {
304
    /* Hack for T-DMB non compliant streams (OnTimeTek ?) */
305
0
    cfg = (GF_BIFSConfig *) gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG);
306
0
    cfg->pixelMetrics = GF_TRUE;
307
0
    cfg->version = 1;
308
0
    return cfg;
309
0
  }
310
0
  bs = gf_bs_new(dsi->data, dsi->dataLength, GF_BITSTREAM_READ);
311
312
0
  cfg = (GF_BIFSConfig *) gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG);
313
0
  if (oti==2) {
314
    /*3D Mesh Coding*/
315
0
    gf_bs_read_int(bs, 1);
316
    /*PMF*/
317
0
    gf_bs_read_int(bs, 1);
318
0
  }
319
0
  cfg->nodeIDbits = gf_bs_read_int(bs, 5);
320
0
  cfg->routeIDbits = gf_bs_read_int(bs, 5);
321
0
  if (oti==2) cfg->protoIDbits = gf_bs_read_int(bs, 5);
322
323
0
  cmd_stream = (Bool)gf_bs_read_int(bs, 1);
324
0
  if (!cmd_stream) {
325
0
    cfg->elementaryMasks = gf_list_new();
326
0
    while (1) {
327
0
      GF_ElementaryMask* em = (GF_ElementaryMask* ) gf_odf_New_ElemMask();
328
0
      em->node_id = gf_bs_read_int(bs, cfg->nodeIDbits);
329
0
      gf_list_add(cfg->elementaryMasks, em);
330
      /*this assumes only FDP, BDP and IFS2D (no elem mask)*/
331
0
      if (gf_bs_read_int(bs, 1) == 0) break;
332
0
    }
333
0
    gf_bs_align(bs);
334
0
    if (gf_bs_get_size(bs) != gf_bs_get_position(bs)) {
335
0
      GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[ODF] Reading bifs config: shift in sizes (not supported)\n"));
336
0
    }
337
0
  } else {
338
0
    cfg->pixelMetrics = (Bool)gf_bs_read_int(bs, 1);
339
0
    hasSize = (Bool)gf_bs_read_int(bs, 1);
340
0
    if (hasSize) {
341
0
      cfg->pixelWidth = gf_bs_read_int(bs, 16);
342
0
      cfg->pixelHeight = gf_bs_read_int(bs, 16);
343
0
    }
344
0
    gf_bs_align(bs);
345
0
    if (gf_bs_get_size(bs) != gf_bs_get_position(bs))
346
0
      GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[ODF] Reading bifs config: shift in sizes (invalid descriptor)\n"));
347
0
  }
348
0
  gf_bs_del(bs);
349
0
  return cfg;
350
0
}
351
352
/*special function for authoring - convert DSI to LASERConfig*/
353
GF_EXPORT
354
GF_Err gf_odf_get_laser_config(GF_DefaultDescriptor *dsi, GF_LASERConfig *cfg)
355
0
{
356
0
  u32 to_skip;
357
0
  GF_BitStream *bs;
358
359
0
  if (!cfg) return GF_BAD_PARAM;
360
0
  memset(cfg, 0, sizeof(GF_LASERConfig));
361
362
0
  if (!dsi || !dsi->data || !dsi->dataLength) return GF_BAD_PARAM;
363
0
  bs = gf_bs_new(dsi->data, dsi->dataLength, GF_BITSTREAM_READ);
364
0
  memset(cfg, 0, sizeof(GF_LASERConfig));
365
0
  cfg->tag = GF_ODF_LASER_CFG_TAG;
366
0
  cfg->profile = gf_bs_read_int(bs, 8);
367
0
  cfg->level = gf_bs_read_int(bs, 8);
368
0
  /*cfg->reserved = */gf_bs_read_int(bs, 3);
369
0
  cfg->pointsCodec = gf_bs_read_int(bs, 2);
370
0
  cfg->pathComponents = gf_bs_read_int(bs, 4);
371
0
  cfg->fullRequestHost = gf_bs_read_int(bs, 1);
372
0
  if (gf_bs_read_int(bs, 1)) cfg->time_resolution = gf_bs_read_int(bs, 16);
373
0
  else cfg->time_resolution = 1000;
374
0
  cfg->colorComponentBits = 1 + gf_bs_read_int(bs, 4);
375
0
  cfg->resolution = gf_bs_read_int(bs, 4);
376
0
  if (cfg->resolution>7) cfg->resolution -= 16;
377
0
  cfg->coord_bits = gf_bs_read_int(bs, 5);
378
0
  cfg->scale_bits_minus_coord_bits = gf_bs_read_int(bs, 4);
379
0
  cfg->newSceneIndicator = gf_bs_read_int(bs, 1);
380
0
  /*reserved2*/ gf_bs_read_int(bs, 3);
381
0
  cfg->extensionIDBits = gf_bs_read_int(bs, 4);
382
  /*hasExtConfig - we just ignore it*/
383
0
  if (gf_bs_read_int(bs, 1)) {
384
0
    to_skip = gf_bs_read_vluimsbf5(bs);
385
0
    while (to_skip) {
386
0
      gf_bs_read_int(bs, 8);
387
0
      to_skip--;
388
0
    }
389
0
  }
390
  /*hasExtension - we just ignore it*/
391
0
  if (gf_bs_read_int(bs, 1)) {
392
0
    to_skip = gf_bs_read_vluimsbf5(bs);
393
0
    while (to_skip) {
394
0
      gf_bs_read_int(bs, 8);
395
0
      to_skip--;
396
0
    }
397
0
  }
398
0
  gf_bs_del(bs);
399
0
  return GF_OK;
400
0
}
401
//unused
402
#if 0
403
GF_Err gf_odf_get_ui_config(GF_DefaultDescriptor *dsi, GF_UIConfig *cfg)
404
{
405
  u32 len, i;
406
  GF_BitStream *bs;
407
  if (!dsi || !dsi->data || !dsi->dataLength || !cfg) return GF_BAD_PARAM;
408
  memset(cfg, 0, sizeof(GF_UIConfig));
409
  cfg->tag = GF_ODF_UI_CFG_TAG;
410
  bs = gf_bs_new(dsi->data, dsi->dataLength, GF_BITSTREAM_READ);
411
  len = gf_bs_read_int(bs, 8);
412
  cfg->deviceName = (char*)gf_malloc(sizeof(char) * (len+1));
413
  for (i=0; i<len; i++) cfg->deviceName[i] = gf_bs_read_int(bs, 8);
414
  cfg->deviceName[i] = 0;
415
416
  if (!stricmp(cfg->deviceName, "StringSensor") && gf_bs_available(bs)) {
417
    cfg->termChar = gf_bs_read_int(bs, 8);
418
    cfg->delChar = gf_bs_read_int(bs, 8);
419
  }
420
  gf_bs_del(bs);
421
  return GF_OK;
422
}
423
#endif
424
425
GF_EXPORT
426
GF_Err gf_odf_encode_ui_config(GF_UIConfig *cfg, GF_DefaultDescriptor **out_dsi)
427
0
{
428
0
  u32 i, len;
429
0
  GF_BitStream *bs;
430
0
  GF_DefaultDescriptor *dsi;
431
0
  if (!out_dsi || (cfg->tag != GF_ODF_UI_CFG_TAG)) return GF_BAD_PARAM;
432
433
0
  *out_dsi = NULL;
434
0
  if (!cfg->deviceName) return GF_OK;
435
436
0
  bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
437
0
  len = (u32) strlen(cfg->deviceName);
438
0
  gf_bs_write_int(bs, len, 8);
439
0
  for (i=0; i<len; i++) gf_bs_write_int(bs, cfg->deviceName[i], 8);
440
0
  if (!stricmp(cfg->deviceName, "StringSensor")) {
441
    /*fixme - this should be UTF-8 chars*/
442
0
    if (cfg->delChar || cfg->termChar) {
443
0
      gf_bs_write_int(bs, cfg->termChar, 8);
444
0
      gf_bs_write_int(bs, cfg->delChar, 8);
445
0
    }
446
0
  }
447
0
  if (cfg->ui_data) gf_bs_write_data(bs, cfg->ui_data, cfg->ui_data_length);
448
449
0
  dsi = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG);
450
0
  gf_bs_get_content(bs, &dsi->data, &dsi->dataLength);
451
0
  gf_bs_del(bs);
452
0
  *out_dsi = dsi;
453
0
  return GF_OK;
454
0
}
455
456
457
GF_EXPORT
458
GF_AVCConfig *gf_odf_avc_cfg_new()
459
80.5k
{
460
80.5k
  GF_AVCConfig *cfg;
461
80.5k
  GF_SAFEALLOC(cfg, GF_AVCConfig);
462
80.5k
  if (!cfg) return NULL;
463
80.5k
  cfg->sequenceParameterSets = gf_list_new();
464
80.5k
  cfg->pictureParameterSets = gf_list_new();
465
80.5k
  cfg->AVCLevelIndication = 1;
466
80.5k
  cfg->chroma_format = 1;
467
80.5k
  cfg->chroma_bit_depth = 8;
468
80.5k
  cfg->luma_bit_depth = 8;
469
80.5k
  return cfg;
470
80.5k
}
471
472
GF_EXPORT
473
void gf_odf_avc_cfg_del(GF_AVCConfig *cfg)
474
80.5k
{
475
80.5k
  if (!cfg) return;
476
109k
  while (gf_list_count(cfg->sequenceParameterSets)) {
477
28.4k
    GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->sequenceParameterSets, 0);
478
28.4k
    gf_list_rem(cfg->sequenceParameterSets, 0);
479
28.4k
    if (sl->data) gf_free(sl->data);
480
28.4k
    gf_free(sl);
481
28.4k
  }
482
80.5k
  gf_list_del(cfg->sequenceParameterSets);
483
80.5k
  cfg->sequenceParameterSets = NULL;
484
485
85.4k
  while (gf_list_count(cfg->pictureParameterSets)) {
486
4.88k
    GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->pictureParameterSets, 0);
487
4.88k
    gf_list_rem(cfg->pictureParameterSets, 0);
488
4.88k
    if (sl->data) gf_free(sl->data);
489
4.88k
    gf_free(sl);
490
4.88k
  }
491
80.5k
  gf_list_del(cfg->pictureParameterSets);
492
80.5k
  cfg->pictureParameterSets = NULL;
493
494
80.5k
  if (cfg->sequenceParameterSetExtensions) {
495
11.8k
    while (gf_list_count(cfg->sequenceParameterSetExtensions)) {
496
6.41k
      GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->sequenceParameterSetExtensions, 0);
497
6.41k
      gf_list_rem(cfg->sequenceParameterSetExtensions, 0);
498
6.41k
      if (sl->data) gf_free(sl->data);
499
6.41k
      gf_free(sl);
500
6.41k
    }
501
5.39k
    gf_list_del(cfg->sequenceParameterSetExtensions);
502
5.39k
    cfg->sequenceParameterSetExtensions = NULL;
503
5.39k
  }
504
80.5k
  gf_free(cfg);
505
80.5k
}
506
507
GF_EXPORT
508
GF_Err gf_odf_avc_cfg_write_bs(GF_AVCConfig *cfg, GF_BitStream *bs)
509
21.1k
{
510
21.1k
  u32 i, count;
511
512
21.1k
  if (!cfg) return GF_BAD_PARAM;
513
514
21.1k
  count = gf_list_count(cfg->sequenceParameterSets);
515
516
21.1k
  if (!cfg->write_annex_b) {
517
21.1k
    gf_bs_write_int(bs, cfg->configurationVersion, 8);
518
21.1k
    gf_bs_write_int(bs, cfg->AVCProfileIndication , 8);
519
21.1k
    gf_bs_write_int(bs, cfg->profile_compatibility, 8);
520
21.1k
    gf_bs_write_int(bs, cfg->AVCLevelIndication, 8);
521
21.1k
    gf_bs_write_int(bs, 0x3F, 6);
522
21.1k
    gf_bs_write_int(bs, cfg->nal_unit_size - 1, 2);
523
21.1k
    gf_bs_write_int(bs, 0x7, 3);
524
21.1k
    gf_bs_write_int(bs, count, 5);
525
21.1k
  }
526
21.9k
  for (i=0; i<count; i++) {
527
842
    GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->sequenceParameterSets, i);
528
842
    if (!cfg->write_annex_b) {
529
842
      gf_bs_write_u16(bs, sl->size);
530
842
    } else {
531
0
      gf_bs_write_u32(bs, 1);
532
0
    }
533
842
    gf_bs_write_data(bs, sl->data, sl->size);
534
842
  }
535
21.1k
  count = gf_list_count(cfg->pictureParameterSets);
536
21.1k
  if (!cfg->write_annex_b) {
537
21.1k
    gf_bs_write_int(bs, count, 8);
538
21.1k
  }
539
22.9k
  for (i=0; i<count; i++) {
540
1.82k
    GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->pictureParameterSets, i);
541
1.82k
    if (!cfg->write_annex_b) {
542
1.82k
      gf_bs_write_u16(bs, sl->size);
543
1.82k
    } else {
544
0
      gf_bs_write_u32(bs, 1);
545
0
    }
546
1.82k
    gf_bs_write_data(bs, sl->data, sl->size);
547
1.82k
  }
548
21.1k
  if (gf_avcc_use_extensions(cfg->AVCProfileIndication)) {
549
16.7k
    if (!cfg->write_annex_b) {
550
16.7k
      gf_bs_write_int(bs, 0xFF, 6);
551
16.7k
      gf_bs_write_int(bs, cfg->chroma_format, 2);
552
16.7k
      gf_bs_write_int(bs, 0xFF, 5);
553
16.7k
      gf_bs_write_int(bs, cfg->luma_bit_depth - 8, 3);
554
16.7k
      gf_bs_write_int(bs, 0xFF, 5);
555
16.7k
      gf_bs_write_int(bs, cfg->chroma_bit_depth - 8, 3);
556
16.7k
    }
557
16.7k
    count = cfg->sequenceParameterSetExtensions ? gf_list_count(cfg->sequenceParameterSetExtensions) : 0;
558
16.7k
    if (!cfg->write_annex_b) {
559
16.7k
      gf_bs_write_u8(bs, count);
560
16.7k
    }
561
17.1k
    for (i=0; i<count; i++) {
562
397
      GF_NALUFFParam *sl = (GF_NALUFFParam *) gf_list_get(cfg->sequenceParameterSetExtensions, i);
563
397
      if (!cfg->write_annex_b) {
564
397
        gf_bs_write_u16(bs, sl->size);
565
397
      } else {
566
0
        gf_bs_write_u32(bs, 1);
567
0
      }
568
397
      gf_bs_write_data(bs, sl->data, sl->size);
569
397
    }
570
16.7k
  }
571
21.1k
  return GF_OK;
572
21.1k
}
573
574
GF_EXPORT
575
GF_Err gf_odf_avc_cfg_write(GF_AVCConfig *cfg, u8 **outData, u32 *outSize)
576
21.1k
{
577
21.1k
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
578
21.1k
  gf_odf_avc_cfg_write_bs(cfg, bs);
579
21.1k
  *outSize = 0;
580
21.1k
  *outData = NULL;
581
21.1k
  gf_bs_get_content(bs, outData, outSize);
582
21.1k
  gf_bs_del(bs);
583
21.1k
  return GF_OK;
584
21.1k
}
585
586
GF_EXPORT
587
GF_AVCConfig *gf_odf_avc_cfg_read(u8 *dsi, u32 dsi_size)
588
6.23k
{
589
6.23k
  u32 i, count;
590
6.23k
  GF_AVCConfig *avcc = gf_odf_avc_cfg_new();
591
6.23k
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
592
6.23k
  avcc->configurationVersion = gf_bs_read_int(bs, 8);
593
6.23k
  avcc->AVCProfileIndication  = gf_bs_read_int(bs, 8);
594
6.23k
  avcc->profile_compatibility = gf_bs_read_int(bs, 8);
595
6.23k
  avcc->AVCLevelIndication  = gf_bs_read_int(bs, 8);
596
6.23k
  gf_bs_read_int(bs, 6);
597
6.23k
  avcc->nal_unit_size = 1 + gf_bs_read_int(bs, 2);
598
6.23k
  gf_bs_read_int(bs, 3);
599
6.23k
  count = gf_bs_read_int(bs, 5);
600
6.60k
  for (i=0; i<count; i++) {
601
422
    GF_NALUFFParam *sl;
602
422
    u32 size = gf_bs_read_int(bs, 16);
603
422
    if ((size>gf_bs_available(bs)) || (size<2)) {
604
52
      GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AVC] Wrong param set size %d\n", size));
605
52
      gf_bs_del(bs);
606
52
      gf_odf_avc_cfg_del(avcc);
607
52
      return NULL;
608
52
    }
609
370
    GF_SAFEALLOC(sl, GF_NALUFFParam );
610
370
    if (!sl) {
611
0
      gf_bs_del(bs);
612
0
      gf_odf_avc_cfg_del(avcc);
613
0
      return NULL;
614
0
    }
615
370
    sl->size = size;
616
370
    sl->data = (char*)gf_malloc(sizeof(char)*sl->size);
617
370
    if (!sl->data) {
618
0
      gf_bs_del(bs);
619
0
      gf_odf_avc_cfg_del(avcc);
620
0
      return NULL;
621
0
    }
622
370
    gf_bs_read_data(bs, sl->data, sl->size);
623
370
    gf_list_add(avcc->sequenceParameterSets, sl);
624
370
  }
625
6.18k
  count = gf_bs_read_int(bs, 8);
626
6.54k
  for (i=0; i<count; i++) {
627
3.95k
    GF_NALUFFParam *sl;
628
3.95k
    u32 size = gf_bs_read_int(bs, 16);
629
3.95k
    if ((size>gf_bs_available(bs)) || (size<2)) {
630
3.59k
      GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AVC] Wrong param set size %d\n", size));
631
3.59k
      gf_bs_del(bs);
632
3.59k
      gf_odf_avc_cfg_del(avcc);
633
3.59k
      return NULL;
634
3.59k
    }
635
366
    GF_SAFEALLOC(sl, GF_NALUFFParam );
636
366
    if (!sl) {
637
0
      gf_bs_del(bs);
638
0
      gf_odf_avc_cfg_del(avcc);
639
0
      return NULL;
640
0
    }
641
366
    sl->size = size;
642
366
    sl->data = (char*)gf_malloc(sizeof(char)*sl->size);
643
366
    if (!sl->data) {
644
0
      gf_bs_del(bs);
645
0
      gf_odf_avc_cfg_del(avcc);
646
0
      return NULL;
647
0
    }
648
366
    gf_bs_read_data(bs, sl->data, sl->size);
649
366
    gf_list_add(avcc->pictureParameterSets, sl);
650
366
  }
651
2.59k
  if (gf_avcc_use_extensions(avcc->AVCProfileIndication)) {
652
1.77k
    gf_bs_read_int(bs, 6);
653
1.77k
    avcc->chroma_format = gf_bs_read_int(bs, 2);
654
1.77k
    gf_bs_read_int(bs, 5);
655
1.77k
    avcc->luma_bit_depth = 8 + gf_bs_read_int(bs, 3);
656
1.77k
    gf_bs_read_int(bs, 5);
657
1.77k
    avcc->chroma_bit_depth = 8 + gf_bs_read_int(bs, 3);
658
659
1.77k
    count = gf_bs_read_int(bs, 8);
660
1.77k
    if (count) {
661
114
      avcc->sequenceParameterSetExtensions = gf_list_new();
662
114
      for (i=0; i<count; i++) {
663
114
        GF_NALUFFParam *sl;
664
114
        u32 size = gf_bs_read_int(bs, 16);
665
114
        if ((size>gf_bs_available(bs)) || (size<2)) {
666
114
          GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AVC] Wrong param set size %d\n", size));
667
114
          gf_bs_del(bs);
668
114
          gf_odf_avc_cfg_del(avcc);
669
114
          return NULL;
670
114
        }
671
0
        GF_SAFEALLOC(sl, GF_NALUFFParam );
672
0
        if (!sl) {
673
0
          gf_bs_del(bs);
674
0
          gf_odf_avc_cfg_del(avcc);
675
0
          return NULL;
676
0
        }
677
0
        sl->size = size;
678
0
        sl->data = (char*)gf_malloc(sizeof(char)*sl->size);
679
0
        if (!sl->data) {
680
0
          gf_bs_del(bs);
681
0
          gf_odf_avc_cfg_del(avcc);
682
0
          return NULL;
683
0
        }
684
0
        gf_bs_read_data(bs, sl->data, sl->size);
685
0
        gf_list_add(avcc->sequenceParameterSetExtensions, sl);
686
0
      }
687
114
    }
688
1.77k
  }
689
690
691
2.47k
  gf_bs_del(bs);
692
2.47k
  return avcc;
693
2.59k
}
694
695
696
GF_Descriptor *gf_odf_new_tx3g()
697
2.93k
{
698
2.93k
  GF_TextSampleDescriptor *newDesc = (GF_TextSampleDescriptor*) gf_malloc(sizeof(GF_TextSampleDescriptor));
699
2.93k
  if (!newDesc) return NULL;
700
2.93k
  memset(newDesc, 0, sizeof(GF_TextSampleDescriptor));
701
2.93k
  newDesc->tag = GF_ODF_TX3G_TAG;
702
2.93k
  return (GF_Descriptor *) newDesc;
703
2.93k
}
704
GF_Err gf_odf_del_tx3g(GF_TextSampleDescriptor *sd)
705
2.93k
{
706
2.93k
  u32 i;
707
3.09k
  for (i=0; i<sd->font_count; i++)
708
164
    if (sd->fonts[i].fontName) gf_free(sd->fonts[i].fontName);
709
2.93k
  gf_free(sd->fonts);
710
2.93k
  gf_free(sd);
711
2.93k
  return GF_OK;
712
2.93k
}
713
714
GF_EXPORT
715
GF_TextSampleDescriptor *gf_odf_tx3g_read(u8 *dsi, u32 dsi_size)
716
82
{
717
82
#ifndef GPAC_DISABLE_ISOM
718
82
  u32 i;
719
82
  u32 gpp_read_rgba(GF_BitStream *bs);
720
82
  void gpp_read_style(GF_BitStream *bs, GF_StyleRecord *rec);
721
82
  void gpp_read_box(GF_BitStream *bs, GF_BoxRecord *rec);
722
723
82
  GF_TextSampleDescriptor *txtc = (GF_TextSampleDescriptor *) gf_odf_new_tx3g();
724
82
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
725
726
82
  txtc->displayFlags = gf_bs_read_int(bs, 32);
727
82
  txtc->horiz_justif = gf_bs_read_int(bs, 8);
728
82
  txtc->vert_justif  = gf_bs_read_int(bs, 8);
729
82
  txtc->back_color = gpp_read_rgba(bs);
730
82
  gpp_read_box(bs, &txtc->default_pos);
731
82
  gpp_read_style(bs, &txtc->default_style);
732
82
  txtc->font_count = gf_bs_read_u16(bs);
733
82
  txtc->fonts = gf_malloc(sizeof(GF_FontRecord)*txtc->font_count);
734
164
  for (i=0; i<txtc->font_count; i++) {
735
82
    u8 len;
736
82
    txtc->fonts[i].fontID = gf_bs_read_u16(bs);
737
82
    len = gf_bs_read_u8(bs);
738
82
    txtc->fonts[i].fontName = gf_malloc(sizeof(char)*(len+1));
739
82
    gf_bs_read_data(bs, txtc->fonts[i].fontName, len);
740
82
    txtc->fonts[i].fontName[len] = 0;
741
82
  }
742
82
  gf_bs_del(bs);
743
82
  return txtc;
744
#else
745
  return NULL;
746
#endif
747
82
}
748
749
GF_Err gf_odf_tx3g_write(GF_TextSampleDescriptor *a, u8 **outData, u32 *outSize)
750
82
{
751
82
#ifndef GPAC_DISABLE_ISOM
752
82
  u32 j;
753
82
  void gpp_write_rgba(GF_BitStream *bs, u32 col);
754
82
  void gpp_write_box(GF_BitStream *bs, GF_BoxRecord *rec);
755
82
  void gpp_write_style(GF_BitStream *bs, GF_StyleRecord *rec);
756
82
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
757
758
82
  gf_bs_write_u32(bs, a->displayFlags);
759
82
  gf_bs_write_u8(bs, a->horiz_justif);
760
82
  gf_bs_write_u8(bs, a->vert_justif);
761
82
  gpp_write_rgba(bs, a->back_color);
762
82
  gpp_write_box(bs, &a->default_pos);
763
82
  gpp_write_style(bs, &a->default_style);
764
765
82
  gf_bs_write_u16(bs, a->font_count);
766
164
  for (j=0; j<a->font_count; j++) {
767
82
    gf_bs_write_u16(bs, a->fonts[j].fontID);
768
82
    if (a->fonts[j].fontName) {
769
82
      u32 len = (u32) strlen(a->fonts[j].fontName);
770
82
      gf_bs_write_u8(bs, len);
771
82
      gf_bs_write_data(bs, a->fonts[j].fontName, len);
772
82
    } else {
773
0
      gf_bs_write_u8(bs, 0);
774
0
    }
775
82
  }
776
82
  gf_bs_get_content(bs, outData, outSize);
777
82
  gf_bs_del(bs);
778
82
  return GF_OK;
779
#else
780
  return GF_NOT_SUPPORTED;
781
#endif
782
82
}
783
784
/*TextConfig*/
785
GF_Descriptor *gf_odf_new_text_cfg()
786
2.05k
{
787
2.05k
  GF_TextConfig *newDesc = (GF_TextConfig*) gf_malloc(sizeof(GF_TextConfig));
788
2.05k
  if (!newDesc) return NULL;
789
2.05k
  memset(newDesc, 0, sizeof(GF_TextConfig));
790
2.05k
  newDesc->tag = GF_ODF_TEXT_CFG_TAG;
791
2.05k
  newDesc->sample_descriptions = gf_list_new();
792
2.05k
  newDesc->Base3GPPFormat = 0x10;
793
2.05k
  newDesc->MPEGExtendedFormat = 0x10;
794
2.05k
  newDesc->profileLevel = 0x10;
795
2.05k
  newDesc->timescale = 1000;
796
2.05k
  return (GF_Descriptor *) newDesc;
797
2.05k
}
798
799
void ResetTextConfig(GF_TextConfig *desc)
800
2.05k
{
801
2.05k
  GF_List *bck;
802
2.05k
  while (gf_list_count(desc->sample_descriptions)) {
803
0
    GF_TextSampleDescriptor *sd = (GF_TextSampleDescriptor *)gf_list_get(desc->sample_descriptions, 0);
804
0
    gf_list_rem(desc->sample_descriptions, 0);
805
0
    gf_odf_del_tx3g(sd);
806
0
  }
807
2.05k
  bck = desc->sample_descriptions;
808
2.05k
  memset(desc, 0, sizeof(GF_TextConfig));
809
2.05k
  desc->tag = GF_ODF_TEXT_CFG_TAG;
810
2.05k
  desc->sample_descriptions = bck;
811
2.05k
}
812
813
GF_Err gf_odf_del_text_cfg(GF_TextConfig *desc)
814
2.05k
{
815
2.05k
  ResetTextConfig(desc);
816
2.05k
  gf_list_del(desc->sample_descriptions);
817
2.05k
  gf_free(desc);
818
2.05k
  return GF_OK;
819
2.05k
}
820
821
/*we need box parsing*/
822
#include <gpac/internal/isomedia_dev.h>
823
GF_EXPORT
824
GF_Err gf_odf_get_text_config(u8 *data, u32 data_len, u32 codecid, GF_TextConfig *cfg)
825
0
{
826
0
  u32 i;
827
0
  Bool has_alt_format;
828
0
#ifndef GPAC_DISABLE_ISOM
829
0
  Bool has_sd;
830
0
  u32 j;
831
0
#endif
832
0
  GF_Err e;
833
0
  GF_BitStream *bs;
834
0
  if (data || data_len || !cfg) return GF_BAD_PARAM;
835
0
  if (codecid != GF_CODECID_TEXT_MPEG4) return GF_NOT_SUPPORTED;
836
837
  /*reset*/
838
0
  ResetTextConfig(cfg);
839
0
  bs = gf_bs_new(data, data_len, GF_BITSTREAM_READ);
840
841
0
  e = GF_OK;
842
0
  cfg->Base3GPPFormat = gf_bs_read_int(bs, 8);
843
0
  cfg->MPEGExtendedFormat = gf_bs_read_int(bs, 8);
844
0
  cfg->profileLevel = gf_bs_read_int(bs, 8);
845
0
  cfg->timescale = gf_bs_read_int(bs, 24);
846
0
  has_alt_format = (Bool)gf_bs_read_int(bs, 1);
847
0
  cfg->sampleDescriptionFlags = gf_bs_read_int(bs, 2);
848
0
#ifndef GPAC_DISABLE_ISOM
849
0
  has_sd = (Bool)gf_bs_read_int(bs, 1);
850
#else
851
  gf_bs_read_int(bs, 1);
852
#endif
853
0
  cfg->has_vid_info = (Bool)gf_bs_read_int(bs, 1);
854
0
  gf_bs_read_int(bs, 3);
855
0
  cfg->layer = gf_bs_read_int(bs, 8);
856
0
  cfg->text_width = gf_bs_read_int(bs, 16);
857
0
  cfg->text_height = gf_bs_read_int(bs, 16);
858
0
  if (has_alt_format) {
859
0
    cfg->nb_compatible_formats = gf_bs_read_int(bs, 8);
860
0
    for (i=0; i<cfg->nb_compatible_formats; i++) cfg->compatible_formats[i] = gf_bs_read_int(bs, 8);
861
0
  }
862
0
#ifndef GPAC_DISABLE_ISOM
863
0
  if (has_sd) {
864
0
    u8 sample_index;
865
0
    GF_TextSampleDescriptor *txdesc;
866
0
    GF_Tx3gSampleEntryBox *a;
867
0
    s64 avail;
868
0
    u32 nb_desc = gf_bs_read_int(bs, 8);
869
870
    /*parse TTU[5]s*/
871
0
    avail = (s64) gf_bs_available(bs);
872
0
    for (i=0; i<nb_desc; i++) {
873
0
      sample_index = gf_bs_read_int(bs, 8);
874
0
      avail -= 1;
875
0
      e = gf_isom_box_parse((GF_Box **) &a, bs);
876
0
      if (e) goto exit;
877
0
      avail -= (s32) a->size;
878
879
0
      if (avail<0) {
880
0
        e = GF_NON_COMPLIANT_BITSTREAM;
881
0
        goto exit;
882
0
      }
883
0
      txdesc = (GF_TextSampleDescriptor *)gf_malloc(sizeof(GF_TextSampleDescriptor));
884
0
      txdesc->sample_index = sample_index;
885
0
      txdesc->displayFlags = a->displayFlags;
886
0
      txdesc->back_color = a->back_color;
887
0
      txdesc->default_pos = a->default_box;
888
0
      txdesc->default_style = a->default_style;
889
0
      txdesc->vert_justif = a->vertical_justification;
890
0
      txdesc->horiz_justif = a->horizontal_justification;
891
0
      txdesc->font_count = a->font_table ? a->font_table->entry_count : 0;
892
0
      if (txdesc->font_count) {
893
0
        txdesc->fonts = (GF_FontRecord*)gf_malloc(sizeof(GF_FontRecord)*txdesc->font_count);
894
0
        for (j=0; j<txdesc->font_count; j++) {
895
0
          txdesc->fonts[j].fontID = a->font_table->fonts[j].fontID;
896
0
          txdesc->fonts[j].fontName = a->font_table->fonts[j].fontName ? gf_strdup(a->font_table->fonts[j].fontName) : NULL;
897
0
        }
898
0
      }
899
0
      gf_list_add(cfg->sample_descriptions, txdesc);
900
0
      gf_isom_box_del((GF_Box *)a);
901
0
    }
902
0
  }
903
0
#endif
904
905
0
  if (cfg->has_vid_info) {
906
0
    cfg->video_width = gf_bs_read_int(bs, 16);
907
0
    cfg->video_height = gf_bs_read_int(bs, 16);
908
0
    cfg->horiz_offset = gf_bs_read_int(bs, 16);
909
0
    cfg->vert_offset = gf_bs_read_int(bs, 16);
910
0
  }
911
912
0
#ifndef GPAC_DISABLE_ISOM
913
0
exit:
914
0
#endif
915
0
  gf_bs_del(bs);
916
0
  if (e) ResetTextConfig(cfg);
917
0
  return e;
918
0
}
919
920
921
922
GF_EXPORT
923
GF_HEVCConfig *gf_odf_hevc_cfg_new()
924
86.4k
{
925
86.4k
  GF_HEVCConfig *cfg;
926
86.4k
  GF_SAFEALLOC(cfg, GF_HEVCConfig);
927
86.4k
  if (!cfg) return NULL;
928
86.4k
  cfg->param_array = gf_list_new();
929
86.4k
  cfg->nal_unit_size = 4;
930
86.4k
  return cfg;
931
86.4k
}
932
933
GF_EXPORT
934
void gf_odf_hevc_cfg_del(GF_HEVCConfig *cfg)
935
86.4k
{
936
86.4k
  if (!cfg) return;
937
113k
  while (gf_list_count(cfg->param_array)) {
938
27.3k
    GF_NALUFFParamArray *pa = (GF_NALUFFParamArray*)gf_list_get(cfg->param_array, 0);
939
27.3k
    gf_list_rem(cfg->param_array, 0);
940
941
30.8k
    while (gf_list_count(pa->nalus)) {
942
3.55k
      GF_NALUFFParam *n = (GF_NALUFFParam*)gf_list_get(pa->nalus, 0);
943
3.55k
      gf_list_rem(pa->nalus, 0);
944
3.55k
      if (n->data) gf_free(n->data);
945
3.55k
      gf_free(n);
946
3.55k
    }
947
27.3k
    gf_list_del(pa->nalus);
948
27.3k
    gf_free(pa);
949
27.3k
  }
950
86.4k
  gf_list_del(cfg->param_array);
951
86.4k
  gf_free(cfg);
952
86.4k
}
953
954
GF_EXPORT
955
GF_Err gf_odf_hevc_cfg_write_bs(GF_HEVCConfig *cfg, GF_BitStream *bs)
956
40.2k
{
957
40.2k
  u32 i, count;
958
959
40.2k
  count = gf_list_count(cfg->param_array);
960
961
40.2k
  if (!cfg->write_annex_b) {
962
40.2k
    gf_bs_write_int(bs, cfg->configurationVersion, 8);
963
964
40.2k
    if (!cfg->is_lhvc) {
965
29.3k
      gf_bs_write_int(bs, cfg->profile_space, 2);
966
29.3k
      gf_bs_write_int(bs, cfg->tier_flag, 1);
967
29.3k
      gf_bs_write_int(bs, cfg->profile_idc, 5);
968
29.3k
      gf_bs_write_int(bs, cfg->general_profile_compatibility_flags, 32);
969
29.3k
      gf_bs_write_int(bs, cfg->progressive_source_flag, 1);
970
29.3k
      gf_bs_write_int(bs, cfg->interlaced_source_flag, 1);
971
29.3k
      gf_bs_write_int(bs, cfg->non_packed_constraint_flag, 1);
972
29.3k
      gf_bs_write_int(bs, cfg->frame_only_constraint_flag, 1);
973
      /*only lowest 44 bits used*/
974
29.3k
      gf_bs_write_long_int(bs, cfg->constraint_indicator_flags, 44);
975
29.3k
      gf_bs_write_int(bs, cfg->level_idc, 8);
976
29.3k
    }
977
978
40.2k
    gf_bs_write_int(bs, 0xFF, 4);
979
40.2k
    gf_bs_write_int(bs, cfg->min_spatial_segmentation_idc, 12);
980
981
40.2k
    gf_bs_write_int(bs, 0xFF, 6);
982
40.2k
    gf_bs_write_int(bs, cfg->parallelismType, 2);
983
984
40.2k
    if (!cfg->is_lhvc) {
985
29.3k
      gf_bs_write_int(bs, 0xFF, 6);
986
29.3k
      gf_bs_write_int(bs, cfg->chromaFormat, 2);
987
29.3k
      gf_bs_write_int(bs, 0xFF, 5);
988
29.3k
      gf_bs_write_int(bs, cfg->luma_bit_depth-8, 3);
989
29.3k
      gf_bs_write_int(bs, 0xFF, 5);
990
29.3k
      gf_bs_write_int(bs, cfg->chroma_bit_depth-8, 3);
991
29.3k
      gf_bs_write_int(bs, cfg->avgFrameRate, 16);
992
993
29.3k
      gf_bs_write_int(bs, cfg->constantFrameRate, 2);
994
29.3k
    } else {
995
10.8k
      gf_bs_write_int(bs, 0xFF, 2);
996
10.8k
    }
997
998
40.2k
    gf_bs_write_int(bs, cfg->numTemporalLayers, 3);
999
40.2k
    gf_bs_write_int(bs, cfg->temporalIdNested, 1);
1000
40.2k
    gf_bs_write_int(bs, cfg->nal_unit_size - 1, 2);
1001
1002
40.2k
    gf_bs_write_int(bs, count, 8);
1003
40.2k
  }
1004
1005
54.3k
  for (i=0; i<count; i++) {
1006
14.1k
    u32 nalucount, j;
1007
14.1k
    GF_NALUFFParamArray *ar = (GF_NALUFFParamArray*)gf_list_get(cfg->param_array, i);
1008
1009
14.1k
    nalucount = gf_list_count(ar->nalus);
1010
14.1k
    if (!cfg->write_annex_b) {
1011
14.1k
      gf_bs_write_int(bs, ar->array_completeness, 1);
1012
14.1k
      gf_bs_write_int(bs, 0, 1);
1013
14.1k
      gf_bs_write_int(bs, ar->type, 6);
1014
14.1k
      gf_bs_write_int(bs, nalucount, 16);
1015
14.1k
    }
1016
1017
16.7k
    for (j=0; j<nalucount; j++) {
1018
2.61k
      GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(ar->nalus, j);
1019
2.61k
      if (!cfg->write_annex_b) {
1020
2.61k
        gf_bs_write_int(bs, sl->size, 16);
1021
2.61k
      } else {
1022
0
        gf_bs_write_u32(bs, 1);
1023
0
      }
1024
2.61k
      gf_bs_write_data(bs, sl->data, sl->size);
1025
2.61k
    }
1026
14.1k
  }
1027
40.2k
  return GF_OK;
1028
40.2k
}
1029
1030
GF_EXPORT
1031
GF_Err gf_odf_hevc_cfg_write(GF_HEVCConfig *cfg, u8 **outData, u32 *outSize)
1032
37.6k
{
1033
37.6k
  GF_Err e;
1034
37.6k
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1035
37.6k
  *outSize = 0;
1036
37.6k
  *outData = NULL;
1037
37.6k
  e = gf_odf_hevc_cfg_write_bs(cfg, bs);
1038
37.6k
  if (e==GF_OK)
1039
37.6k
    gf_bs_get_content(bs, outData, outSize);
1040
1041
37.6k
  gf_bs_del(bs);
1042
37.6k
  return e;
1043
37.6k
}
1044
1045
GF_EXPORT
1046
GF_HEVCConfig *gf_odf_hevc_cfg_read_bs(GF_BitStream *bs, Bool is_lhvc)
1047
14.8k
{
1048
14.8k
  u32 i, count;
1049
14.8k
  GF_HEVCConfig *cfg = gf_odf_hevc_cfg_new();
1050
1051
14.8k
  cfg->is_lhvc = is_lhvc;
1052
1053
14.8k
  cfg->configurationVersion = gf_bs_read_int(bs, 8);
1054
1055
14.8k
  if (!is_lhvc) {
1056
10.5k
    cfg->profile_space = gf_bs_read_int(bs, 2);
1057
10.5k
    cfg->tier_flag = gf_bs_read_int(bs, 1);
1058
10.5k
    cfg->profile_idc = gf_bs_read_int(bs, 5);
1059
10.5k
    cfg->general_profile_compatibility_flags = gf_bs_read_int(bs, 32);
1060
1061
10.5k
    cfg->progressive_source_flag = gf_bs_read_int(bs, 1);
1062
10.5k
    cfg->interlaced_source_flag = gf_bs_read_int(bs, 1);
1063
10.5k
    cfg->non_packed_constraint_flag = gf_bs_read_int(bs, 1);
1064
10.5k
    cfg->frame_only_constraint_flag = gf_bs_read_int(bs, 1);
1065
    /*only lowest 44 bits used*/
1066
10.5k
    cfg->constraint_indicator_flags = gf_bs_read_long_int(bs, 44);
1067
10.5k
    cfg->level_idc = gf_bs_read_int(bs, 8);
1068
10.5k
  }
1069
1070
14.8k
  gf_bs_read_int(bs, 4); //reserved
1071
14.8k
  cfg->min_spatial_segmentation_idc = gf_bs_read_int(bs, 12);
1072
1073
14.8k
  gf_bs_read_int(bs, 6);//reserved
1074
14.8k
  cfg->parallelismType = gf_bs_read_int(bs, 2);
1075
1076
14.8k
  if (!is_lhvc) {
1077
10.5k
    gf_bs_read_int(bs, 6);
1078
10.5k
    cfg->chromaFormat = gf_bs_read_int(bs, 2);
1079
10.5k
    gf_bs_read_int(bs, 5);
1080
10.5k
    cfg->luma_bit_depth = gf_bs_read_int(bs, 3) + 8;
1081
10.5k
    gf_bs_read_int(bs, 5);
1082
10.5k
    cfg->chroma_bit_depth = gf_bs_read_int(bs, 3) + 8;
1083
10.5k
    cfg->avgFrameRate = gf_bs_read_int(bs, 16);
1084
1085
10.5k
    cfg->constantFrameRate = gf_bs_read_int(bs, 2);
1086
10.5k
  } else {
1087
4.24k
    gf_bs_read_int(bs, 2); //reserved
1088
4.24k
  }
1089
1090
14.8k
  cfg->numTemporalLayers = gf_bs_read_int(bs, 3);
1091
14.8k
  cfg->temporalIdNested = gf_bs_read_int(bs, 1);
1092
1093
14.8k
  cfg->nal_unit_size = 1 + gf_bs_read_int(bs, 2);
1094
1095
14.8k
  count = gf_bs_read_int(bs, 8);
1096
41.6k
  for (i=0; i<count; i++) {
1097
27.3k
    u32 nalucount, j;
1098
27.3k
    GF_NALUFFParamArray *ar;
1099
27.3k
    GF_SAFEALLOC(ar, GF_NALUFFParamArray);
1100
27.3k
    if (!ar) {
1101
0
      gf_odf_hevc_cfg_del(cfg);
1102
0
      return NULL;
1103
0
    }
1104
27.3k
    ar->nalus = gf_list_new();
1105
27.3k
    gf_list_add(cfg->param_array, ar);
1106
1107
27.3k
    ar->array_completeness = gf_bs_read_int(bs, 1);
1108
27.3k
    gf_bs_read_int(bs, 1);
1109
27.3k
    ar->type = gf_bs_read_int(bs, 6);
1110
27.3k
    nalucount = gf_bs_read_int(bs, 16);
1111
30.8k
    for (j=0; j<nalucount; j++) {
1112
4.05k
      GF_NALUFFParam *sl;
1113
4.05k
      u32 size = gf_bs_read_int(bs, 16);
1114
4.05k
      if ((size>gf_bs_available(bs)) || (size<2)) {
1115
496
        GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] Wrong param set size %d\n", size));
1116
496
        gf_odf_hevc_cfg_del(cfg);
1117
496
        return NULL;
1118
496
      }
1119
3.55k
      GF_SAFEALLOC(sl, GF_NALUFFParam );
1120
3.55k
      if (!sl) {
1121
0
        gf_odf_hevc_cfg_del(cfg);
1122
0
        return NULL;
1123
0
      }
1124
1125
3.55k
      sl->size = size;
1126
3.55k
      sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
1127
3.55k
      gf_bs_read_data(bs, sl->data, sl->size);
1128
3.55k
      gf_list_add(ar->nalus, sl);
1129
3.55k
    }
1130
27.3k
  }
1131
14.3k
  return cfg;
1132
14.8k
}
1133
1134
GF_EXPORT
1135
GF_HEVCConfig *gf_odf_hevc_cfg_read(u8 *dsi, u32 dsi_size, Bool is_lhvc)
1136
8.73k
{
1137
8.73k
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
1138
8.73k
  GF_HEVCConfig *cfg = gf_odf_hevc_cfg_read_bs(bs, is_lhvc);
1139
8.73k
  gf_bs_del(bs);
1140
8.73k
  return cfg;
1141
8.73k
}
1142
1143
GF_EXPORT
1144
GF_VVCConfig *gf_odf_vvc_cfg_new()
1145
32.7k
{
1146
32.7k
  GF_VVCConfig *cfg;
1147
32.7k
  GF_SAFEALLOC(cfg, GF_VVCConfig);
1148
32.7k
  if (!cfg) return NULL;
1149
32.7k
  cfg->param_array = gf_list_new();
1150
32.7k
  cfg->nal_unit_size = 4;
1151
32.7k
  cfg->chroma_format = 1;
1152
32.7k
  cfg->bit_depth = 8;
1153
32.7k
  return cfg;
1154
32.7k
}
1155
1156
GF_EXPORT
1157
void gf_odf_vvc_cfg_del(GF_VVCConfig *cfg)
1158
32.7k
{
1159
32.7k
  if (!cfg) return;
1160
35.7k
  while (gf_list_count(cfg->param_array)) {
1161
3.00k
    GF_NALUFFParamArray *pa = (GF_NALUFFParamArray*)gf_list_get(cfg->param_array, 0);
1162
3.00k
    gf_list_rem(cfg->param_array, 0);
1163
1164
4.54k
    while (gf_list_count(pa->nalus)) {
1165
1.53k
      GF_NALUFFParam *n = (GF_NALUFFParam*)gf_list_get(pa->nalus, 0);
1166
1.53k
      gf_list_rem(pa->nalus, 0);
1167
1.53k
      if (n->data) gf_free(n->data);
1168
1.53k
      gf_free(n);
1169
1.53k
    }
1170
3.00k
    gf_list_del(pa->nalus);
1171
3.00k
    gf_free(pa);
1172
3.00k
  }
1173
32.7k
  gf_list_del(cfg->param_array);
1174
32.7k
  if (cfg->general_constraint_info)
1175
20.9k
    gf_free(cfg->general_constraint_info);
1176
32.7k
  if (cfg->sub_profiles_idc)
1177
495
    gf_free(cfg->sub_profiles_idc);
1178
32.7k
  gf_free(cfg);
1179
32.7k
}
1180
1181
GF_EXPORT
1182
GF_Err gf_odf_vvc_cfg_write_bs(GF_VVCConfig *cfg, GF_BitStream *bs)
1183
20.9k
{
1184
20.9k
  u32 i, count;
1185
1186
20.9k
  count = gf_list_count(cfg->param_array);
1187
1188
20.9k
  if (!cfg->write_annex_b) {
1189
1190
20.9k
    gf_bs_write_int(bs, 0xFF, 5);
1191
20.9k
    gf_bs_write_int(bs, cfg->nal_unit_size - 1, 2);
1192
20.9k
    gf_bs_write_int(bs, cfg->ptl_present, 1);
1193
1194
20.9k
    if (cfg->ptl_present) {
1195
13.9k
      s32 idx;
1196
1197
13.9k
      gf_bs_write_int(bs, cfg->ols_idx, 9);
1198
13.9k
      gf_bs_write_int(bs, cfg->numTemporalLayers, 3);
1199
13.9k
      gf_bs_write_int(bs, cfg->constantFrameRate, 2);
1200
13.9k
      gf_bs_write_int(bs, cfg->chroma_format, 2);
1201
13.9k
      gf_bs_write_int(bs, cfg->bit_depth - 8, 3);
1202
13.9k
      gf_bs_write_int(bs, 0xFF, 5);
1203
1204
13.9k
      if (!cfg->general_constraint_info)
1205
0
        cfg->num_constraint_info = 0;
1206
1207
      //write PTL
1208
13.9k
      gf_bs_write_int(bs, 0, 2);
1209
13.9k
      gf_bs_write_int(bs, cfg->num_constraint_info, 6);
1210
13.9k
      gf_bs_write_int(bs, cfg->general_profile_idc, 7);
1211
13.9k
      gf_bs_write_int(bs, cfg->general_tier_flag, 1);
1212
13.9k
      gf_bs_write_u8(bs, cfg->general_level_idc);
1213
13.9k
      gf_bs_write_int(bs, cfg->ptl_frame_only_constraint, 1);
1214
13.9k
      gf_bs_write_int(bs, cfg->ptl_multilayer_enabled, 1);
1215
1216
13.9k
      if (cfg->num_constraint_info) {
1217
13.9k
        gf_bs_write_data(bs, cfg->general_constraint_info, cfg->num_constraint_info - 1);
1218
13.9k
        gf_bs_write_int(bs, cfg->general_constraint_info[cfg->num_constraint_info - 1], 6);
1219
13.9k
      } else {
1220
0
        gf_bs_write_int(bs, 0, 6);
1221
0
      }
1222
1223
31.0k
      for (idx=cfg->numTemporalLayers-2; idx>=0; idx--) {
1224
17.1k
        u8 val = cfg->ptl_sublayer_present_mask & (1<<idx);
1225
17.1k
        gf_bs_write_int(bs, val ? 1 : 0, 1);
1226
17.1k
      }
1227
31.9k
      for (idx=cfg->numTemporalLayers; idx<=8 && cfg->numTemporalLayers>1; idx++) {
1228
17.9k
        gf_bs_write_int(bs, 0, 1);
1229
17.9k
      }
1230
31.0k
      for (idx=cfg->numTemporalLayers-2; idx>=0; idx--) {
1231
17.1k
        if (cfg->ptl_sublayer_present_mask & (1<<idx))
1232
0
          gf_bs_write_u8(bs, cfg->sublayer_level_idc[idx]);
1233
17.1k
      }
1234
13.9k
      if (!cfg->sub_profiles_idc) cfg->num_sub_profiles = 0;
1235
13.9k
      gf_bs_write_u8(bs, cfg->num_sub_profiles);
1236
13.9k
      for (idx=0; idx<cfg->num_sub_profiles; idx++) {
1237
0
        gf_bs_write_u32(bs, cfg->sub_profiles_idc[idx]);
1238
0
      }
1239
      //end PTL
1240
1241
13.9k
      gf_bs_write_u16(bs, cfg->maxPictureWidth);
1242
13.9k
      gf_bs_write_u16(bs, cfg->maxPictureHeight);
1243
13.9k
      gf_bs_write_u16(bs, cfg->avgFrameRate);
1244
13.9k
    }
1245
20.9k
    gf_bs_write_int(bs, count, 8);
1246
20.9k
  }
1247
1248
20.9k
  for (i=0; i<count; i++) {
1249
0
    u32 nalucount, j;
1250
0
    GF_NALUFFParamArray *ar = (GF_NALUFFParamArray*)gf_list_get(cfg->param_array, i);
1251
1252
0
    nalucount = gf_list_count(ar->nalus);
1253
0
    if (!cfg->write_annex_b) {
1254
0
      gf_bs_write_int(bs, ar->array_completeness, 1);
1255
0
      gf_bs_write_int(bs, 0, 2);
1256
0
      gf_bs_write_int(bs, ar->type, 5);
1257
1258
0
      if ((ar->type != GF_VVC_NALU_DEC_PARAM) && (ar->type != GF_VVC_NALU_OPI))
1259
0
        gf_bs_write_int(bs, nalucount, 16);
1260
0
      else
1261
0
        nalucount = 1;
1262
0
    }
1263
1264
0
    for (j=0; j<nalucount; j++) {
1265
0
      GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(ar->nalus, j);
1266
0
      if (!sl)
1267
0
        return GF_ISOM_INVALID_MEDIA;
1268
0
      if (!cfg->write_annex_b) {
1269
0
        gf_bs_write_int(bs, sl->size, 16);
1270
0
      } else {
1271
0
        gf_bs_write_u32(bs, 1);
1272
0
      }
1273
0
      gf_bs_write_data(bs, sl->data, sl->size);
1274
0
    }
1275
0
  }
1276
20.9k
  return GF_OK;
1277
20.9k
}
1278
1279
GF_EXPORT
1280
GF_Err gf_odf_vvc_cfg_write(GF_VVCConfig *cfg, u8 **outData, u32 *outSize)
1281
20.9k
{
1282
20.9k
  GF_Err e;
1283
20.9k
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1284
20.9k
  *outSize = 0;
1285
20.9k
  *outData = NULL;
1286
20.9k
  e = gf_odf_vvc_cfg_write_bs(cfg, bs);
1287
20.9k
  if (e==GF_OK)
1288
20.9k
    gf_bs_get_content(bs, outData, outSize);
1289
1290
20.9k
  gf_bs_del(bs);
1291
20.9k
  return e;
1292
20.9k
}
1293
1294
GF_EXPORT
1295
GF_VVCConfig *gf_odf_vvc_cfg_read_bs(GF_BitStream *bs)
1296
11.7k
{
1297
11.7k
  u32 i, count;
1298
11.7k
  GF_VVCConfig *cfg = gf_odf_vvc_cfg_new();
1299
1300
11.7k
  gf_bs_read_int(bs, 5);
1301
11.7k
  cfg->nal_unit_size = 1 + gf_bs_read_int(bs, 2);
1302
11.7k
  cfg->ptl_present = gf_bs_read_int(bs, 1);
1303
1304
11.7k
  if (cfg->ptl_present) {
1305
7.17k
    s32 j;
1306
1307
7.17k
    cfg->ols_idx = gf_bs_read_int(bs, 9);
1308
7.17k
    cfg->numTemporalLayers = gf_bs_read_int(bs, 3);
1309
7.17k
    cfg->constantFrameRate = gf_bs_read_int(bs, 2);
1310
7.17k
    cfg->chroma_format = gf_bs_read_int(bs, 2);
1311
7.17k
    cfg->bit_depth = 8 + gf_bs_read_int(bs, 3);
1312
7.17k
    gf_bs_read_int(bs, 5);
1313
1314
    //parse PTL
1315
7.17k
    gf_bs_read_int(bs, 2);
1316
7.17k
    cfg->num_constraint_info = gf_bs_read_int(bs, 6);
1317
7.17k
    cfg->general_profile_idc = gf_bs_read_int(bs, 7);
1318
7.17k
    cfg->general_tier_flag = gf_bs_read_int(bs, 1);
1319
7.17k
    cfg->general_level_idc = gf_bs_read_u8(bs);
1320
7.17k
    cfg->ptl_frame_only_constraint = gf_bs_read_int(bs, 1);
1321
7.17k
    cfg->ptl_multilayer_enabled = gf_bs_read_int(bs, 1);
1322
1323
7.17k
    if (cfg->num_constraint_info) {
1324
6.92k
      cfg->general_constraint_info = gf_malloc(sizeof(u8)*cfg->num_constraint_info);
1325
6.92k
      if (!cfg->general_constraint_info) {
1326
0
        gf_free(cfg);
1327
0
        GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VVC] alloc failed while parsing vvc config\n"));
1328
0
        return NULL;
1329
0
      }
1330
6.92k
      gf_bs_read_data(bs, cfg->general_constraint_info, cfg->num_constraint_info - 1);
1331
6.92k
      cfg->general_constraint_info[cfg->num_constraint_info-1] =  gf_bs_read_int(bs, 6);
1332
6.92k
    } else {
1333
      //forbidden in spec!
1334
253
      gf_bs_read_int(bs, 6);
1335
253
    }
1336
1337
7.17k
    cfg->ptl_sublayer_present_mask = 0;
1338
20.3k
    for (j=cfg->numTemporalLayers-2; j>=0; j--) {
1339
13.1k
      u32 val = gf_bs_read_int(bs, 1);
1340
13.1k
      cfg->ptl_sublayer_present_mask |= val << j;
1341
13.1k
    }
1342
21.7k
    for (j=cfg->numTemporalLayers; j<=8 && cfg->numTemporalLayers>1; j++) {
1343
14.5k
      gf_bs_read_int(bs, 1);
1344
14.5k
    }
1345
20.3k
    for (j=cfg->numTemporalLayers-2; j>=0; j--) {
1346
13.1k
      if (cfg->ptl_sublayer_present_mask & (1<<j)) {
1347
949
        cfg->sublayer_level_idc[j] = gf_bs_read_u8(bs);
1348
949
      }
1349
13.1k
    }
1350
7.17k
    cfg->num_sub_profiles = gf_bs_read_u8(bs);
1351
7.17k
    if (cfg->num_sub_profiles) {
1352
495
      cfg->sub_profiles_idc = gf_malloc(sizeof(u32)*cfg->num_sub_profiles);
1353
495
      if (!cfg->sub_profiles_idc) {
1354
0
        gf_free(cfg->general_constraint_info);
1355
0
        gf_free(cfg);
1356
0
        GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VVC] alloc failed while parsing vvc config\n"));
1357
0
        return NULL;
1358
0
      }
1359
495
    }
1360
87.4k
    for (i=0; i<cfg->num_sub_profiles; i++) {
1361
80.2k
      cfg->sub_profiles_idc[i] = gf_bs_read_u32(bs);
1362
80.2k
    }
1363
1364
    //end PTL
1365
1366
7.17k
    cfg->maxPictureWidth = gf_bs_read_u16(bs);
1367
7.17k
    cfg->maxPictureHeight = gf_bs_read_u16(bs);
1368
7.17k
    cfg->avgFrameRate = gf_bs_read_u16(bs);
1369
7.17k
  }
1370
1371
11.7k
  count = gf_bs_read_int(bs, 8);
1372
63.5k
  for (i=0; i<count; i++) {
1373
53.4k
    u32 nalucount, j;
1374
53.4k
    Bool valid = GF_FALSE;
1375
53.4k
    GF_NALUFFParamArray *ar;
1376
53.4k
    GF_SAFEALLOC(ar, GF_NALUFFParamArray);
1377
53.4k
    if (!ar) {
1378
0
      gf_odf_vvc_cfg_del(cfg);
1379
0
      GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VVC] alloc failed while parsing vvc config\n"));
1380
0
      return NULL;
1381
0
    }
1382
53.4k
    ar->array_completeness = gf_bs_read_int(bs, 1);
1383
53.4k
    gf_bs_read_int(bs, 2);
1384
53.4k
    ar->type = gf_bs_read_int(bs, 5);
1385
1386
53.4k
    switch (ar->type) {
1387
801
    case GF_VVC_NALU_DEC_PARAM:
1388
1.29k
    case GF_VVC_NALU_OPI:
1389
1.83k
    case GF_VVC_NALU_VID_PARAM:
1390
2.32k
    case GF_VVC_NALU_SEQ_PARAM:
1391
2.59k
    case GF_VVC_NALU_PIC_PARAM:
1392
2.87k
    case GF_VVC_NALU_SEI_PREFIX:
1393
3.00k
    case GF_VVC_NALU_SEI_SUFFIX:
1394
3.00k
      valid = GF_TRUE;
1395
3.00k
      ar->nalus = gf_list_new();
1396
3.00k
      gf_list_add(cfg->param_array, ar);
1397
3.00k
      break;
1398
50.4k
    default:
1399
50.4k
      GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[VVC] Invalid NALU type %d in vvcC - ignoring\n", ar->type));
1400
50.4k
      gf_free(ar);
1401
50.4k
      break;
1402
53.4k
    }
1403
1404
53.4k
    if (!valid || ((ar->type != GF_VVC_NALU_DEC_PARAM) && (ar->type != GF_VVC_NALU_OPI)))
1405
52.1k
      nalucount = gf_bs_read_int(bs, 16);
1406
1.29k
    else
1407
1.29k
      nalucount = 1;
1408
1409
55.1k
    for (j=0; j<nalucount; j++) {
1410
3.42k
      GF_NALUFFParam *sl;
1411
3.42k
      u32 size = gf_bs_read_int(bs, 16);
1412
3.42k
      if ((size>gf_bs_available(bs)) || (size<2)) {
1413
1.69k
        GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VVC] Wrong param set size %d\n", size));
1414
1.69k
        gf_odf_vvc_cfg_del(cfg);
1415
1.69k
        return NULL;
1416
1.69k
      }
1417
1.72k
      if (!valid) {
1418
190
        gf_bs_skip_bytes(bs, size);
1419
190
        continue;
1420
190
      }
1421
1.53k
      GF_SAFEALLOC(sl, GF_NALUFFParam );
1422
1.53k
      if (!sl) {
1423
0
        gf_odf_vvc_cfg_del(cfg);
1424
0
        GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VVC] alloc failed while parsing vvc config\n"));
1425
0
        return NULL;
1426
0
      }
1427
1428
1.53k
      sl->size = size;
1429
1.53k
      sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
1430
1.53k
      if (!sl->data) {
1431
0
        gf_free(sl);
1432
0
        gf_odf_vvc_cfg_del(cfg);
1433
0
        GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VVC] alloc failed while parsing vvc config\n"));
1434
0
        return NULL;
1435
0
      }
1436
1.53k
      gf_bs_read_data(bs, sl->data, sl->size);
1437
1.53k
      gf_list_add(ar->nalus, sl);
1438
1.53k
    }
1439
53.4k
  }
1440
10.0k
  return cfg;
1441
11.7k
}
1442
1443
GF_EXPORT
1444
GF_VVCConfig *gf_odf_vvc_cfg_read(u8 *dsi, u32 dsi_size)
1445
7.95k
{
1446
7.95k
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
1447
7.95k
  GF_VVCConfig *cfg = gf_odf_vvc_cfg_read_bs(bs);
1448
7.95k
  gf_bs_del(bs);
1449
7.95k
  return cfg;
1450
7.95k
}
1451
1452
GF_EXPORT
1453
GF_AV1Config *gf_odf_av1_cfg_new()
1454
50.1k
{
1455
50.1k
  GF_AV1Config *cfg;
1456
50.1k
  GF_SAFEALLOC(cfg, GF_AV1Config);
1457
50.1k
  if (!cfg) return NULL;
1458
50.1k
  cfg->marker = 1;
1459
50.1k
  cfg->version = 1;
1460
50.1k
  cfg->initial_presentation_delay_minus_one = 0;
1461
50.1k
  cfg->obu_array = gf_list_new();
1462
50.1k
  return cfg;
1463
50.1k
}
1464
1465
GF_EXPORT
1466
void gf_odf_av1_cfg_del(GF_AV1Config *cfg)
1467
52.1k
{
1468
52.1k
  if (!cfg) return;
1469
331k
  while (gf_list_count(cfg->obu_array)) {
1470
279k
    GF_AV1_OBUArrayEntry *a = (GF_AV1_OBUArrayEntry*)gf_list_get(cfg->obu_array, 0);
1471
279k
    if (a->obu) gf_free(a->obu);
1472
279k
    gf_list_rem(cfg->obu_array, 0);
1473
279k
    gf_free(a);
1474
279k
  }
1475
52.1k
  gf_list_del(cfg->obu_array);
1476
52.1k
  gf_free(cfg);
1477
52.1k
}
1478
1479
GF_EXPORT
1480
GF_Err gf_odf_av1_cfg_write_bs(GF_AV1Config *cfg, GF_BitStream *bs)
1481
3.34k
{
1482
3.34k
  u32 i = 0;
1483
3.34k
  gf_bs_write_int(bs, cfg->marker, 1);
1484
3.34k
  gf_assert(cfg->marker == 1);
1485
3.34k
  gf_bs_write_int(bs, cfg->version, 7);
1486
3.34k
  gf_assert(cfg->version == 1);
1487
3.34k
  gf_bs_write_int(bs, cfg->seq_profile, 3);
1488
3.34k
  gf_bs_write_int(bs, cfg->seq_level_idx_0, 5);
1489
3.34k
  gf_bs_write_int(bs, cfg->seq_tier_0, 1);
1490
3.34k
  gf_bs_write_int(bs, cfg->high_bitdepth, 1);
1491
3.34k
  gf_bs_write_int(bs, cfg->twelve_bit, 1);
1492
3.34k
  gf_bs_write_int(bs, cfg->monochrome, 1);
1493
3.34k
  gf_bs_write_int(bs, cfg->chroma_subsampling_x, 1);
1494
3.34k
  gf_bs_write_int(bs, cfg->chroma_subsampling_y, 1);
1495
3.34k
  gf_bs_write_int(bs, cfg->chroma_sample_position, 2);
1496
3.34k
  gf_bs_write_int(bs, 0, 3); /*reserved*/
1497
3.34k
  gf_bs_write_int(bs, cfg->initial_presentation_delay_present, 1);
1498
3.34k
  gf_bs_write_int(bs, cfg->initial_presentation_delay_minus_one, 4); /*TODO: compute initial_presentation_delay_minus_one*/
1499
115k
  for (i = 0; i < gf_list_count(cfg->obu_array); ++i) {
1500
111k
    GF_AV1_OBUArrayEntry *a = gf_list_get(cfg->obu_array, i);
1501
111k
    gf_bs_write_data(bs, a->obu, (u32)a->obu_length); //TODO: we are supposed to omit the size on the last OBU...
1502
111k
  }
1503
3.34k
  return GF_OK;
1504
3.34k
}
1505
1506
GF_EXPORT
1507
3.34k
GF_Err gf_odf_av1_cfg_write(GF_AV1Config *cfg, u8 **outData, u32 *outSize) {
1508
3.34k
  GF_Err e;
1509
3.34k
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1510
3.34k
  *outSize = 0;
1511
3.34k
  *outData = NULL;
1512
3.34k
  e = gf_odf_av1_cfg_write_bs(cfg, bs);
1513
3.34k
  if (e == GF_OK)
1514
3.34k
    gf_bs_get_content(bs, outData, outSize);
1515
1516
3.34k
  gf_bs_del(bs);
1517
3.34k
  return e;
1518
3.34k
}
1519
1520
GF_EXPORT
1521
GF_VPConfig *gf_odf_vp_cfg_new()
1522
2.25k
{
1523
2.25k
  GF_VPConfig *cfg;
1524
2.25k
  GF_SAFEALLOC(cfg, GF_VPConfig);
1525
2.25k
  if (!cfg) return NULL;
1526
2.25k
  cfg->codec_initdata_size = 0;
1527
2.25k
  cfg->codec_initdata = NULL;
1528
2.25k
  return cfg;
1529
2.25k
}
1530
1531
GF_EXPORT
1532
void gf_odf_vp_cfg_del(GF_VPConfig *cfg)
1533
2.25k
{
1534
2.25k
  if (!cfg) return;
1535
1536
2.25k
  if (cfg->codec_initdata) {
1537
0
    gf_free(cfg->codec_initdata);
1538
0
    cfg->codec_initdata = NULL;
1539
0
  }
1540
1541
2.25k
  gf_free(cfg);
1542
2.25k
}
1543
1544
GF_EXPORT
1545
GF_Err gf_odf_vp_cfg_write_bs(GF_VPConfig *cfg, GF_BitStream *bs, Bool is_v0)
1546
1.24k
{
1547
1.24k
  gf_bs_write_int(bs, cfg->profile, 8);
1548
1.24k
  gf_bs_write_int(bs, cfg->level, 8);
1549
1.24k
  gf_bs_write_int(bs, cfg->bit_depth, 4);
1550
1.24k
  gf_bs_write_int(bs, cfg->chroma_subsampling, 3);
1551
1.24k
  gf_bs_write_int(bs, cfg->video_fullRange_flag, 1);
1552
1.24k
  gf_bs_write_int(bs, cfg->colour_primaries, 8);
1553
1.24k
  gf_bs_write_int(bs, cfg->transfer_characteristics, 8);
1554
1.24k
  gf_bs_write_int(bs, cfg->matrix_coefficients, 8);
1555
1556
1.24k
  if (!is_v0) {
1557
1.24k
    if (cfg->codec_initdata_size) {
1558
0
      GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[VPX] Invalid data in configuration: codec_initdata_size must be 0, was %d - ignoring\n", cfg->codec_initdata_size));
1559
0
    }
1560
1561
1.24k
    gf_bs_write_int(bs, (u16)0, 16);
1562
1.24k
  }
1563
1564
1.24k
  return GF_OK;
1565
1.24k
}
1566
1567
GF_EXPORT
1568
GF_Err gf_odf_vp_cfg_write(GF_VPConfig *cfg, u8 **outData, u32 *outSize, Bool is_v0)
1569
1.24k
{
1570
1.24k
  GF_Err e;
1571
1.24k
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1572
1.24k
  *outSize = 0;
1573
1.24k
  *outData = NULL;
1574
1.24k
  e = gf_odf_vp_cfg_write_bs(cfg, bs, is_v0);
1575
1.24k
  if (e==GF_OK)
1576
1.24k
    gf_bs_get_content(bs, outData, outSize);
1577
1578
1.24k
  gf_bs_del(bs);
1579
1.24k
  return e;
1580
1.24k
}
1581
1582
GF_EXPORT
1583
GF_VPConfig *gf_odf_vp_cfg_read_bs(GF_BitStream *bs, Bool is_v0)
1584
1.61k
{
1585
1.61k
  GF_VPConfig *cfg = gf_odf_vp_cfg_new();
1586
1587
1.61k
  cfg->profile = gf_bs_read_int(bs, 8);
1588
1.61k
  cfg->level = gf_bs_read_int(bs, 8);
1589
1590
1.61k
  cfg->bit_depth = gf_bs_read_int(bs, 4);
1591
1.61k
  cfg->chroma_subsampling = gf_bs_read_int(bs, 3);
1592
1.61k
  cfg->video_fullRange_flag = gf_bs_read_int(bs, 1);
1593
1594
1.61k
  cfg->colour_primaries = gf_bs_read_int(bs, 8);
1595
1.61k
  cfg->transfer_characteristics = gf_bs_read_int(bs, 8);
1596
1.61k
  cfg->matrix_coefficients = gf_bs_read_int(bs, 8);
1597
1598
1.61k
  if (is_v0)
1599
1.00k
    return cfg;
1600
1601
616
  cfg->codec_initdata_size = gf_bs_read_int(bs, 16);
1602
1603
  // must be 0 according to spec
1604
616
  if (cfg->codec_initdata_size) {
1605
367
    GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VPX] Invalid data in configuration: codec_initdata_size must be 0, was %d\n", cfg->codec_initdata_size));
1606
367
    gf_odf_vp_cfg_del(cfg);
1607
367
    return NULL;
1608
367
  }
1609
1610
249
  return cfg;
1611
616
}
1612
1613
GF_EXPORT
1614
GF_VPConfig *gf_odf_vp_cfg_read(u8 *dsi, u32 dsi_size)
1615
32
{
1616
32
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
1617
32
  GF_VPConfig *cfg = gf_odf_vp_cfg_read_bs(bs, GF_FALSE);
1618
32
  gf_bs_del(bs);
1619
32
  return cfg;
1620
32
}
1621
1622
GF_EXPORT
1623
GF_AV1Config *gf_odf_av1_cfg_read_bs_size(GF_BitStream *bs, u32 size)
1624
46.6k
{
1625
46.6k
#ifndef GPAC_DISABLE_AV_PARSERS
1626
46.6k
  AV1State *av1_state;
1627
46.6k
  u8 reserved;
1628
46.6k
  GF_AV1Config *cfg;
1629
1630
46.6k
  if (!size) size = (u32) gf_bs_available(bs);
1631
46.6k
  if (!size) return NULL;
1632
1633
46.6k
  GF_SAFEALLOC(av1_state, AV1State);
1634
46.6k
  if (!av1_state) return NULL;
1635
46.6k
  cfg = gf_odf_av1_cfg_new();
1636
46.6k
  gf_av1_init_state(av1_state);
1637
46.6k
  av1_state->config = cfg;
1638
1639
46.6k
  cfg->marker = gf_bs_read_int(bs, 1);
1640
46.6k
  cfg->version = gf_bs_read_int(bs, 7);
1641
46.6k
  cfg->seq_profile = gf_bs_read_int(bs, 3);
1642
46.6k
  cfg->seq_level_idx_0 = gf_bs_read_int(bs, 5);
1643
46.6k
  cfg->seq_tier_0 = gf_bs_read_int(bs, 1);
1644
46.6k
  cfg->high_bitdepth = gf_bs_read_int(bs, 1);
1645
46.6k
  cfg->twelve_bit = gf_bs_read_int(bs, 1);
1646
46.6k
  cfg->monochrome = gf_bs_read_int(bs, 1);
1647
46.6k
  cfg->chroma_subsampling_x = gf_bs_read_int(bs, 1);
1648
46.6k
  cfg->chroma_subsampling_y = gf_bs_read_int(bs, 1);
1649
46.6k
  cfg->chroma_sample_position = gf_bs_read_int(bs, 2);
1650
1651
46.6k
  reserved = gf_bs_read_int(bs, 3);
1652
46.6k
  cfg->initial_presentation_delay_present = gf_bs_read_int(bs, 1);
1653
46.6k
  if (cfg->initial_presentation_delay_present) {
1654
3.42k
    cfg->initial_presentation_delay_minus_one = gf_bs_read_int(bs, 4);
1655
43.1k
  } else {
1656
43.1k
    /*reserved = */gf_bs_read_int(bs, 4);
1657
43.1k
    cfg->initial_presentation_delay_minus_one = 0;
1658
43.1k
  }
1659
46.6k
  size -= 4;
1660
1661
46.6k
  if (reserved != 0 || cfg->marker != 1 || cfg->version != 1) {
1662
3.00k
    GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[AV1] av1C: wrong reserved %d / marker %d / version %d expecting 0 1 1\n", reserved, cfg->marker, cfg->version));
1663
3.00k
    gf_odf_av1_cfg_del(cfg);
1664
3.00k
    gf_free(av1_state);
1665
3.00k
    return NULL;
1666
3.00k
  }
1667
1668
212k
  while (size) {
1669
206k
    u64 pos, obu_size;
1670
206k
    ObuType obu_type;
1671
206k
    GF_AV1_OBUArrayEntry *a;
1672
1673
206k
    pos = gf_bs_get_position(bs);
1674
206k
    obu_size = 0;
1675
206k
    if (gf_av1_parse_obu(bs, &obu_type, &obu_size, NULL, av1_state) != GF_OK) {
1676
37.1k
      GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] av1C: could not parse AV1 OBU at position "LLU". Leaving parsing.\n", pos));
1677
37.1k
      break;
1678
37.1k
    }
1679
169k
    gf_assert(obu_size == gf_bs_get_position(bs) - pos);
1680
169k
    GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[AV1] av1C: parsed AV1 OBU type=%u size="LLU" at position "LLU".\n", obu_type, obu_size, pos));
1681
1682
169k
    if (!av1_is_obu_header(obu_type)) {
1683
135k
      GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[AV1] av1C: AV1 unexpected OBU type=%u size="LLU" found at position "LLU". Forwarding.\n", pos));
1684
135k
    }
1685
169k
    GF_SAFEALLOC(a, GF_AV1_OBUArrayEntry);
1686
169k
    if (!a) break;
1687
169k
    a->obu = gf_malloc((size_t)obu_size);
1688
169k
    if (!a->obu) {
1689
0
      gf_free(a);
1690
0
      break;
1691
0
    }
1692
169k
    gf_bs_seek(bs, pos);
1693
169k
    gf_bs_read_data(bs, (char *) a->obu, (u32)obu_size);
1694
169k
    a->obu_length = obu_size;
1695
169k
    a->obu_type = obu_type;
1696
169k
    gf_list_add(cfg->obu_array, a);
1697
1698
169k
    if (size<obu_size) {
1699
1.28k
      GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] AV1 config misses %d bytes to fit the entire OBU\n", obu_size - size));
1700
1.28k
      break;
1701
1.28k
    }
1702
168k
    size -= (u32) obu_size;
1703
168k
  }
1704
43.6k
  gf_av1_reset_state(av1_state, GF_TRUE);
1705
43.6k
  gf_bs_align(bs);
1706
43.6k
  gf_free(av1_state);
1707
43.6k
  return cfg;
1708
#else
1709
  return NULL;
1710
#endif
1711
46.6k
}
1712
1713
GF_EXPORT
1714
GF_AV1Config *gf_odf_av1_cfg_read_bs(GF_BitStream *bs)
1715
2.59k
{
1716
2.59k
  return gf_odf_av1_cfg_read_bs_size(bs, 0);
1717
1718
2.59k
}
1719
GF_EXPORT
1720
GF_AV1Config *gf_odf_av1_cfg_read(u8 *dsi, u32 dsi_size)
1721
2.59k
{
1722
2.59k
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
1723
2.59k
  GF_AV1Config *cfg = gf_odf_av1_cfg_read_bs(bs);
1724
2.59k
  gf_bs_del(bs);
1725
2.59k
  return cfg;
1726
2.59k
}
1727
1728
1729
1730
GF_EXPORT
1731
GF_AVS3VConfig *gf_odf_avs3v_cfg_new()
1732
819
{
1733
819
  GF_AVS3VConfig *cfg;
1734
819
  GF_SAFEALLOC(cfg, GF_AVS3VConfig);
1735
819
  if (!cfg) return NULL;
1736
819
  return cfg;
1737
819
}
1738
1739
GF_EXPORT
1740
void gf_odf_avs3v_cfg_del(GF_AVS3VConfig *cfg)
1741
819
{
1742
819
  if (!cfg) return;
1743
819
  if (cfg->sequence_header) gf_free(cfg->sequence_header);
1744
819
  gf_free(cfg);
1745
819
}
1746
1747
GF_EXPORT
1748
GF_Err gf_odf_avs3v_cfg_write_bs(GF_AVS3VConfig *cfg, GF_BitStream *bs)
1749
0
{
1750
0
  gf_bs_write_int(bs, cfg->configurationVersion, 8);
1751
0
  gf_bs_write_int(bs, cfg->sequence_header_length, 16);
1752
0
  gf_bs_write_data(bs, cfg->sequence_header, cfg->sequence_header_length);
1753
0
  gf_bs_write_int(bs, 0xFF, 6); //reserved
1754
0
  gf_bs_write_int(bs, cfg->library_dependency_idc, 2);
1755
1756
0
  return GF_OK;
1757
0
}
1758
1759
GF_EXPORT
1760
GF_Err gf_odf_avs3v_cfg_write(GF_AVS3VConfig *cfg, u8 **outData, u32 *outSize)
1761
0
{
1762
0
  GF_Err e;
1763
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1764
0
  *outSize = 0;
1765
0
  *outData = NULL;
1766
0
  e = gf_odf_avs3v_cfg_write_bs(cfg, bs);
1767
0
  if (e==GF_OK)
1768
0
    gf_bs_get_content(bs, outData, outSize);
1769
1770
0
  gf_bs_del(bs);
1771
0
  return e;
1772
0
}
1773
1774
GF_EXPORT
1775
GF_AVS3VConfig *gf_odf_avs3v_cfg_read_bs(GF_BitStream *bs)
1776
819
{
1777
819
  GF_AVS3VConfig *cfg = gf_odf_avs3v_cfg_new();
1778
1779
819
  cfg->configurationVersion = gf_bs_read_int(bs, 8);
1780
819
  cfg->sequence_header_length = gf_bs_read_int(bs, 16);
1781
819
  cfg->sequence_header = gf_malloc(cfg->sequence_header_length);
1782
819
  if (!cfg->sequence_header) {
1783
0
    GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AVS3 Video] Sequence header allocation failed\n"));
1784
0
    gf_odf_avs3v_cfg_del(cfg);
1785
0
    return NULL;
1786
0
  }
1787
819
  gf_bs_read_data(bs, (char *)cfg->sequence_header, (u32)cfg->sequence_header_length);
1788
819
  gf_bs_read_int(bs, 6); //reserved
1789
819
  cfg->library_dependency_idc = gf_bs_read_int(bs, 2); // 6 bits reserved at '1' + 2 bits
1790
1791
819
  return cfg;
1792
819
}
1793
1794
GF_EXPORT
1795
GF_AVS3VConfig *gf_odf_avs3v_cfg_read(u8 *dsi, u32 dsi_size)
1796
0
{
1797
0
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
1798
0
  GF_AVS3VConfig *cfg = gf_odf_avs3v_cfg_read_bs(bs);
1799
0
  gf_bs_del(bs);
1800
0
  return cfg;
1801
0
}
1802
1803
1804
GF_EXPORT
1805
GF_DOVIDecoderConfigurationRecord *gf_odf_dovi_cfg_read_bs(GF_BitStream *bs)
1806
2.87k
{
1807
2.87k
  GF_DOVIDecoderConfigurationRecord *cfg;
1808
2.87k
  GF_SAFEALLOC(cfg, GF_DOVIDecoderConfigurationRecord);
1809
1810
2.87k
  cfg->dv_version_major = gf_bs_read_u8(bs);
1811
2.87k
  cfg->dv_version_minor = gf_bs_read_u8(bs);
1812
2.87k
  cfg->dv_profile = gf_bs_read_int(bs, 7);
1813
2.87k
  cfg->dv_level = gf_bs_read_int(bs, 6);
1814
2.87k
  cfg->rpu_present_flag = gf_bs_read_int(bs, 1);
1815
2.87k
  cfg->el_present_flag = gf_bs_read_int(bs, 1);
1816
2.87k
  cfg->bl_present_flag = gf_bs_read_int(bs, 1);
1817
2.87k
  cfg->dv_bl_signal_compatibility_id = gf_bs_read_int(bs, 4);
1818
2.87k
  if (gf_bs_read_int(bs, 28)) {
1819
0
    GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[DOVI] Configuration reserved bits are not zero\n"));
1820
0
  }
1821
14.3k
  for (u32 i=0; i<4; i++) {
1822
11.4k
    if (gf_bs_read_u32(bs)) {
1823
0
      GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[DOVII] Configuration reserved bits are not zero\n"));
1824
0
    }
1825
11.4k
  }
1826
2.87k
  return cfg;
1827
2.87k
}
1828
1829
GF_EXPORT
1830
void gf_odf_dovi_cfg_del(GF_DOVIDecoderConfigurationRecord *cfg)
1831
2.87k
{
1832
2.87k
  gf_free(cfg);
1833
2.87k
}
1834
1835
GF_EXPORT
1836
GF_Err gf_odf_dovi_cfg_write_bs(GF_DOVIDecoderConfigurationRecord *cfg, GF_BitStream *bs)
1837
2
{
1838
2
  gf_bs_write_u8(bs,  cfg->dv_version_major);
1839
2
  gf_bs_write_u8(bs,  cfg->dv_version_minor);
1840
2
  gf_bs_write_int(bs, cfg->dv_profile, 7);
1841
2
  gf_bs_write_int(bs, cfg->dv_level, 6);
1842
2
  gf_bs_write_int(bs, cfg->rpu_present_flag, 1);
1843
2
  gf_bs_write_int(bs, cfg->el_present_flag, 1);
1844
2
  gf_bs_write_int(bs, cfg->bl_present_flag, 1);
1845
2
  gf_bs_write_int(bs, cfg->dv_bl_signal_compatibility_id, 4);
1846
2
  gf_bs_write_int(bs, 0, 28);
1847
2
  gf_bs_write_u32(bs, 0);
1848
2
  gf_bs_write_u32(bs, 0);
1849
2
  gf_bs_write_u32(bs, 0);
1850
2
  gf_bs_write_u32(bs, 0);
1851
2
  return GF_OK;
1852
2
}
1853
1854
1855
GF_EXPORT
1856
GF_Err gf_odf_ac3_cfg_write_bs(GF_AC3Config *cfg, GF_BitStream *bs)
1857
4.04k
{
1858
4.04k
  if (!cfg || !bs) return GF_BAD_PARAM;
1859
1860
4.04k
  if (cfg->is_ec3) {
1861
3.88k
    u32 i;
1862
3.88k
    gf_bs_write_int(bs, cfg->brcode, 13);
1863
3.88k
    gf_bs_write_int(bs, cfg->nb_streams - 1, 3);
1864
19.5k
    for (i=0; i<cfg->nb_streams; i++) {
1865
15.6k
      gf_bs_write_int(bs, cfg->streams[i].fscod, 2);
1866
15.6k
      gf_bs_write_int(bs, cfg->streams[i].bsid, 5);
1867
15.6k
      gf_bs_write_int(bs, cfg->streams[i].bsmod, 5);
1868
15.6k
      gf_bs_write_int(bs, cfg->streams[i].acmod, 3);
1869
15.6k
      gf_bs_write_int(bs, cfg->streams[i].lfon, 1);
1870
15.6k
      gf_bs_write_int(bs, 0, 3);
1871
15.6k
      gf_bs_write_int(bs, cfg->streams[i].nb_dep_sub, 4);
1872
15.6k
      if (cfg->streams[i].nb_dep_sub) {
1873
628
        gf_bs_write_int(bs, cfg->streams[i].chan_loc, 9);
1874
15.0k
      } else {
1875
15.0k
        gf_bs_write_int(bs, 0, 1);
1876
15.0k
      }
1877
15.6k
    }
1878
3.88k
  } else {
1879
158
    gf_bs_write_int(bs, cfg->streams[0].fscod, 2);
1880
158
    gf_bs_write_int(bs, cfg->streams[0].bsid, 5);
1881
158
    gf_bs_write_int(bs, cfg->streams[0].bsmod, 3);
1882
158
    gf_bs_write_int(bs, cfg->streams[0].acmod, 3);
1883
158
    gf_bs_write_int(bs, cfg->streams[0].lfon, 1);
1884
158
    gf_bs_write_int(bs, cfg->brcode, 5);
1885
158
    gf_bs_write_int(bs, 0, 5);
1886
158
  }
1887
4.04k
  return GF_OK;
1888
4.04k
}
1889
1890
GF_EXPORT
1891
GF_Err gf_odf_ac3_cfg_write(GF_AC3Config *cfg, u8 **data, u32 *size)
1892
4.04k
{
1893
4.04k
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1894
4.04k
  GF_Err e = gf_odf_ac3_cfg_write_bs(cfg, bs);
1895
1896
4.04k
  if (cfg->is_ec3 && (cfg->atmos_ec3_ext || cfg->complexity_index_type)) {
1897
758
    gf_bs_write_int(bs, 0, 7);
1898
758
    gf_bs_write_int(bs, cfg->atmos_ec3_ext, 1);
1899
758
    gf_bs_write_u8(bs, cfg->complexity_index_type);
1900
758
  }
1901
4.04k
  gf_bs_get_content(bs, data, size);
1902
1903
4.04k
  gf_bs_del(bs);
1904
4.04k
  return e;
1905
4.04k
}
1906
1907
GF_EXPORT
1908
GF_Err gf_odf_ac3_cfg_parse_bs(GF_BitStream *bs, Bool is_ec3, GF_AC3Config *cfg)
1909
2.38k
{
1910
2.38k
  if (!cfg || !bs) return GF_BAD_PARAM;
1911
2.38k
  memset(cfg, 0, sizeof(GF_AC3Config));
1912
2.38k
  cfg->is_ec3 = is_ec3;
1913
2.38k
  if (is_ec3) {
1914
1.25k
    u32 j;
1915
1.25k
    cfg->is_ec3 = 1;
1916
1.25k
    cfg->brcode = gf_bs_read_int(bs, 13);
1917
1.25k
    cfg->nb_streams = 1 + gf_bs_read_int(bs, 3);
1918
3.09k
    for (j=0; j<cfg->nb_streams; j++) {
1919
1.83k
      cfg->streams[j].fscod = gf_bs_read_int(bs, 2);
1920
1.83k
      cfg->streams[j].bsid = gf_bs_read_int(bs, 5);
1921
1.83k
      gf_bs_read_int(bs, 1);
1922
1.83k
      cfg->streams[j].asvc = gf_bs_read_int(bs, 1);
1923
1.83k
      cfg->streams[j].bsmod = gf_bs_read_int(bs, 3);
1924
1.83k
      cfg->streams[j].acmod = gf_bs_read_int(bs, 3);
1925
1.83k
      cfg->streams[j].lfon = gf_bs_read_int(bs, 1);
1926
1.83k
      gf_bs_read_int(bs, 3);
1927
1.83k
      cfg->streams[j].nb_dep_sub = gf_bs_read_int(bs, 4);
1928
1.83k
      if (cfg->streams[j].nb_dep_sub) {
1929
745
        cfg->streams[j].chan_loc = gf_bs_read_int(bs, 9);
1930
1.09k
      } else {
1931
1.09k
        gf_bs_read_int(bs, 1);
1932
1.09k
      }
1933
1.83k
    }
1934
1.25k
  } else {
1935
1.12k
    cfg->nb_streams = 1;
1936
1.12k
    cfg->streams[0].fscod = gf_bs_read_int(bs, 2);
1937
1.12k
    cfg->streams[0].bsid = gf_bs_read_int(bs, 5);
1938
1.12k
    cfg->streams[0].bsmod = gf_bs_read_int(bs, 3);
1939
1.12k
    cfg->streams[0].acmod = gf_bs_read_int(bs, 3);
1940
1.12k
    cfg->streams[0].lfon = gf_bs_read_int(bs, 1);
1941
1.12k
    cfg->brcode = gf_bs_read_int(bs, 5);
1942
1.12k
    gf_bs_read_int(bs, 5);
1943
1.12k
  }
1944
2.38k
  return GF_OK;
1945
2.38k
}
1946
1947
GF_EXPORT
1948
GF_Err gf_odf_ac3_cfg_parse(u8 *dsi, u32 dsi_len, Bool is_ec3, GF_AC3Config *cfg)
1949
0
{
1950
0
  GF_BitStream *bs;
1951
0
  GF_Err e;
1952
0
  if (!cfg || !dsi) return GF_BAD_PARAM;
1953
0
  bs = gf_bs_new(dsi, dsi_len, GF_BITSTREAM_READ);
1954
0
  e = gf_odf_ac3_cfg_parse_bs(bs, is_ec3, cfg);
1955
0
  if (is_ec3 && gf_bs_available(bs)>=2) {
1956
0
    gf_bs_read_int(bs, 7);
1957
0
    cfg->atmos_ec3_ext = gf_bs_read_int(bs, 1);
1958
0
    cfg->complexity_index_type = gf_bs_read_u8(bs);
1959
0
  }
1960
0
  gf_bs_del(bs);
1961
0
  return e;
1962
0
}
1963
1964
1.77M
#define GF_AC4_SSS(bs, value, nbits, size, mode) { \
1965
1.77M
  if (mode == GF_AC4_DESCMODE_PARSE) value = gf_bs_read_int(bs, nbits); \
1966
1.77M
  else if (mode == GF_AC4_DESCMODE_WRITE) gf_bs_write_int(bs, value, nbits); \
1967
25.0k
  else if (mode == GF_AC4_DESCMODE_GETSIZE) *size += nbits;}
1968
1969
16.1k
#define GF_AC4_ALLIGN(bs, size, mode) { \
1970
16.1k
  if (mode == GF_AC4_DESCMODE_PARSE) gf_bs_align(bs); \
1971
16.1k
  else if (mode == GF_AC4_DESCMODE_WRITE) gf_bs_align(bs); \
1972
276
  else if (mode == GF_AC4_DESCMODE_GETSIZE && (*size % 8 != 0)) *size = ((*size / 8) + 1) * 8;}
1973
1974
GF_Err gf_odf_ac4_cfg_alternative_info(GF_AC4AlternativeInfo *info, GF_BitStream *bs, u64 *size, u8 desc_mode)
1975
1.82k
{
1976
1.82k
  u32 i;
1977
1978
1.82k
  GF_AC4_SSS(bs, info->name_len, 16, size, desc_mode);
1979
1980
1.82k
  if (info->name_len >= GF_ARRAY_LENGTH(info->presentation_name))
1981
1.24k
    return GF_ISOM_INVALID_MEDIA;
1982
1983
40.3k
  for (i = 0; i < info->name_len; i++) {
1984
39.8k
    GF_AC4_SSS(bs, info->presentation_name[i], 8, size, desc_mode);
1985
39.8k
  }
1986
1987
581
  GF_AC4_SSS(bs, info->n_targets, 5, size, desc_mode);
1988
1989
581
  if (info->n_targets >= MIN(GF_ARRAY_LENGTH(info->target_md_compat), GF_ARRAY_LENGTH(info->target_device_category)))
1990
0
    return GF_ISOM_INVALID_MEDIA;
1991
1992
1.63k
  for (i = 0; i < info->n_targets; i++) {
1993
1.05k
    GF_AC4_SSS(bs, info->target_md_compat[i], 3, size, desc_mode);
1994
1.05k
    GF_AC4_SSS(bs, info->target_device_category[i], 8, size, desc_mode);
1995
1.05k
  }
1996
581
  return GF_OK;
1997
581
}
1998
1999
GF_Err gf_odf_ac4_cfg_substream_dsi(GF_AC4SubStream *s, GF_BitStream *bs, u8 b_channel_coded, u64 *size, u8 desc_mode)
2000
235k
{
2001
235k
  u32 zero_val = 0;
2002
2003
235k
  GF_AC4_SSS(bs, s->dsi_sf_multiplier, 2, size, desc_mode);
2004
235k
  GF_AC4_SSS(bs, s->b_substream_bitrate_indicator, 1, size, desc_mode);
2005
235k
  if (s->b_substream_bitrate_indicator == 1) {
2006
13.8k
    GF_AC4_SSS(bs, s->substream_bitrate_indicator, 5, size, desc_mode);
2007
13.8k
  }
2008
235k
  if (b_channel_coded == 1) {
2009
140k
    GF_AC4_SSS(bs, s->dsi_substream_channel_mask, 24, size, desc_mode);
2010
140k
  } else {
2011
94.7k
    GF_AC4_SSS(bs, s->b_ajoc, 1, size, desc_mode);
2012
94.7k
    if (s->b_ajoc == 1) {
2013
10.6k
      GF_AC4_SSS(bs, s->b_static_dmx, 1, size, desc_mode);
2014
10.6k
      if (s->b_static_dmx == 0) {
2015
6.35k
        GF_AC4_SSS(bs, s->n_dmx_objects_minus1, 4, size, desc_mode);
2016
6.35k
      }
2017
10.6k
      GF_AC4_SSS(bs, s->n_umx_objects_minus1, 6, size, desc_mode);
2018
10.6k
    }
2019
94.7k
    GF_AC4_SSS(bs, s->b_substream_contains_bed_objects, 1, size, desc_mode);
2020
94.7k
    GF_AC4_SSS(bs, s->b_substream_contains_dynamic_objects, 1, size, desc_mode);
2021
94.7k
    GF_AC4_SSS(bs, s->b_substream_contains_ISF_objects, 1, size, desc_mode);
2022
94.7k
    GF_AC4_SSS(bs, zero_val, 1, size, desc_mode); //reserved bit
2023
94.7k
  }
2024
235k
  return GF_OK;
2025
235k
}
2026
2027
GF_Err gf_odf_ac4_cfg_content_type(GF_AC4SubStreamGroupV1 *g, GF_BitStream *bs, u64 *size, u8 desc_mode)
2028
8.94k
{
2029
8.94k
  u32 i;
2030
2031
8.94k
  GF_AC4_SSS(bs, g->b_content_type, 1, size, desc_mode);
2032
8.94k
  if (g->b_content_type == 1){
2033
1.14k
    GF_AC4_SSS(bs, g->content_classifier, 3, size, desc_mode);
2034
1.14k
    GF_AC4_SSS(bs, g->b_language_indicator, 1, size, desc_mode);
2035
1.14k
    if (g->b_language_indicator == 1){
2036
685
      GF_AC4_SSS(bs, g->n_language_tag_bytes, 6, size, desc_mode);
2037
24.0k
      for (i = 0; i < g->n_language_tag_bytes; i++ ){
2038
23.3k
        GF_AC4_SSS(bs, g->language_tag_bytes[i], 8, size, desc_mode);
2039
23.3k
      }
2040
685
    }
2041
1.14k
  }
2042
8.94k
  return GF_OK;
2043
8.94k
}
2044
2045
GF_Err gf_odf_ac4_cfg_substream_group_dsi(GF_AC4SubStreamGroupV1 *g, GF_BitStream *bs, u64 *size, u8 desc_mode)
2046
8.94k
{
2047
8.94k
  u32 i;
2048
8.94k
  GF_AC4SubStream *s;
2049
2050
8.94k
  if (!g)
2051
0
    return GF_BAD_PARAM;
2052
2053
8.94k
  GF_AC4_SSS(bs, g->b_substreams_present, 1, size, desc_mode);
2054
8.94k
  GF_AC4_SSS(bs, g->b_hsf_ext, 1, size, desc_mode);
2055
8.94k
  GF_AC4_SSS(bs, g->b_channel_coded, 1, size, desc_mode);
2056
8.94k
  GF_AC4_SSS(bs, g->n_lf_substreams, 8, size, desc_mode);
2057
2058
8.94k
  if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2059
8.64k
    g->substreams = gf_list_new();
2060
8.64k
  }
2061
244k
  for (i = 0; i < g->n_lf_substreams; i++ ){
2062
235k
    if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2063
233k
      GF_SAFEALLOC(s, GF_AC4SubStream);
2064
233k
    } else { // write or get_size
2065
1.30k
      s = (GF_AC4SubStream*)gf_list_get(g->substreams, i);
2066
1.30k
    }
2067
235k
    gf_odf_ac4_cfg_substream_dsi(s, bs, g->b_channel_coded, size, desc_mode);
2068
235k
    if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2069
233k
      gf_list_add(g->substreams, s);
2070
233k
    }
2071
235k
  }
2072
8.94k
  gf_odf_ac4_cfg_content_type(g, bs, size, desc_mode);
2073
8.94k
  return GF_OK;
2074
8.94k
}
2075
2076
GF_Err gf_odf_ac4_cfg_bitrate_dsi(GF_AC4BitrateDsi *bitr, GF_BitStream *bs, u64 *size, u8 desc_mode)
2077
8.87k
{
2078
8.87k
  GF_AC4_SSS(bs, bitr->bit_rate_mode, 2, size, desc_mode);
2079
8.87k
  GF_AC4_SSS(bs, bitr->bit_rate, 32, size, desc_mode);
2080
8.87k
  GF_AC4_SSS(bs, bitr->bit_rate_precision, 32, size, desc_mode);
2081
8.87k
  return GF_OK;
2082
8.87k
}
2083
2084
GF_Err gf_odf_ac4_cfg_presentation_v1_dsi(GF_AC4PresentationV1 *p, GF_BitStream *bs, u64 *size, u8 desc_mode)
2085
6.70k
{
2086
6.70k
  GF_AC4SubStreamGroupV1 *g;
2087
6.70k
  u32 i, zero_val = 0;
2088
2089
6.70k
  GF_AC4_SSS(bs, p->presentation_config, 5, size, desc_mode);
2090
6.70k
  if (p->presentation_config == 0x06) {
2091
131
    p->b_add_emdf_substreams = 1;
2092
6.57k
  } else {
2093
6.57k
    GF_AC4_SSS(bs, p->mdcompat, 3, size, desc_mode);
2094
6.57k
    GF_AC4_SSS(bs, p->b_presentation_id, 1, size, desc_mode);
2095
6.57k
    if (p->b_presentation_id) {
2096
549
      GF_AC4_SSS(bs, p->presentation_id, 5, size, desc_mode);
2097
549
    }
2098
6.57k
    GF_AC4_SSS(bs, p->dsi_frame_rate_multiply_info, 2, size, desc_mode);
2099
6.57k
    GF_AC4_SSS(bs, p->dsi_frame_rate_fraction_info, 2, size, desc_mode);
2100
6.57k
    GF_AC4_SSS(bs, p->presentation_emdf_version, 5, size, desc_mode);
2101
6.57k
    GF_AC4_SSS(bs, p->presentation_key_id, 10, size, desc_mode);
2102
2103
6.57k
    GF_AC4_SSS(bs, p->b_presentation_channel_coded, 1, size, desc_mode);
2104
6.57k
    if (p->b_presentation_channel_coded) {
2105
2.23k
      GF_AC4_SSS(bs, p->dsi_presentation_ch_mode, 5, size, desc_mode);
2106
2.23k
      if (p->dsi_presentation_ch_mode >= 11 && p->dsi_presentation_ch_mode <= 14) {
2107
227
        GF_AC4_SSS(bs, p->pres_b_4_back_channels_present, 1, size, desc_mode);
2108
227
        GF_AC4_SSS(bs, p->pres_top_channel_pairs, 2, size, desc_mode);
2109
227
      }
2110
2.23k
      GF_AC4_SSS(bs, p->presentation_channel_mask_v1, 24, size, desc_mode);
2111
2.23k
    }
2112
2113
6.57k
    GF_AC4_SSS(bs, p->b_presentation_core_differs, 1, size, desc_mode);
2114
6.57k
    if (p->b_presentation_core_differs) {
2115
2.45k
      GF_AC4_SSS(bs, p->b_presentation_core_channel_coded, 1, size, desc_mode);
2116
2.45k
      if (p->b_presentation_core_channel_coded) {
2117
1.84k
        GF_AC4_SSS(bs, p->dsi_presentation_channel_mode_core, 2, size, desc_mode);
2118
1.84k
      }
2119
2.45k
    }
2120
6.57k
    GF_AC4_SSS(bs, p->b_presentation_filter, 1, size, desc_mode);
2121
6.57k
    if (p->b_presentation_filter) {
2122
2.22k
      GF_AC4_SSS(bs, p->b_enable_presentation, 1, size, desc_mode);
2123
2.22k
      GF_AC4_SSS(bs, p->n_filter_bytes, 8, size, desc_mode);
2124
280k
      for (i = 0; i < p->n_filter_bytes; i++) {
2125
277k
        GF_AC4_SSS(bs, zero_val, 8, size, desc_mode); // filter_data
2126
277k
      }
2127
2.22k
    }
2128
    // calloc memory for substream_groups
2129
6.57k
    if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2130
6.42k
      p->substream_groups = gf_list_new();
2131
6.42k
    }
2132
2133
6.57k
    if (p->presentation_config == 0x1f) {
2134
123
      if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2135
105
        GF_SAFEALLOC(g, GF_AC4SubStreamGroupV1);
2136
105
        gf_list_add(p->substream_groups, g);
2137
105
        p->n_substream_groups = 1;
2138
105
      } else { // write or get_size
2139
18
        g = (GF_AC4SubStreamGroupV1*)gf_list_get(p->substream_groups, 0);
2140
18
      }
2141
123
      if (g)
2142
123
        gf_odf_ac4_cfg_substream_group_dsi(g, bs, size, desc_mode);
2143
123
    }
2144
6.45k
    else {
2145
6.45k
      GF_AC4_SSS(bs, p->b_multi_pid, 1, size, desc_mode);
2146
6.45k
      if (p->presentation_config >= 0 && p->presentation_config <= 2) {
2147
2.96k
        p->n_substream_groups = 2;
2148
2.96k
      }
2149
6.45k
      if (p->presentation_config == 3 || p->presentation_config == 4) {
2150
275
        p->n_substream_groups = 3;
2151
275
      }
2152
2153
6.45k
      if (p->presentation_config == 5) {
2154
        // n_substream_groups_minus2
2155
420
        if (desc_mode == GF_AC4_DESCMODE_PARSE)
2156
420
          p->n_substream_groups = gf_bs_read_int(bs, 3) + 2;
2157
0
        else if (desc_mode == GF_AC4_DESCMODE_WRITE)
2158
0
          gf_bs_write_int(bs, p->n_substream_groups - 2, 3);
2159
0
        else if(desc_mode == GF_AC4_DESCMODE_GETSIZE)
2160
0
          *size += 3;
2161
420
      }
2162
2163
15.2k
      for (i = 0; i < p->n_substream_groups; i++) {
2164
8.82k
        if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2165
8.54k
          GF_SAFEALLOC(g, GF_AC4SubStreamGroupV1);
2166
8.54k
          gf_list_add(p->substream_groups, g);
2167
8.54k
        } else { // write or get_size
2168
283
          g = (GF_AC4SubStreamGroupV1*)gf_list_get(p->substream_groups, i);
2169
283
        }
2170
8.82k
        gf_odf_ac4_cfg_substream_group_dsi(g, bs, size, desc_mode);
2171
8.82k
      }
2172
2173
6.45k
      if (p->presentation_config > 5) {
2174
2.79k
        GF_AC4_SSS(bs, p->n_skip_bytes, 7, size, desc_mode);
2175
14.8k
        for (i = 0; i < p->n_skip_bytes; i++) {
2176
12.0k
          GF_AC4_SSS(bs, zero_val, 8, size, desc_mode); // skip_data
2177
12.0k
        }
2178
2.79k
      }
2179
6.45k
    }
2180
6.57k
    GF_AC4_SSS(bs, p->b_pre_virtualized, 1, size, desc_mode);
2181
6.57k
    GF_AC4_SSS(bs, p->b_add_emdf_substreams, 1, size, desc_mode);
2182
6.57k
  }
2183
6.70k
  if (p->b_add_emdf_substreams) {
2184
1.01k
    GF_AC4_SSS(bs, p->n_add_emdf_substreams, 7, size, desc_mode);
2185
9.40k
    for (i = 0; i < p->n_add_emdf_substreams && i < GF_ARRAY_LENGTH(p->substream_emdf_version) && i < GF_ARRAY_LENGTH(p->substream_key_id); i++) {
2186
8.38k
      GF_AC4_SSS(bs, p->substream_emdf_version[i], 5, size, desc_mode);
2187
8.38k
      GF_AC4_SSS(bs, p->substream_key_id[i], 10, size, desc_mode);
2188
8.38k
    }
2189
1.01k
  }
2190
6.70k
  GF_AC4_SSS(bs, p->b_presentation_bitrate_info, 1, size, desc_mode);
2191
6.70k
  if (p->b_presentation_bitrate_info) {
2192
1.26k
    gf_odf_ac4_cfg_bitrate_dsi(&(p->ac4_bitrate_dsi), bs, size, desc_mode);
2193
1.26k
  }
2194
6.70k
  GF_AC4_SSS(bs, p->b_alternative, 1, size, desc_mode);
2195
6.70k
  if (p->b_alternative) {
2196
1.82k
    GF_AC4_ALLIGN(bs, size, desc_mode);
2197
1.82k
    gf_odf_ac4_cfg_alternative_info(&(p->alternative_info), bs, size, desc_mode);
2198
1.82k
  }
2199
6.70k
  GF_AC4_ALLIGN(bs, size, desc_mode);
2200
   /*
2201
   * TODO: Not implement, need the information from ac4_substream.
2202
   * Currently just set the value to 1 according to Dolby's internal discussion.
2203
   */
2204
6.70k
  p->de_indicator = 1;
2205
6.70k
  GF_AC4_SSS(bs, p->de_indicator, 1, size, desc_mode);
2206
6.70k
  GF_AC4_SSS(bs, p->dolby_atmos_indicator, 1, size, desc_mode);
2207
6.70k
  GF_AC4_SSS(bs, zero_val, 4, size, desc_mode);
2208
2209
6.70k
  if (p->presentation_id > 31) {
2210
1
    p->b_extended_presentation_id = 1;
2211
1
    p->extended_presentation_id = p->presentation_id;
2212
1
  }
2213
6.70k
  GF_AC4_SSS(bs, p->b_extended_presentation_id, 1, size, desc_mode);
2214
6.70k
  if (p->b_extended_presentation_id) {
2215
1.18k
    GF_AC4_SSS(bs, p->extended_presentation_id, 9, size, desc_mode);
2216
1.18k
  }
2217
5.52k
  else {
2218
5.52k
    GF_AC4_SSS(bs, zero_val, 1, size, desc_mode);
2219
5.52k
  }
2220
2221
6.70k
  return GF_OK;
2222
6.70k
}
2223
2224
static void gf_odf_ac4_presentation_deep_copy(GF_AC4PresentationV1 *pres_dst, GF_AC4PresentationV1 *pres_src);
2225
2226
GF_Err gf_odf_ac4_cfg_dsi_v1(GF_AC4StreamInfo *dsi, GF_BitStream *bs, u64 *size, u8 desc_mode)
2227
7.61k
{
2228
7.61k
  u32 i, j, add_pres_bytes, presentation_bytes, skip_bytes, ims_pres_num = 0, legacy_pres_num = 0;
2229
7.61k
  u32 pres_bytes = 0, t_size_bytes = 0;
2230
7.61k
  GF_AC4PresentationV1* p = NULL, *imsp = NULL;
2231
7.61k
  u64 pos, t_size_bits = 0;
2232
7.61k
  u8 *t_data = NULL;
2233
7.61k
  GF_BitStream *t_bs;
2234
2235
7.61k
  if (!dsi)
2236
0
    return GF_BAD_PARAM;
2237
2238
7.61k
  GF_AC4_SSS(bs, dsi->ac4_dsi_version, 3, size, desc_mode);
2239
7.61k
  GF_AC4_SSS(bs, dsi->bitstream_version, 7, size, desc_mode);
2240
7.61k
  GF_AC4_SSS(bs, dsi->fs_index, 1, size, desc_mode);
2241
7.61k
  GF_AC4_SSS(bs, dsi->frame_rate_index, 4, size, desc_mode);
2242
2243
7.61k
  if (desc_mode == GF_AC4_DESCMODE_WRITE) {
2244
    // check whether legacy presentations are added in the presentations
2245
406
    for (i = 0; i < dsi->n_presentations; i++) {
2246
289
      p = gf_list_get(dsi->presentations, i);
2247
289
      if (!p) continue;
2248
155
      if (p->presentation_version == 1) {
2249
48
        legacy_pres_num += 1;
2250
107
      } else if (p->presentation_version == 2) {
2251
66
        ims_pres_num += 1;
2252
66
      }
2253
155
    }
2254
2255
    // In WRITE mode, modify n_presentations for IMS content and add legacy presentations
2256
    // For more information, please read Dolby AC-4 Online Delivery Kit - Signaling immersive stereo content
2257
117
    if (legacy_pres_num == 0 && ims_pres_num > 0) {
2258
46
      GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("[AC4] This is a Dolby AC-4 bitstreams signal immersive stereo content.\n"));
2259
2260
126
      for (i = 0; i < dsi->n_presentations; i++) {
2261
80
        p = gf_list_get(dsi->presentations, i);
2262
80
        if (!p) continue;
2263
61
        if (p->presentation_version == 2) {
2264
46
          GF_SAFEALLOC(imsp, GF_AC4PresentationV1);
2265
46
          gf_odf_ac4_presentation_deep_copy(imsp, p);
2266
2267
46
          imsp->presentation_version = 1;
2268
46
          imsp->b_pre_virtualized = 0;
2269
46
          imsp->dolby_atmos_indicator = 0;
2270
46
          gf_list_add(dsi->presentations, imsp);
2271
46
        }
2272
61
      }
2273
46
      dsi->n_presentations += ims_pres_num;
2274
46
    }
2275
117
  }
2276
2277
7.61k
  GF_AC4_SSS(bs, dsi->n_presentations, 9, size, desc_mode);
2278
7.61k
  if (dsi->bitstream_version > 1) {
2279
7.37k
    GF_AC4_SSS(bs, dsi->b_program_id, 1, size, desc_mode);
2280
7.37k
    if (dsi->b_program_id) {
2281
1.99k
      GF_AC4_SSS(bs, dsi->short_program_id, 16, size, desc_mode);
2282
1.99k
      GF_AC4_SSS(bs, dsi->b_uuid, 1, size, desc_mode);
2283
1.99k
      if (dsi->b_uuid) {
2284
4.96k
        for (i = 0; i < 16; i++)
2285
4.67k
          GF_AC4_SSS(bs, dsi->program_uuid[i], 8, size, desc_mode);
2286
292
      }
2287
1.99k
    }
2288
7.37k
  }
2289
2290
  // ac4_bitrate_dsi
2291
7.61k
  gf_odf_ac4_cfg_bitrate_dsi(&dsi->ac4_bitrate_dsi, bs, size, desc_mode);
2292
7.61k
  GF_AC4_ALLIGN(bs, size, desc_mode);
2293
2294
7.61k
  if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2295
7.49k
    dsi->presentations = gf_list_new();
2296
7.49k
  }
2297
2298
555k
  for (i = 0; i < dsi->n_presentations; i++) {
2299
548k
    if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2300
547k
      GF_SAFEALLOC(p, GF_AC4PresentationV1);
2301
547k
      gf_list_add(dsi->presentations, p);
2302
2303
547k
      p->presentation_version = gf_bs_read_int(bs, 8);
2304
547k
      pres_bytes = gf_bs_read_int(bs, 8);
2305
547k
      if (pres_bytes == 255) {
2306
317
        add_pres_bytes = gf_bs_read_int(bs, 16);
2307
317
        pres_bytes += add_pres_bytes;
2308
317
      }
2309
2310
547k
      pos = gf_bs_get_position(bs);
2311
2312
547k
      if (p->presentation_version == 0) {
2313
540k
        GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support presentation_version 0.\n"));
2314
540k
      } else if (p->presentation_version == 1) {
2315
3.79k
        gf_odf_ac4_cfg_presentation_v1_dsi(p, bs, size, desc_mode);
2316
3.90k
      } else if (p->presentation_version == 2) {
2317
2.75k
        gf_odf_ac4_cfg_presentation_v1_dsi(p, bs, size, desc_mode);
2318
2.75k
      }
2319
2320
547k
      presentation_bytes = (u32) (gf_bs_get_position(bs) - pos);
2321
547k
      skip_bytes = pres_bytes - presentation_bytes;
2322
2323
1.63M
      for (j = 0; j < skip_bytes && gf_bs_available(bs); j++) {
2324
1.08M
        gf_bs_read_int(bs, 8);
2325
1.08M
      }
2326
547k
    }
2327
335
    else if (desc_mode == GF_AC4_DESCMODE_WRITE) {
2328
335
      p = gf_list_get(dsi->presentations, i);
2329
335
      if (!p) continue;
2330
2331
201
      t_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
2332
201
      if (p->presentation_version == 0) {
2333
42
        GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support presentation_version 0.\n"));
2334
159
      } else if (p->presentation_version == 1 || p->presentation_version == 2) {
2335
159
        gf_odf_ac4_cfg_presentation_v1_dsi(p, t_bs, size, desc_mode);
2336
159
      }
2337
2338
      // write into output bitstream
2339
201
      gf_bs_write_int(bs, p->presentation_version, 8);
2340
201
      presentation_bytes = (u32) gf_bs_get_position(t_bs);
2341
201
      if (presentation_bytes < 255) {
2342
201
        gf_bs_write_int(bs, presentation_bytes, 8);
2343
201
      } else {
2344
0
        gf_bs_write_int(bs, 255, 8);
2345
0
        gf_bs_write_int(bs, presentation_bytes - 255, 16);
2346
0
      }
2347
201
      gf_bs_get_content(t_bs, &t_data, &t_size_bytes);
2348
201
      gf_bs_write_data(bs, t_data, t_size_bytes);
2349
2350
201
      gf_bs_del(t_bs);
2351
201
      gf_free(t_data);
2352
201
    }
2353
0
    else if (desc_mode == GF_AC4_DESCMODE_GETSIZE) {
2354
0
      p = gf_list_get(dsi->presentations, i);
2355
2356
0
      t_size_bits = 0; // t_size in bits
2357
0
      if (p->presentation_version == 0) {
2358
0
        GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support presentation_version 0.\n"));
2359
0
        return GF_OK;
2360
0
      } else if (p->presentation_version == 1 || p->presentation_version == 2) {
2361
0
        gf_odf_ac4_cfg_presentation_v1_dsi(p, bs, &t_size_bits, desc_mode);
2362
0
      }
2363
2364
0
      if (t_size_bits < 255 * 8) {
2365
0
        *size += (8 + 8 + t_size_bits);
2366
0
      } else {
2367
0
        *size += (8 + 8 + 16 + t_size_bits);
2368
0
      }
2369
0
    }
2370
548k
  }
2371
2372
7.61k
  return GF_OK;
2373
7.61k
}
2374
2375
GF_EXPORT
2376
GF_Err gf_odf_ac4_cfg_write_bs(GF_AC4Config *cfg, GF_BitStream *bs)
2377
117
{
2378
117
  if (!cfg || !bs) return GF_BAD_PARAM;
2379
117
  GF_AC4StreamInfo* dsi = &cfg->stream;
2380
117
  if (dsi->ac4_dsi_version == 0) {
2381
0
    GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support ac4_dsi_version 0.\n"));
2382
0
    return GF_OK;
2383
0
  }
2384
117
  GF_Err e = gf_odf_ac4_cfg_dsi_v1(dsi, bs, NULL, GF_AC4_DESCMODE_WRITE);
2385
117
  return e;
2386
117
}
2387
2388
GF_EXPORT
2389
GF_Err gf_odf_ac4_cfg_write(GF_AC4Config *cfg, u8 **data, u32 *size)
2390
117
{
2391
117
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
2392
117
  GF_Err e = gf_odf_ac4_cfg_write_bs(cfg, bs);
2393
117
  gf_bs_get_content(bs, data, size);
2394
117
  gf_bs_del(bs);
2395
117
  return e;
2396
117
}
2397
2398
GF_EXPORT
2399
GF_Err gf_odf_ac4_cfg_parse_bs(GF_BitStream *bs, GF_AC4Config *cfg)
2400
8.64k
{
2401
8.64k
  GF_AC4StreamInfo* dsi = &cfg->stream;
2402
8.64k
  u64 pos = gf_bs_get_position(bs);
2403
8.64k
  dsi->ac4_dsi_version = gf_bs_read_int(bs, 3);
2404
8.64k
  if (dsi->ac4_dsi_version == 0) {
2405
1.14k
    GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support ac4_dsi_version 0.\n"));
2406
1.14k
    return GF_OK;
2407
1.14k
  }
2408
7.49k
  gf_bs_seek(bs, pos);
2409
7.49k
  GF_Err e = gf_odf_ac4_cfg_dsi_v1(dsi, bs, NULL, GF_AC4_DESCMODE_PARSE);
2410
7.49k
  if (e) return e;
2411
7.49k
  cfg->sample_rate = dsi->fs_index ? 48000 : 44100;
2412
7.49k
  return e;
2413
7.49k
}
2414
2415
GF_EXPORT
2416
GF_Err gf_odf_ac4_cfg_parse(u8 *dsi, u32 dsi_len, GF_AC4Config *cfg)
2417
0
{
2418
0
  GF_BitStream *bs;
2419
0
  GF_Err e;
2420
0
  if (!cfg || !dsi) return GF_BAD_PARAM;
2421
0
  bs = gf_bs_new(dsi, dsi_len, GF_BITSTREAM_READ);
2422
0
  e = gf_odf_ac4_cfg_parse_bs(bs, cfg);
2423
0
  gf_bs_del(bs);
2424
0
  return e;
2425
0
}
2426
2427
GF_EXPORT
2428
u64 gf_odf_ac4_cfg_size(GF_AC4Config *cfg)
2429
0
{
2430
0
  GF_AC4StreamInfo* dsi = &cfg->stream;
2431
0
  u64 size = 0;
2432
0
  if (dsi->ac4_dsi_version == 0) {
2433
0
    GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support ac4_dsi_version 0.\n"));
2434
0
    return 0;
2435
0
  } else {
2436
0
    gf_odf_ac4_cfg_dsi_v1(dsi, NULL, &size, GF_AC4_DESCMODE_GETSIZE);
2437
0
  }
2438
0
  return size / 8;
2439
0
}
2440
2441
GF_EXPORT
2442
void gf_odf_ac4_cfg_deep_copy(GF_AC4Config *dst, GF_AC4Config *src)
2443
0
{
2444
0
  u32 i;
2445
0
  GF_List *presentations_src = src->stream.presentations;
2446
0
  GF_AC4PresentationV1 *pres_dst, *pres_src;
2447
2448
0
  if (!dst || !src) {
2449
0
    return;
2450
0
  }
2451
2452
0
  memcpy(dst, src, sizeof(GF_AC4Config));
2453
2454
0
  if (!src->stream.presentations) {
2455
0
    return;
2456
0
  }
2457
2458
0
  dst->stream.presentations = gf_list_new();
2459
0
  for (i = 0; i < gf_list_count(presentations_src); i++) {
2460
0
    pres_src = gf_list_get(presentations_src, i);
2461
2462
0
    GF_SAFEALLOC(pres_dst, GF_AC4PresentationV1);
2463
0
    gf_odf_ac4_presentation_deep_copy(pres_dst, pres_src);
2464
0
    gf_list_add(dst->stream.presentations, pres_dst);
2465
0
  }
2466
0
}
2467
2468
static void gf_odf_ac4_presentation_deep_copy(GF_AC4PresentationV1 *pres_dst, GF_AC4PresentationV1 *pres_src)
2469
46
{
2470
46
  u32 j, s;
2471
46
  GF_AC4SubStreamGroupV1 *group_dst, *group_src;
2472
46
  GF_AC4SubStream *subs_dst, *subs_src;
2473
2474
46
  if (!pres_dst || !pres_src) {
2475
0
    return;
2476
0
  }
2477
2478
46
  memcpy(pres_dst, pres_src, sizeof(GF_AC4PresentationV1));
2479
2480
46
  if (!pres_src->substream_groups) {
2481
0
    return;
2482
0
  }
2483
2484
46
  pres_dst->substream_groups = gf_list_new();
2485
130
  for (j = 0; j < gf_list_count(pres_src->substream_groups); j++) {
2486
84
    group_src = gf_list_get(pres_src->substream_groups, j);
2487
2488
84
    GF_SAFEALLOC(group_dst, GF_AC4SubStreamGroupV1);
2489
84
    memcpy(group_dst, group_src, sizeof(GF_AC4SubStreamGroupV1));
2490
84
    gf_list_add(pres_dst->substream_groups, group_dst);
2491
2492
84
    if (!group_src->substreams) {
2493
0
      continue;
2494
0
    }
2495
2496
84
    group_dst->substreams = gf_list_new();
2497
437
    for (s = 0; s < gf_list_count(group_src->substreams); s++) {
2498
353
      subs_src = gf_list_get(group_src->substreams, s);
2499
2500
353
      GF_SAFEALLOC(subs_dst, GF_AC4SubStream);
2501
353
      memcpy(subs_dst, subs_src, sizeof(GF_AC4SubStream));
2502
353
      gf_list_add(group_dst->substreams, subs_dst);
2503
353
    }
2504
84
  }
2505
46
}
2506
2507
GF_EXPORT
2508
void gf_odf_ac4_cfg_clean_list(GF_AC4Config *cfg)
2509
17.6k
{
2510
17.6k
  u32 s;
2511
17.6k
  GF_AC4PresentationV1 *pres;
2512
17.6k
  GF_AC4SubStreamGroupV1 *group;
2513
17.6k
  GF_AC4SubStream *subs;
2514
2515
17.6k
  if (!cfg)
2516
0
    return;
2517
2518
2519
17.6k
  if (cfg->stream.presentations) {
2520
2521
8.79k
    GF_List* groups_to_del = gf_list_new();
2522
2523
681k
    while ( (pres = gf_list_pop_back(cfg->stream.presentations)) ) {
2524
2525
672k
      if (pres->substream_groups) {
2526
2527
304k
        while ( (group = gf_list_pop_back(pres->substream_groups)) ) {
2528
2529
173k
          if (group && gf_list_find(groups_to_del, group) < 0)
2530
18.4k
            gf_list_add(groups_to_del, group);
2531
2532
173k
        }
2533
131k
        gf_list_del(pres->substream_groups);
2534
2535
131k
      }
2536
672k
      gf_free(pres);
2537
672k
    }
2538
2539
27.2k
    while ( (group = gf_list_pop_back(groups_to_del)) ) {
2540
18.4k
      if (group->substreams) {
2541
2542
284k
        for (s = 0; s < gf_list_count(group->substreams); s++) {
2543
265k
          subs = gf_list_get(group->substreams, s);
2544
265k
          if (!subs) {
2545
0
            continue;
2546
0
          }
2547
2548
265k
          gf_free(subs);
2549
265k
        }
2550
18.4k
        gf_list_del(group->substreams);
2551
2552
18.4k
      }
2553
18.4k
      gf_free(group);
2554
2555
18.4k
    }
2556
8.79k
    gf_list_del(groups_to_del);
2557
2558
8.79k
    gf_list_del(cfg->stream.presentations);
2559
8.79k
    cfg->stream.presentations = NULL;
2560
8.79k
  }
2561
17.6k
}
2562
2563
GF_EXPORT
2564
void gf_odf_ac4_cfg_del(GF_AC4Config *cfg)
2565
0
{
2566
0
  if (!cfg) return;
2567
0
  gf_odf_ac4_cfg_clean_list(cfg);
2568
0
  gf_free(cfg);
2569
0
}
2570
2571
GF_EXPORT
2572
GF_Err gf_odf_opus_cfg_parse_bs(GF_BitStream *bs, GF_OpusConfig *cfg)
2573
30
{
2574
30
  memset(cfg, 0, sizeof(GF_OpusConfig));
2575
30
  cfg->version = gf_bs_read_u8(bs);
2576
30
  cfg->OutputChannelCount = gf_bs_read_u8(bs);
2577
30
  cfg->PreSkip = gf_bs_read_u16_le(bs);
2578
30
  cfg->InputSampleRate = gf_bs_read_u32_le(bs);
2579
30
  cfg->OutputGain = gf_bs_read_u16_le(bs);
2580
30
  cfg->ChannelMappingFamily = gf_bs_read_u8(bs);
2581
30
  if (cfg->ChannelMappingFamily) {
2582
0
    cfg->StreamCount = gf_bs_read_u8(bs);
2583
0
    cfg->CoupledCount = gf_bs_read_u8(bs);
2584
0
    gf_bs_read_data(bs, (char *) cfg->ChannelMapping, cfg->OutputChannelCount);
2585
0
  }
2586
30
  return GF_OK;
2587
30
}
2588
2589
GF_EXPORT
2590
GF_Err gf_odf_opus_cfg_parse(u8 *dsi, u32 dsi_len, GF_OpusConfig *cfg)
2591
30
{
2592
30
  GF_BitStream *bs;
2593
30
  GF_Err e;
2594
30
  if (!cfg || !dsi) return GF_BAD_PARAM;
2595
30
  bs = gf_bs_new(dsi, dsi_len, GF_BITSTREAM_READ);
2596
30
  e = gf_odf_opus_cfg_parse_bs(bs, cfg);
2597
30
  gf_bs_del(bs);
2598
30
  return e;
2599
30
}
2600
2601
GF_EXPORT
2602
GF_Err gf_odf_opus_cfg_write_bs(GF_OpusConfig *cfg, GF_BitStream *bs)
2603
31
{
2604
31
  if (!cfg || !bs) return GF_BAD_PARAM;
2605
31
  gf_bs_write_u8(bs, cfg->version);
2606
31
  gf_bs_write_u8(bs, cfg->OutputChannelCount);
2607
31
  gf_bs_write_u16_le(bs, cfg->PreSkip);
2608
31
  gf_bs_write_u32_le(bs, cfg->InputSampleRate);
2609
31
  gf_bs_write_u16_le(bs, cfg->OutputGain);
2610
31
  gf_bs_write_u8(bs, cfg->ChannelMappingFamily);
2611
31
  if (cfg->ChannelMappingFamily) {
2612
0
    gf_bs_write_u8(bs, cfg->StreamCount);
2613
0
    gf_bs_write_u8(bs, cfg->CoupledCount);
2614
0
    gf_bs_write_data(bs, (char *) cfg->ChannelMapping, cfg->OutputChannelCount);
2615
0
  }
2616
31
  return GF_OK;
2617
31
}
2618
2619
GF_EXPORT
2620
GF_Err gf_odf_opus_cfg_write(GF_OpusConfig *cfg, u8 **data, u32 *size)
2621
0
{
2622
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
2623
0
  GF_Err e = gf_odf_opus_cfg_write_bs(cfg, bs);
2624
2625
0
  gf_bs_get_content(bs, data, size);
2626
0
  gf_bs_del(bs);
2627
0
  return e;
2628
0
}
2629
2630
GF_EXPORT
2631
GF_IAConfig *gf_odf_iamf_cfg_new()
2632
25.6k
{
2633
25.6k
  GF_IAConfig *cfg = NULL;
2634
25.6k
  GF_SAFEALLOC(cfg, GF_IAConfig);
2635
25.6k
  if (!cfg) return NULL;
2636
25.6k
  cfg->configurationVersion = 1;
2637
25.6k
  cfg->configOBUs_size = 0;
2638
25.6k
  cfg->configOBUs = gf_list_new();
2639
25.6k
  if (!cfg->configOBUs) {
2640
0
    gf_free(cfg);
2641
0
    return NULL;
2642
0
  }
2643
25.6k
  return cfg;
2644
25.6k
}
2645
2646
GF_EXPORT
2647
25.7k
GF_IAConfig *gf_odf_iamf_cfg_read_bs_size(GF_BitStream *bs, u32 size) {
2648
25.7k
#ifndef GPAC_DISABLE_AV_PARSERS
2649
25.7k
  IAMFState *state = NULL;
2650
25.7k
  GF_IAConfig *cfg = NULL;
2651
25.7k
  u8 leb128_size;
2652
2653
25.7k
  if (!size) size = (u32) gf_bs_available(bs);
2654
25.7k
  if (!size) {
2655
238
    GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[IAMF] Unknown IAConfigurationBox size to read\n"));
2656
238
    return NULL;
2657
238
  }
2658
2659
25.4k
  GF_SAFEALLOC(state, IAMFState);
2660
25.4k
  if (!state) return NULL;
2661
25.4k
  cfg = gf_odf_iamf_cfg_new();
2662
25.4k
  gf_iamf_init_state(state);
2663
2664
25.4k
  cfg->configurationVersion = gf_bs_read_u8(bs);
2665
25.4k
  if (cfg->configurationVersion != 1) {
2666
4.14k
    GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[IAMF] Unknown configurationVersion %d\n", cfg->configurationVersion));
2667
4.14k
    gf_odf_iamf_cfg_del(cfg);
2668
4.14k
    gf_free(state);
2669
4.14k
    return NULL;
2670
4.14k
  }
2671
21.3k
  size--;
2672
2673
21.3k
  cfg->configOBUs_size = (u32)gf_av1_leb128_read(bs, &leb128_size);
2674
21.3k
  size -= leb128_size;
2675
2676
30.1k
  while(size) {
2677
29.6k
    u64 pos, obu_size;
2678
29.6k
    IamfObuType obu_type;
2679
29.6k
    GF_IamfObu *config_obu;
2680
2681
29.6k
    pos = gf_bs_get_position(bs);
2682
29.6k
    obu_size = 0;
2683
29.6k
    if (gf_iamf_parse_obu(bs, &obu_type, &obu_size, state) != GF_OK) {
2684
20.0k
      GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[IAMF] could not parse configOBUs at position "LLU". Leaving parsing.\n", pos));
2685
20.0k
      break;
2686
20.0k
    }
2687
9.61k
    gf_assert(obu_size == gf_bs_get_position(bs) - pos);
2688
9.61k
    GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[IAMF] parsed OBU type=%u size="LLU" at position "LLU".\n", obu_type, obu_size, pos));
2689
2690
9.61k
    GF_SAFEALLOC(config_obu, GF_IamfObu);
2691
9.61k
    if (!config_obu) break;
2692
9.61k
    config_obu->raw_obu_bytes = gf_malloc((size_t)obu_size);
2693
9.61k
    if (!config_obu->raw_obu_bytes) {
2694
0
      gf_free(config_obu);
2695
0
      break;
2696
0
    }
2697
9.61k
    gf_bs_seek(bs, pos);
2698
9.61k
    gf_bs_read_data(bs, (char *)config_obu->raw_obu_bytes, (u32)obu_size);
2699
9.61k
    config_obu->obu_length = obu_size;
2700
9.61k
    config_obu->obu_type = obu_type;
2701
9.61k
    gf_list_add(cfg->configOBUs, config_obu);
2702
2703
9.61k
    if (size < obu_size) {
2704
845
      GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[IAMF] IAMF config misses %d bytes to fit the entire OBU\n", obu_size - size));
2705
845
      break;
2706
845
    }
2707
8.76k
    size -= (u32) obu_size;
2708
8.76k
  }
2709
2710
21.3k
  gf_iamf_reset_state(state, GF_TRUE);
2711
21.3k
  gf_bs_align(bs);
2712
21.3k
  gf_free(state);
2713
21.3k
  return cfg;
2714
#else
2715
  return NULL;
2716
#endif
2717
25.4k
}
2718
2719
GF_EXPORT
2720
16
GF_IAConfig *gf_odf_iamf_cfg_read_bs(GF_BitStream *bs) {
2721
16
  return gf_odf_iamf_cfg_read_bs_size(bs, 0);
2722
16
}
2723
2724
GF_EXPORT
2725
GF_IAConfig *gf_odf_iamf_cfg_read(u8 *dsi, u32 dsi_size)
2726
16
{
2727
16
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
2728
16
  GF_IAConfig *cfg = gf_odf_iamf_cfg_read_bs(bs);
2729
16
  gf_bs_del(bs);
2730
16
  return cfg;
2731
16
}
2732
2733
GF_EXPORT
2734
void gf_odf_iamf_cfg_del(GF_IAConfig *cfg)
2735
25.6k
{
2736
25.6k
  if (!cfg) return;
2737
35.3k
  while (gf_list_count(cfg->configOBUs)) {
2738
9.67k
    GF_IamfObu *configOBU = (GF_IamfObu*)gf_list_get(cfg->configOBUs, 0);
2739
9.67k
    if (configOBU->raw_obu_bytes) gf_free(configOBU->raw_obu_bytes);
2740
9.67k
    gf_list_rem(cfg->configOBUs, 0);
2741
9.67k
    gf_free(configOBU);
2742
9.67k
  }
2743
25.6k
  gf_list_del(cfg->configOBUs);
2744
25.6k
  gf_free(cfg);
2745
25.6k
}
2746
2747
GF_EXPORT
2748
GF_Err gf_odf_iamf_cfg_write_bs(GF_IAConfig *cfg, GF_BitStream *bs)
2749
16
{
2750
16
  u32 i;
2751
16
  if (!cfg || !bs) return GF_BAD_PARAM;
2752
2753
16
  #ifndef GPAC_DISABLE_AV_PARSERS
2754
16
    gf_bs_write_u8(bs, cfg->configurationVersion);
2755
16
    gf_av1_leb128_write(bs, cfg->configOBUs_size);
2756
73
    for (i = 0; i < gf_list_count(cfg->configOBUs); ++i) {
2757
57
        GF_IamfObu *configOBU = gf_list_get(cfg->configOBUs, i);
2758
57
        gf_bs_write_data(bs, configOBU->raw_obu_bytes, (u32)configOBU->obu_length);
2759
57
    }
2760
16
  #endif
2761
2762
16
  return GF_OK;
2763
16
}
2764
2765
GF_EXPORT
2766
16
GF_Err gf_odf_iamf_cfg_write(GF_IAConfig *cfg, u8 **outData, u32 *outSize) {
2767
16
  GF_Err e;
2768
16
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
2769
16
  *outSize = 0;
2770
16
  *outData = NULL;
2771
16
  e = gf_odf_iamf_cfg_write_bs(cfg, bs);
2772
16
  if (e == GF_OK)
2773
16
    gf_bs_get_content(bs, outData, outSize);
2774
2775
16
  gf_bs_del(bs);
2776
16
  return e;
2777
16
}
2778
2779
GF_EXPORT
2780
u32 gf_odf_iamf_cfg_size(GF_IAConfig *cfg)
2781
0
{
2782
0
  if (!cfg) return 0;
2783
2784
0
  #ifndef GPAC_DISABLE_AV_PARSERS
2785
0
    u32 cfg_size = 1; // configurationVersion
2786
0
    cfg_size += gf_av1_leb128_size(cfg->configOBUs_size);
2787
0
    cfg_size += cfg->configOBUs_size;
2788
0
    return cfg_size;
2789
  #else
2790
    return 0;
2791
  #endif
2792
0
}