Coverage Report

Created: 2025-11-24 07:00

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
0
{
34
0
  if (size_desc < 0x00000080) {
35
0
    return 1 + 1;
36
0
  } else if (size_desc < 0x00004000) {
37
0
    return 2 + 1;
38
0
  } else if (size_desc < 0x00200000) {
39
0
    return 3 + 1;
40
0
  } else if (size_desc < 0x10000000) {
41
0
    return 4 + 1;
42
0
  } else {
43
0
    return -1;
44
0
  }
45
46
0
}
47
48
49
GF_EXPORT
50
GF_Err gf_odf_parse_descriptor(GF_BitStream *bs, GF_Descriptor **desc, u32 *desc_size)
51
0
{
52
0
  u32 val, size, sizeHeader;
53
0
  u8 tag;
54
0
  GF_Err err;
55
0
  GF_Descriptor *newDesc;
56
0
  if (!bs) return GF_BAD_PARAM;
57
58
0
  *desc_size = 0;
59
60
  //tag
61
0
  tag = (u8) gf_bs_read_int(bs, 8);
62
0
  sizeHeader = 1;
63
64
  //size
65
0
  size = 0;
66
0
  do {
67
0
    val = gf_bs_read_int(bs, 8);
68
0
    sizeHeader++;
69
0
    if (sizeHeader > 5) {
70
0
      GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Descriptor size on more than 4 bytes\n"));
71
0
      return GF_ODF_INVALID_DESCRIPTOR;
72
0
    }
73
0
    size <<= 7;
74
0
    size |= val & 0x7F;
75
0
  } while ( val & 0x80);
76
0
  *desc_size = size;
77
78
0
  if (gf_bs_available(bs) < size) {
79
0
    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
0
    return GF_ODF_INVALID_DESCRIPTOR;
81
0
  }
82
83
0
  GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[ODF] Reading descriptor (tag %d size %d)\n", tag, size ));
84
85
0
  newDesc = gf_odf_create_descriptor(tag);
86
0
  if (! newDesc) {
87
0
    *desc = NULL;
88
0
    *desc_size = sizeHeader;
89
0
    if ( (tag >= GF_ODF_ISO_RES_BEGIN_TAG) &&
90
0
            (tag <= GF_ODF_ISO_RES_END_TAG) ) {
91
0
      return GF_ODF_FORBIDDEN_DESCRIPTOR;
92
0
    }
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
0
#endif
103
0
  }
104
105
0
  newDesc->tag = tag;
106
0
  err = gf_odf_read_descriptor(bs, newDesc, *desc_size);
107
108
  /*FFmpeg fix*/
109
0
  if ((tag==GF_ODF_SLC_TAG) && (((GF_SLConfig*)newDesc)->predefined==2)) {
110
0
    if (*desc_size==3) {
111
0
      *desc_size = 1;
112
0
      err = GF_OK;
113
0
    }
114
0
  }
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
0
  *desc_size += sizeHeader - gf_odf_size_field_size(*desc_size);
120
0
  *desc = newDesc;
121
0
  if (err) {
122
0
    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
0
    gf_odf_delete_descriptor(newDesc);
124
0
    *desc = NULL;
125
0
  }
126
0
  return err;
127
0
}
128
129
130
131
GF_Err gf_odf_delete_descriptor_list(GF_List *descList)
132
0
{
133
0
  GF_Err e;
134
0
  GF_Descriptor*tmp;
135
0
  u32 i;
136
  //no error if NULL chain...
137
0
  if (! descList) return GF_OK;
138
0
  i=0;
139
0
  while ((tmp = (GF_Descriptor*)gf_list_enum(descList, &i))) {
140
0
    e = gf_odf_delete_descriptor(tmp);
141
0
    if (e) return e;
142
0
  }
143
0
  gf_list_del(descList);
144
0
  return GF_OK;
145
0
}
146
147
GF_Err gf_odf_write_base_descriptor(GF_BitStream *bs, u8 tag, u32 size)
148
0
{
149
0
  u32 length;
150
0
  unsigned char vals[4];
151
152
0
  if (!tag ) return GF_BAD_PARAM;
153
154
0
  length = size;
155
0
  vals[3] = (unsigned char) (length & 0x7f);
156
0
  length >>= 7;
157
0
  vals[2] = (unsigned char) ((length & 0x7f) | 0x80);
158
0
  length >>= 7;
159
0
  vals[1] = (unsigned char) ((length & 0x7f) | 0x80);
160
0
  length >>= 7;
161
0
  vals[0] = (unsigned char) ((length & 0x7f) | 0x80);
162
163
0
  gf_bs_write_int(bs, tag, 8);
164
0
  if (size < 0x00000080) {
165
0
    gf_bs_write_int(bs, vals[3], 8);
166
0
  } else if (size < 0x00004000) {
167
0
    gf_bs_write_int(bs, vals[2], 8);
168
0
    gf_bs_write_int(bs, vals[3], 8);
169
0
  } 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
0
  return GF_OK;
182
0
}
183
184
185
GF_Err gf_odf_size_descriptor_list(GF_List *descList, u32 *outSize)
186
0
{
187
0
  GF_Err e;
188
0
  u32 tmpSize, count, i;
189
0
  if (! descList) return GF_OK;
190
191
0
  count = gf_list_count(descList);
192
0
  for ( i = 0; i < count; i++ ) {
193
0
    GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(descList, i);
194
0
    if (tmp) {
195
0
      e = gf_odf_size_descriptor(tmp, &tmpSize);
196
0
      if (e) return e;
197
0
      if (tmpSize) *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
198
0
    }
199
0
  }
200
0
  return GF_OK;
201
0
}
202
203
GF_Err gf_odf_write_descriptor_list(GF_BitStream *bs, GF_List *descList)
204
0
{
205
0
  GF_Err e;
206
0
  u32 count, i;
207
208
0
  if (! descList) return GF_OK;
209
0
  count = gf_list_count(descList);
210
0
  for ( i = 0; i < count; i++ ) {
211
0
    GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(descList, i);
212
0
    if (tmp) {
213
0
      e = gf_odf_write_descriptor(bs, tmp);
214
0
      if (e) return e;
215
0
    }
216
0
  }
217
0
  return GF_OK;
218
0
}
219
220
GF_Err gf_odf_write_descriptor_list_filter(GF_BitStream *bs, GF_List *descList, u8 only_tag)
221
0
{
222
0
  GF_Err e;
223
0
  u32 count, i;
224
225
0
  if (! descList) return GF_OK;
226
0
  count = gf_list_count(descList);
227
0
  for ( i = 0; i < count; i++ ) {
228
0
    GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(descList, i);
229
0
    if (tmp && (tmp->tag==only_tag) ) {
230
0
      e = gf_odf_write_descriptor(bs, tmp);
231
0
      if (e) return e;
232
0
    }
233
0
  }
234
0
  return GF_OK;
235
0
}
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
0
{
460
0
  GF_AVCConfig *cfg;
461
0
  GF_SAFEALLOC(cfg, GF_AVCConfig);
462
0
  if (!cfg) return NULL;
463
0
  cfg->sequenceParameterSets = gf_list_new();
464
0
  cfg->pictureParameterSets = gf_list_new();
465
0
  cfg->AVCLevelIndication = 1;
466
0
  cfg->chroma_format = 1;
467
0
  cfg->chroma_bit_depth = 8;
468
0
  cfg->luma_bit_depth = 8;
469
0
  return cfg;
470
0
}
471
472
GF_EXPORT
473
void gf_odf_avc_cfg_del(GF_AVCConfig *cfg)
474
0
{
475
0
  if (!cfg) return;
476
0
  while (gf_list_count(cfg->sequenceParameterSets)) {
477
0
    GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->sequenceParameterSets, 0);
478
0
    gf_list_rem(cfg->sequenceParameterSets, 0);
479
0
    if (sl->data) gf_free(sl->data);
480
0
    gf_free(sl);
481
0
  }
482
0
  gf_list_del(cfg->sequenceParameterSets);
483
0
  cfg->sequenceParameterSets = NULL;
484
485
0
  while (gf_list_count(cfg->pictureParameterSets)) {
486
0
    GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->pictureParameterSets, 0);
487
0
    gf_list_rem(cfg->pictureParameterSets, 0);
488
0
    if (sl->data) gf_free(sl->data);
489
0
    gf_free(sl);
490
0
  }
491
0
  gf_list_del(cfg->pictureParameterSets);
492
0
  cfg->pictureParameterSets = NULL;
493
494
0
  if (cfg->sequenceParameterSetExtensions) {
495
0
    while (gf_list_count(cfg->sequenceParameterSetExtensions)) {
496
0
      GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->sequenceParameterSetExtensions, 0);
497
0
      gf_list_rem(cfg->sequenceParameterSetExtensions, 0);
498
0
      if (sl->data) gf_free(sl->data);
499
0
      gf_free(sl);
500
0
    }
501
0
    gf_list_del(cfg->sequenceParameterSetExtensions);
502
0
    cfg->sequenceParameterSetExtensions = NULL;
503
0
  }
504
0
  gf_free(cfg);
505
0
}
506
507
GF_EXPORT
508
GF_Err gf_odf_avc_cfg_write_bs(GF_AVCConfig *cfg, GF_BitStream *bs)
509
0
{
510
0
  u32 i, count;
511
512
0
  if (!cfg) return GF_BAD_PARAM;
513
514
0
  count = gf_list_count(cfg->sequenceParameterSets);
515
516
0
  if (!cfg->write_annex_b) {
517
0
    gf_bs_write_int(bs, cfg->configurationVersion, 8);
518
0
    gf_bs_write_int(bs, cfg->AVCProfileIndication , 8);
519
0
    gf_bs_write_int(bs, cfg->profile_compatibility, 8);
520
0
    gf_bs_write_int(bs, cfg->AVCLevelIndication, 8);
521
0
    gf_bs_write_int(bs, 0x3F, 6);
522
0
    gf_bs_write_int(bs, cfg->nal_unit_size - 1, 2);
523
0
    gf_bs_write_int(bs, 0x7, 3);
524
0
    gf_bs_write_int(bs, count, 5);
525
0
  }
526
0
  for (i=0; i<count; i++) {
527
0
    GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->sequenceParameterSets, i);
528
0
    if (!cfg->write_annex_b) {
529
0
      gf_bs_write_u16(bs, sl->size);
530
0
    } else {
531
0
      gf_bs_write_u32(bs, 1);
532
0
    }
533
0
    gf_bs_write_data(bs, sl->data, sl->size);
534
0
  }
535
0
  count = gf_list_count(cfg->pictureParameterSets);
536
0
  if (!cfg->write_annex_b) {
537
0
    gf_bs_write_int(bs, count, 8);
538
0
  }
539
0
  for (i=0; i<count; i++) {
540
0
    GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->pictureParameterSets, i);
541
0
    if (!cfg->write_annex_b) {
542
0
      gf_bs_write_u16(bs, sl->size);
543
0
    } else {
544
0
      gf_bs_write_u32(bs, 1);
545
0
    }
546
0
    gf_bs_write_data(bs, sl->data, sl->size);
547
0
  }
548
0
  if (gf_avcc_use_extensions(cfg->AVCProfileIndication)) {
549
0
    if (!cfg->write_annex_b) {
550
0
      gf_bs_write_int(bs, 0xFF, 6);
551
0
      gf_bs_write_int(bs, cfg->chroma_format, 2);
552
0
      gf_bs_write_int(bs, 0xFF, 5);
553
0
      gf_bs_write_int(bs, cfg->luma_bit_depth - 8, 3);
554
0
      gf_bs_write_int(bs, 0xFF, 5);
555
0
      gf_bs_write_int(bs, cfg->chroma_bit_depth - 8, 3);
556
0
    }
557
0
    count = cfg->sequenceParameterSetExtensions ? gf_list_count(cfg->sequenceParameterSetExtensions) : 0;
558
0
    if (!cfg->write_annex_b) {
559
0
      gf_bs_write_u8(bs, count);
560
0
    }
561
0
    for (i=0; i<count; i++) {
562
0
      GF_NALUFFParam *sl = (GF_NALUFFParam *) gf_list_get(cfg->sequenceParameterSetExtensions, i);
563
0
      if (!cfg->write_annex_b) {
564
0
        gf_bs_write_u16(bs, sl->size);
565
0
      } else {
566
0
        gf_bs_write_u32(bs, 1);
567
0
      }
568
0
      gf_bs_write_data(bs, sl->data, sl->size);
569
0
    }
570
0
  }
571
0
  return GF_OK;
572
0
}
573
574
GF_EXPORT
575
GF_Err gf_odf_avc_cfg_write(GF_AVCConfig *cfg, u8 **outData, u32 *outSize)
576
0
{
577
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
578
0
  gf_odf_avc_cfg_write_bs(cfg, bs);
579
0
  *outSize = 0;
580
0
  *outData = NULL;
581
0
  gf_bs_get_content(bs, outData, outSize);
582
0
  gf_bs_del(bs);
583
0
  return GF_OK;
584
0
}
585
586
GF_EXPORT
587
GF_AVCConfig *gf_odf_avc_cfg_read(u8 *dsi, u32 dsi_size)
588
0
{
589
0
  u32 i, count;
590
0
  GF_AVCConfig *avcc = gf_odf_avc_cfg_new();
591
0
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
592
0
  avcc->configurationVersion = gf_bs_read_int(bs, 8);
593
0
  avcc->AVCProfileIndication  = gf_bs_read_int(bs, 8);
594
0
  avcc->profile_compatibility = gf_bs_read_int(bs, 8);
595
0
  avcc->AVCLevelIndication  = gf_bs_read_int(bs, 8);
596
0
  gf_bs_read_int(bs, 6);
597
0
  avcc->nal_unit_size = 1 + gf_bs_read_int(bs, 2);
598
0
  gf_bs_read_int(bs, 3);
599
0
  count = gf_bs_read_int(bs, 5);
600
0
  for (i=0; i<count; i++) {
601
0
    GF_NALUFFParam *sl;
602
0
    u32 size = gf_bs_read_int(bs, 16);
603
0
    if ((size>gf_bs_available(bs)) || (size<2)) {
604
0
      GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AVC] Wrong param set size %d\n", size));
605
0
      gf_bs_del(bs);
606
0
      gf_odf_avc_cfg_del(avcc);
607
0
      return NULL;
608
0
    }
609
0
    GF_SAFEALLOC(sl, GF_NALUFFParam );
610
0
    if (!sl) {
611
0
      gf_bs_del(bs);
612
0
      gf_odf_avc_cfg_del(avcc);
613
0
      return NULL;
614
0
    }
615
0
    sl->size = size;
616
0
    sl->data = (char*)gf_malloc(sizeof(char)*sl->size);
617
0
    if (!sl->data) {
618
0
      gf_bs_del(bs);
619
0
      gf_odf_avc_cfg_del(avcc);
620
0
      return NULL;
621
0
    }
622
0
    gf_bs_read_data(bs, sl->data, sl->size);
623
0
    gf_list_add(avcc->sequenceParameterSets, sl);
624
0
  }
625
0
  count = gf_bs_read_int(bs, 8);
626
0
  for (i=0; i<count; i++) {
627
0
    GF_NALUFFParam *sl;
628
0
    u32 size = gf_bs_read_int(bs, 16);
629
0
    if ((size>gf_bs_available(bs)) || (size<2)) {
630
0
      GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AVC] Wrong param set size %d\n", size));
631
0
      gf_bs_del(bs);
632
0
      gf_odf_avc_cfg_del(avcc);
633
0
      return NULL;
634
0
    }
635
0
    GF_SAFEALLOC(sl, GF_NALUFFParam );
636
0
    if (!sl) {
637
0
      gf_bs_del(bs);
638
0
      gf_odf_avc_cfg_del(avcc);
639
0
      return NULL;
640
0
    }
641
0
    sl->size = size;
642
0
    sl->data = (char*)gf_malloc(sizeof(char)*sl->size);
643
0
    if (!sl->data) {
644
0
      gf_bs_del(bs);
645
0
      gf_odf_avc_cfg_del(avcc);
646
0
      return NULL;
647
0
    }
648
0
    gf_bs_read_data(bs, sl->data, sl->size);
649
0
    gf_list_add(avcc->pictureParameterSets, sl);
650
0
  }
651
0
  if (gf_avcc_use_extensions(avcc->AVCProfileIndication)) {
652
0
    gf_bs_read_int(bs, 6);
653
0
    avcc->chroma_format = gf_bs_read_int(bs, 2);
654
0
    gf_bs_read_int(bs, 5);
655
0
    avcc->luma_bit_depth = 8 + gf_bs_read_int(bs, 3);
656
0
    gf_bs_read_int(bs, 5);
657
0
    avcc->chroma_bit_depth = 8 + gf_bs_read_int(bs, 3);
658
659
0
    count = gf_bs_read_int(bs, 8);
660
0
    if (count) {
661
0
      avcc->sequenceParameterSetExtensions = gf_list_new();
662
0
      for (i=0; i<count; i++) {
663
0
        GF_NALUFFParam *sl;
664
0
        u32 size = gf_bs_read_int(bs, 16);
665
0
        if ((size>gf_bs_available(bs)) || (size<2)) {
666
0
          GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AVC] Wrong param set size %d\n", size));
667
0
          gf_bs_del(bs);
668
0
          gf_odf_avc_cfg_del(avcc);
669
0
          return NULL;
670
0
        }
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
0
    }
688
0
  }
689
690
691
0
  gf_bs_del(bs);
692
0
  return avcc;
693
0
}
694
695
696
GF_Descriptor *gf_odf_new_tx3g()
697
0
{
698
0
  GF_TextSampleDescriptor *newDesc = (GF_TextSampleDescriptor*) gf_malloc(sizeof(GF_TextSampleDescriptor));
699
0
  if (!newDesc) return NULL;
700
0
  memset(newDesc, 0, sizeof(GF_TextSampleDescriptor));
701
0
  newDesc->tag = GF_ODF_TX3G_TAG;
702
0
  return (GF_Descriptor *) newDesc;
703
0
}
704
GF_Err gf_odf_del_tx3g(GF_TextSampleDescriptor *sd)
705
0
{
706
0
  u32 i;
707
0
  for (i=0; i<sd->font_count; i++)
708
0
    if (sd->fonts[i].fontName) gf_free(sd->fonts[i].fontName);
709
0
  gf_free(sd->fonts);
710
0
  gf_free(sd);
711
0
  return GF_OK;
712
0
}
713
714
GF_EXPORT
715
GF_TextSampleDescriptor *gf_odf_tx3g_read(u8 *dsi, u32 dsi_size)
716
0
{
717
0
#ifndef GPAC_DISABLE_ISOM
718
0
  u32 i;
719
0
  u32 gpp_read_rgba(GF_BitStream *bs);
720
0
  void gpp_read_style(GF_BitStream *bs, GF_StyleRecord *rec);
721
0
  void gpp_read_box(GF_BitStream *bs, GF_BoxRecord *rec);
722
723
0
  GF_TextSampleDescriptor *txtc = (GF_TextSampleDescriptor *) gf_odf_new_tx3g();
724
0
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
725
726
0
  txtc->displayFlags = gf_bs_read_int(bs, 32);
727
0
  txtc->horiz_justif = gf_bs_read_int(bs, 8);
728
0
  txtc->vert_justif  = gf_bs_read_int(bs, 8);
729
0
  txtc->back_color = gpp_read_rgba(bs);
730
0
  gpp_read_box(bs, &txtc->default_pos);
731
0
  gpp_read_style(bs, &txtc->default_style);
732
0
  txtc->font_count = gf_bs_read_u16(bs);
733
0
  txtc->fonts = gf_malloc(sizeof(GF_FontRecord)*txtc->font_count);
734
0
  for (i=0; i<txtc->font_count; i++) {
735
0
    u8 len;
736
0
    txtc->fonts[i].fontID = gf_bs_read_u16(bs);
737
0
    len = gf_bs_read_u8(bs);
738
0
    txtc->fonts[i].fontName = gf_malloc(sizeof(char)*(len+1));
739
0
    gf_bs_read_data(bs, txtc->fonts[i].fontName, len);
740
0
    txtc->fonts[i].fontName[len] = 0;
741
0
  }
742
0
  gf_bs_del(bs);
743
0
  return txtc;
744
#else
745
  return NULL;
746
#endif
747
0
}
748
749
GF_Err gf_odf_tx3g_write(GF_TextSampleDescriptor *a, u8 **outData, u32 *outSize)
750
0
{
751
0
#ifndef GPAC_DISABLE_ISOM
752
0
  u32 j;
753
0
  void gpp_write_rgba(GF_BitStream *bs, u32 col);
754
0
  void gpp_write_box(GF_BitStream *bs, GF_BoxRecord *rec);
755
0
  void gpp_write_style(GF_BitStream *bs, GF_StyleRecord *rec);
756
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
757
758
0
  gf_bs_write_u32(bs, a->displayFlags);
759
0
  gf_bs_write_u8(bs, a->horiz_justif);
760
0
  gf_bs_write_u8(bs, a->vert_justif);
761
0
  gpp_write_rgba(bs, a->back_color);
762
0
  gpp_write_box(bs, &a->default_pos);
763
0
  gpp_write_style(bs, &a->default_style);
764
765
0
  gf_bs_write_u16(bs, a->font_count);
766
0
  for (j=0; j<a->font_count; j++) {
767
0
    gf_bs_write_u16(bs, a->fonts[j].fontID);
768
0
    if (a->fonts[j].fontName) {
769
0
      u32 len = (u32) strlen(a->fonts[j].fontName);
770
0
      gf_bs_write_u8(bs, len);
771
0
      gf_bs_write_data(bs, a->fonts[j].fontName, len);
772
0
    } else {
773
0
      gf_bs_write_u8(bs, 0);
774
0
    }
775
0
  }
776
0
  gf_bs_get_content(bs, outData, outSize);
777
0
  gf_bs_del(bs);
778
0
  return GF_OK;
779
#else
780
  return GF_NOT_SUPPORTED;
781
#endif
782
0
}
783
784
/*TextConfig*/
785
GF_Descriptor *gf_odf_new_text_cfg()
786
0
{
787
0
  GF_TextConfig *newDesc = (GF_TextConfig*) gf_malloc(sizeof(GF_TextConfig));
788
0
  if (!newDesc) return NULL;
789
0
  memset(newDesc, 0, sizeof(GF_TextConfig));
790
0
  newDesc->tag = GF_ODF_TEXT_CFG_TAG;
791
0
  newDesc->sample_descriptions = gf_list_new();
792
0
  newDesc->Base3GPPFormat = 0x10;
793
0
  newDesc->MPEGExtendedFormat = 0x10;
794
0
  newDesc->profileLevel = 0x10;
795
0
  newDesc->timescale = 1000;
796
0
  return (GF_Descriptor *) newDesc;
797
0
}
798
799
void ResetTextConfig(GF_TextConfig *desc)
800
0
{
801
0
  GF_List *bck;
802
0
  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
0
  bck = desc->sample_descriptions;
808
0
  memset(desc, 0, sizeof(GF_TextConfig));
809
0
  desc->tag = GF_ODF_TEXT_CFG_TAG;
810
0
  desc->sample_descriptions = bck;
811
0
}
812
813
GF_Err gf_odf_del_text_cfg(GF_TextConfig *desc)
814
0
{
815
0
  ResetTextConfig(desc);
816
0
  gf_list_del(desc->sample_descriptions);
817
0
  gf_free(desc);
818
0
  return GF_OK;
819
0
}
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
0
{
925
0
  GF_HEVCConfig *cfg;
926
0
  GF_SAFEALLOC(cfg, GF_HEVCConfig);
927
0
  if (!cfg) return NULL;
928
0
  cfg->param_array = gf_list_new();
929
0
  cfg->nal_unit_size = 4;
930
0
  return cfg;
931
0
}
932
933
GF_EXPORT
934
void gf_odf_hevc_cfg_del(GF_HEVCConfig *cfg)
935
0
{
936
0
  if (!cfg) return;
937
0
  while (gf_list_count(cfg->param_array)) {
938
0
    GF_NALUFFParamArray *pa = (GF_NALUFFParamArray*)gf_list_get(cfg->param_array, 0);
939
0
    gf_list_rem(cfg->param_array, 0);
940
941
0
    while (gf_list_count(pa->nalus)) {
942
0
      GF_NALUFFParam *n = (GF_NALUFFParam*)gf_list_get(pa->nalus, 0);
943
0
      gf_list_rem(pa->nalus, 0);
944
0
      if (n->data) gf_free(n->data);
945
0
      gf_free(n);
946
0
    }
947
0
    gf_list_del(pa->nalus);
948
0
    gf_free(pa);
949
0
  }
950
0
  gf_list_del(cfg->param_array);
951
0
  gf_free(cfg);
952
0
}
953
954
GF_EXPORT
955
GF_Err gf_odf_hevc_cfg_write_bs(GF_HEVCConfig *cfg, GF_BitStream *bs)
956
0
{
957
0
  u32 i, count;
958
959
0
  count = gf_list_count(cfg->param_array);
960
961
0
  if (!cfg->write_annex_b) {
962
0
    gf_bs_write_int(bs, cfg->configurationVersion, 8);
963
964
0
    if (!cfg->is_lhvc) {
965
0
      gf_bs_write_int(bs, cfg->profile_space, 2);
966
0
      gf_bs_write_int(bs, cfg->tier_flag, 1);
967
0
      gf_bs_write_int(bs, cfg->profile_idc, 5);
968
0
      gf_bs_write_int(bs, cfg->general_profile_compatibility_flags, 32);
969
0
      gf_bs_write_int(bs, cfg->progressive_source_flag, 1);
970
0
      gf_bs_write_int(bs, cfg->interlaced_source_flag, 1);
971
0
      gf_bs_write_int(bs, cfg->non_packed_constraint_flag, 1);
972
0
      gf_bs_write_int(bs, cfg->frame_only_constraint_flag, 1);
973
      /*only lowest 44 bits used*/
974
0
      gf_bs_write_long_int(bs, cfg->constraint_indicator_flags, 44);
975
0
      gf_bs_write_int(bs, cfg->level_idc, 8);
976
0
    }
977
978
0
    gf_bs_write_int(bs, 0xFF, 4);
979
0
    gf_bs_write_int(bs, cfg->min_spatial_segmentation_idc, 12);
980
981
0
    gf_bs_write_int(bs, 0xFF, 6);
982
0
    gf_bs_write_int(bs, cfg->parallelismType, 2);
983
984
0
    if (!cfg->is_lhvc) {
985
0
      gf_bs_write_int(bs, 0xFF, 6);
986
0
      gf_bs_write_int(bs, cfg->chromaFormat, 2);
987
0
      gf_bs_write_int(bs, 0xFF, 5);
988
0
      gf_bs_write_int(bs, cfg->luma_bit_depth-8, 3);
989
0
      gf_bs_write_int(bs, 0xFF, 5);
990
0
      gf_bs_write_int(bs, cfg->chroma_bit_depth-8, 3);
991
0
      gf_bs_write_int(bs, cfg->avgFrameRate, 16);
992
993
0
      gf_bs_write_int(bs, cfg->constantFrameRate, 2);
994
0
    } else {
995
0
      gf_bs_write_int(bs, 0xFF, 2);
996
0
    }
997
998
0
    gf_bs_write_int(bs, cfg->numTemporalLayers, 3);
999
0
    gf_bs_write_int(bs, cfg->temporalIdNested, 1);
1000
0
    gf_bs_write_int(bs, cfg->nal_unit_size - 1, 2);
1001
1002
0
    gf_bs_write_int(bs, count, 8);
1003
0
  }
1004
1005
0
  for (i=0; i<count; i++) {
1006
0
    u32 nalucount, j;
1007
0
    GF_NALUFFParamArray *ar = (GF_NALUFFParamArray*)gf_list_get(cfg->param_array, i);
1008
1009
0
    nalucount = gf_list_count(ar->nalus);
1010
0
    if (!cfg->write_annex_b) {
1011
0
      gf_bs_write_int(bs, ar->array_completeness, 1);
1012
0
      gf_bs_write_int(bs, 0, 1);
1013
0
      gf_bs_write_int(bs, ar->type, 6);
1014
0
      gf_bs_write_int(bs, nalucount, 16);
1015
0
    }
1016
1017
0
    for (j=0; j<nalucount; j++) {
1018
0
      GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(ar->nalus, j);
1019
0
      if (!cfg->write_annex_b) {
1020
0
        gf_bs_write_int(bs, sl->size, 16);
1021
0
      } else {
1022
0
        gf_bs_write_u32(bs, 1);
1023
0
      }
1024
0
      gf_bs_write_data(bs, sl->data, sl->size);
1025
0
    }
1026
0
  }
1027
0
  return GF_OK;
1028
0
}
1029
1030
GF_EXPORT
1031
GF_Err gf_odf_hevc_cfg_write(GF_HEVCConfig *cfg, u8 **outData, u32 *outSize)
1032
0
{
1033
0
  GF_Err e;
1034
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1035
0
  *outSize = 0;
1036
0
  *outData = NULL;
1037
0
  e = gf_odf_hevc_cfg_write_bs(cfg, bs);
1038
0
  if (e==GF_OK)
1039
0
    gf_bs_get_content(bs, outData, outSize);
1040
1041
0
  gf_bs_del(bs);
1042
0
  return e;
1043
0
}
1044
1045
GF_EXPORT
1046
GF_HEVCConfig *gf_odf_hevc_cfg_read_bs(GF_BitStream *bs, Bool is_lhvc)
1047
0
{
1048
0
  u32 i, count;
1049
0
  GF_HEVCConfig *cfg = gf_odf_hevc_cfg_new();
1050
1051
0
  cfg->is_lhvc = is_lhvc;
1052
1053
0
  cfg->configurationVersion = gf_bs_read_int(bs, 8);
1054
1055
0
  if (!is_lhvc) {
1056
0
    cfg->profile_space = gf_bs_read_int(bs, 2);
1057
0
    cfg->tier_flag = gf_bs_read_int(bs, 1);
1058
0
    cfg->profile_idc = gf_bs_read_int(bs, 5);
1059
0
    cfg->general_profile_compatibility_flags = gf_bs_read_int(bs, 32);
1060
1061
0
    cfg->progressive_source_flag = gf_bs_read_int(bs, 1);
1062
0
    cfg->interlaced_source_flag = gf_bs_read_int(bs, 1);
1063
0
    cfg->non_packed_constraint_flag = gf_bs_read_int(bs, 1);
1064
0
    cfg->frame_only_constraint_flag = gf_bs_read_int(bs, 1);
1065
    /*only lowest 44 bits used*/
1066
0
    cfg->constraint_indicator_flags = gf_bs_read_long_int(bs, 44);
1067
0
    cfg->level_idc = gf_bs_read_int(bs, 8);
1068
0
  }
1069
1070
0
  gf_bs_read_int(bs, 4); //reserved
1071
0
  cfg->min_spatial_segmentation_idc = gf_bs_read_int(bs, 12);
1072
1073
0
  gf_bs_read_int(bs, 6);//reserved
1074
0
  cfg->parallelismType = gf_bs_read_int(bs, 2);
1075
1076
0
  if (!is_lhvc) {
1077
0
    gf_bs_read_int(bs, 6);
1078
0
    cfg->chromaFormat = gf_bs_read_int(bs, 2);
1079
0
    gf_bs_read_int(bs, 5);
1080
0
    cfg->luma_bit_depth = gf_bs_read_int(bs, 3) + 8;
1081
0
    gf_bs_read_int(bs, 5);
1082
0
    cfg->chroma_bit_depth = gf_bs_read_int(bs, 3) + 8;
1083
0
    cfg->avgFrameRate = gf_bs_read_int(bs, 16);
1084
1085
0
    cfg->constantFrameRate = gf_bs_read_int(bs, 2);
1086
0
  } else {
1087
0
    gf_bs_read_int(bs, 2); //reserved
1088
0
  }
1089
1090
0
  cfg->numTemporalLayers = gf_bs_read_int(bs, 3);
1091
0
  cfg->temporalIdNested = gf_bs_read_int(bs, 1);
1092
1093
0
  cfg->nal_unit_size = 1 + gf_bs_read_int(bs, 2);
1094
1095
0
  count = gf_bs_read_int(bs, 8);
1096
0
  for (i=0; i<count; i++) {
1097
0
    u32 nalucount, j;
1098
0
    GF_NALUFFParamArray *ar;
1099
0
    GF_SAFEALLOC(ar, GF_NALUFFParamArray);
1100
0
    if (!ar) {
1101
0
      gf_odf_hevc_cfg_del(cfg);
1102
0
      return NULL;
1103
0
    }
1104
0
    ar->nalus = gf_list_new();
1105
0
    gf_list_add(cfg->param_array, ar);
1106
1107
0
    ar->array_completeness = gf_bs_read_int(bs, 1);
1108
0
    gf_bs_read_int(bs, 1);
1109
0
    ar->type = gf_bs_read_int(bs, 6);
1110
0
    nalucount = gf_bs_read_int(bs, 16);
1111
0
    for (j=0; j<nalucount; j++) {
1112
0
      GF_NALUFFParam *sl;
1113
0
      u32 size = gf_bs_read_int(bs, 16);
1114
0
      if ((size>gf_bs_available(bs)) || (size<2)) {
1115
0
        GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] Wrong param set size %d\n", size));
1116
0
        gf_odf_hevc_cfg_del(cfg);
1117
0
        return NULL;
1118
0
      }
1119
0
      GF_SAFEALLOC(sl, GF_NALUFFParam );
1120
0
      if (!sl) {
1121
0
        gf_odf_hevc_cfg_del(cfg);
1122
0
        return NULL;
1123
0
      }
1124
1125
0
      sl->size = size;
1126
0
      sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
1127
0
      gf_bs_read_data(bs, sl->data, sl->size);
1128
0
      gf_list_add(ar->nalus, sl);
1129
0
    }
1130
0
  }
1131
0
  return cfg;
1132
0
}
1133
1134
GF_EXPORT
1135
GF_HEVCConfig *gf_odf_hevc_cfg_read(u8 *dsi, u32 dsi_size, Bool is_lhvc)
1136
0
{
1137
0
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
1138
0
  GF_HEVCConfig *cfg = gf_odf_hevc_cfg_read_bs(bs, is_lhvc);
1139
0
  gf_bs_del(bs);
1140
0
  return cfg;
1141
0
}
1142
1143
GF_EXPORT
1144
GF_VVCConfig *gf_odf_vvc_cfg_new()
1145
0
{
1146
0
  GF_VVCConfig *cfg;
1147
0
  GF_SAFEALLOC(cfg, GF_VVCConfig);
1148
0
  if (!cfg) return NULL;
1149
0
  cfg->param_array = gf_list_new();
1150
0
  cfg->nal_unit_size = 4;
1151
0
  cfg->chroma_format = 1;
1152
0
  cfg->bit_depth = 8;
1153
0
  return cfg;
1154
0
}
1155
1156
GF_EXPORT
1157
void gf_odf_vvc_cfg_del(GF_VVCConfig *cfg)
1158
0
{
1159
0
  if (!cfg) return;
1160
0
  while (gf_list_count(cfg->param_array)) {
1161
0
    GF_NALUFFParamArray *pa = (GF_NALUFFParamArray*)gf_list_get(cfg->param_array, 0);
1162
0
    gf_list_rem(cfg->param_array, 0);
1163
1164
0
    while (gf_list_count(pa->nalus)) {
1165
0
      GF_NALUFFParam *n = (GF_NALUFFParam*)gf_list_get(pa->nalus, 0);
1166
0
      gf_list_rem(pa->nalus, 0);
1167
0
      if (n->data) gf_free(n->data);
1168
0
      gf_free(n);
1169
0
    }
1170
0
    gf_list_del(pa->nalus);
1171
0
    gf_free(pa);
1172
0
  }
1173
0
  gf_list_del(cfg->param_array);
1174
0
  if (cfg->general_constraint_info)
1175
0
    gf_free(cfg->general_constraint_info);
1176
0
  if (cfg->sub_profiles_idc)
1177
0
    gf_free(cfg->sub_profiles_idc);
1178
0
  gf_free(cfg);
1179
0
}
1180
1181
GF_EXPORT
1182
GF_Err gf_odf_vvc_cfg_write_bs(GF_VVCConfig *cfg, GF_BitStream *bs)
1183
0
{
1184
0
  u32 i, count;
1185
1186
0
  count = gf_list_count(cfg->param_array);
1187
1188
0
  if (!cfg->write_annex_b) {
1189
1190
0
    gf_bs_write_int(bs, 0xFF, 5);
1191
0
    gf_bs_write_int(bs, cfg->nal_unit_size - 1, 2);
1192
0
    gf_bs_write_int(bs, cfg->ptl_present, 1);
1193
1194
0
    if (cfg->ptl_present) {
1195
0
      s32 idx;
1196
1197
0
      gf_bs_write_int(bs, cfg->ols_idx, 9);
1198
0
      gf_bs_write_int(bs, cfg->numTemporalLayers, 3);
1199
0
      gf_bs_write_int(bs, cfg->constantFrameRate, 2);
1200
0
      gf_bs_write_int(bs, cfg->chroma_format, 2);
1201
0
      gf_bs_write_int(bs, cfg->bit_depth - 8, 3);
1202
0
      gf_bs_write_int(bs, 0xFF, 5);
1203
1204
0
      if (!cfg->general_constraint_info)
1205
0
        cfg->num_constraint_info = 0;
1206
1207
      //write PTL
1208
0
      gf_bs_write_int(bs, 0, 2);
1209
0
      gf_bs_write_int(bs, cfg->num_constraint_info, 6);
1210
0
      gf_bs_write_int(bs, cfg->general_profile_idc, 7);
1211
0
      gf_bs_write_int(bs, cfg->general_tier_flag, 1);
1212
0
      gf_bs_write_u8(bs, cfg->general_level_idc);
1213
0
      gf_bs_write_int(bs, cfg->ptl_frame_only_constraint, 1);
1214
0
      gf_bs_write_int(bs, cfg->ptl_multilayer_enabled, 1);
1215
1216
0
      if (cfg->num_constraint_info) {
1217
0
        gf_bs_write_data(bs, cfg->general_constraint_info, cfg->num_constraint_info - 1);
1218
0
        gf_bs_write_int(bs, cfg->general_constraint_info[cfg->num_constraint_info - 1], 6);
1219
0
      } else {
1220
0
        gf_bs_write_int(bs, 0, 6);
1221
0
      }
1222
1223
0
      for (idx=cfg->numTemporalLayers-2; idx>=0; idx--) {
1224
0
        u8 val = cfg->ptl_sublayer_present_mask & (1<<idx);
1225
0
        gf_bs_write_int(bs, val ? 1 : 0, 1);
1226
0
      }
1227
0
      for (idx=cfg->numTemporalLayers; idx<=8 && cfg->numTemporalLayers>1; idx++) {
1228
0
        gf_bs_write_int(bs, 0, 1);
1229
0
      }
1230
0
      for (idx=cfg->numTemporalLayers-2; idx>=0; idx--) {
1231
0
        if (cfg->ptl_sublayer_present_mask & (1<<idx))
1232
0
          gf_bs_write_u8(bs, cfg->sublayer_level_idc[idx]);
1233
0
      }
1234
0
      if (!cfg->sub_profiles_idc) cfg->num_sub_profiles = 0;
1235
0
      gf_bs_write_u8(bs, cfg->num_sub_profiles);
1236
0
      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
0
      gf_bs_write_u16(bs, cfg->maxPictureWidth);
1242
0
      gf_bs_write_u16(bs, cfg->maxPictureHeight);
1243
0
      gf_bs_write_u16(bs, cfg->avgFrameRate);
1244
0
    }
1245
0
    gf_bs_write_int(bs, count, 8);
1246
0
  }
1247
1248
0
  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
0
  return GF_OK;
1277
0
}
1278
1279
GF_EXPORT
1280
GF_Err gf_odf_vvc_cfg_write(GF_VVCConfig *cfg, u8 **outData, u32 *outSize)
1281
0
{
1282
0
  GF_Err e;
1283
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1284
0
  *outSize = 0;
1285
0
  *outData = NULL;
1286
0
  e = gf_odf_vvc_cfg_write_bs(cfg, bs);
1287
0
  if (e==GF_OK)
1288
0
    gf_bs_get_content(bs, outData, outSize);
1289
1290
0
  gf_bs_del(bs);
1291
0
  return e;
1292
0
}
1293
1294
GF_EXPORT
1295
GF_VVCConfig *gf_odf_vvc_cfg_read_bs(GF_BitStream *bs)
1296
0
{
1297
0
  u32 i, count;
1298
0
  GF_VVCConfig *cfg = gf_odf_vvc_cfg_new();
1299
1300
0
  gf_bs_read_int(bs, 5);
1301
0
  cfg->nal_unit_size = 1 + gf_bs_read_int(bs, 2);
1302
0
  cfg->ptl_present = gf_bs_read_int(bs, 1);
1303
1304
0
  if (cfg->ptl_present) {
1305
0
    s32 j;
1306
1307
0
    cfg->ols_idx = gf_bs_read_int(bs, 9);
1308
0
    cfg->numTemporalLayers = gf_bs_read_int(bs, 3);
1309
0
    cfg->constantFrameRate = gf_bs_read_int(bs, 2);
1310
0
    cfg->chroma_format = gf_bs_read_int(bs, 2);
1311
0
    cfg->bit_depth = 8 + gf_bs_read_int(bs, 3);
1312
0
    gf_bs_read_int(bs, 5);
1313
1314
    //parse PTL
1315
0
    gf_bs_read_int(bs, 2);
1316
0
    cfg->num_constraint_info = gf_bs_read_int(bs, 6);
1317
0
    cfg->general_profile_idc = gf_bs_read_int(bs, 7);
1318
0
    cfg->general_tier_flag = gf_bs_read_int(bs, 1);
1319
0
    cfg->general_level_idc = gf_bs_read_u8(bs);
1320
0
    cfg->ptl_frame_only_constraint = gf_bs_read_int(bs, 1);
1321
0
    cfg->ptl_multilayer_enabled = gf_bs_read_int(bs, 1);
1322
1323
0
    if (cfg->num_constraint_info) {
1324
0
      cfg->general_constraint_info = gf_malloc(sizeof(u8)*cfg->num_constraint_info);
1325
0
      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
0
      gf_bs_read_data(bs, cfg->general_constraint_info, cfg->num_constraint_info - 1);
1331
0
      cfg->general_constraint_info[cfg->num_constraint_info-1] =  gf_bs_read_int(bs, 6);
1332
0
    } else {
1333
      //forbidden in spec!
1334
0
      gf_bs_read_int(bs, 6);
1335
0
    }
1336
1337
0
    cfg->ptl_sublayer_present_mask = 0;
1338
0
    for (j=cfg->numTemporalLayers-2; j>=0; j--) {
1339
0
      u32 val = gf_bs_read_int(bs, 1);
1340
0
      cfg->ptl_sublayer_present_mask |= val << j;
1341
0
    }
1342
0
    for (j=cfg->numTemporalLayers; j<=8 && cfg->numTemporalLayers>1; j++) {
1343
0
      gf_bs_read_int(bs, 1);
1344
0
    }
1345
0
    for (j=cfg->numTemporalLayers-2; j>=0; j--) {
1346
0
      if (cfg->ptl_sublayer_present_mask & (1<<j)) {
1347
0
        cfg->sublayer_level_idc[j] = gf_bs_read_u8(bs);
1348
0
      }
1349
0
    }
1350
0
    cfg->num_sub_profiles = gf_bs_read_u8(bs);
1351
0
    if (cfg->num_sub_profiles) {
1352
0
      cfg->sub_profiles_idc = gf_malloc(sizeof(u32)*cfg->num_sub_profiles);
1353
0
      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
0
    }
1360
0
    for (i=0; i<cfg->num_sub_profiles; i++) {
1361
0
      cfg->sub_profiles_idc[i] = gf_bs_read_u32(bs);
1362
0
    }
1363
1364
    //end PTL
1365
1366
0
    cfg->maxPictureWidth = gf_bs_read_u16(bs);
1367
0
    cfg->maxPictureHeight = gf_bs_read_u16(bs);
1368
0
    cfg->avgFrameRate = gf_bs_read_u16(bs);
1369
0
  }
1370
1371
0
  count = gf_bs_read_int(bs, 8);
1372
0
  for (i=0; i<count; i++) {
1373
0
    u32 nalucount, j;
1374
0
    Bool valid = GF_FALSE;
1375
0
    GF_NALUFFParamArray *ar;
1376
0
    GF_SAFEALLOC(ar, GF_NALUFFParamArray);
1377
0
    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
0
    ar->array_completeness = gf_bs_read_int(bs, 1);
1383
0
    gf_bs_read_int(bs, 2);
1384
0
    ar->type = gf_bs_read_int(bs, 5);
1385
1386
0
    switch (ar->type) {
1387
0
    case GF_VVC_NALU_DEC_PARAM:
1388
0
    case GF_VVC_NALU_OPI:
1389
0
    case GF_VVC_NALU_VID_PARAM:
1390
0
    case GF_VVC_NALU_SEQ_PARAM:
1391
0
    case GF_VVC_NALU_PIC_PARAM:
1392
0
    case GF_VVC_NALU_SEI_PREFIX:
1393
0
    case GF_VVC_NALU_SEI_SUFFIX:
1394
0
      valid = GF_TRUE;
1395
0
      ar->nalus = gf_list_new();
1396
0
      gf_list_add(cfg->param_array, ar);
1397
0
      break;
1398
0
    default:
1399
0
      GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[VVC] Invalid NALU type %d in vvcC - ignoring\n", ar->type));
1400
0
      gf_free(ar);
1401
0
      break;
1402
0
    }
1403
1404
0
    if (!valid || ((ar->type != GF_VVC_NALU_DEC_PARAM) && (ar->type != GF_VVC_NALU_OPI)))
1405
0
      nalucount = gf_bs_read_int(bs, 16);
1406
0
    else
1407
0
      nalucount = 1;
1408
1409
0
    for (j=0; j<nalucount; j++) {
1410
0
      GF_NALUFFParam *sl;
1411
0
      u32 size = gf_bs_read_int(bs, 16);
1412
0
      if ((size>gf_bs_available(bs)) || (size<2)) {
1413
0
        GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VVC] Wrong param set size %d\n", size));
1414
0
        gf_odf_vvc_cfg_del(cfg);
1415
0
        return NULL;
1416
0
      }
1417
0
      if (!valid) {
1418
0
        gf_bs_skip_bytes(bs, size);
1419
0
        continue;
1420
0
      }
1421
0
      GF_SAFEALLOC(sl, GF_NALUFFParam );
1422
0
      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
0
      sl->size = size;
1429
0
      sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
1430
0
      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
0
      gf_bs_read_data(bs, sl->data, sl->size);
1437
0
      gf_list_add(ar->nalus, sl);
1438
0
    }
1439
0
  }
1440
0
  return cfg;
1441
0
}
1442
1443
GF_EXPORT
1444
GF_VVCConfig *gf_odf_vvc_cfg_read(u8 *dsi, u32 dsi_size)
1445
0
{
1446
0
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
1447
0
  GF_VVCConfig *cfg = gf_odf_vvc_cfg_read_bs(bs);
1448
0
  gf_bs_del(bs);
1449
0
  return cfg;
1450
0
}
1451
1452
GF_EXPORT
1453
GF_AV1Config *gf_odf_av1_cfg_new()
1454
0
{
1455
0
  GF_AV1Config *cfg;
1456
0
  GF_SAFEALLOC(cfg, GF_AV1Config);
1457
0
  if (!cfg) return NULL;
1458
0
  cfg->marker = 1;
1459
0
  cfg->version = 1;
1460
0
  cfg->initial_presentation_delay_minus_one = 0;
1461
0
  cfg->obu_array = gf_list_new();
1462
0
  return cfg;
1463
0
}
1464
1465
GF_EXPORT
1466
void gf_odf_av1_cfg_del(GF_AV1Config *cfg)
1467
0
{
1468
0
  if (!cfg) return;
1469
0
  while (gf_list_count(cfg->obu_array)) {
1470
0
    GF_AV1_OBUArrayEntry *a = (GF_AV1_OBUArrayEntry*)gf_list_get(cfg->obu_array, 0);
1471
0
    if (a->obu) gf_free(a->obu);
1472
0
    gf_list_rem(cfg->obu_array, 0);
1473
0
    gf_free(a);
1474
0
  }
1475
0
  gf_list_del(cfg->obu_array);
1476
0
  gf_free(cfg);
1477
0
}
1478
1479
GF_EXPORT
1480
GF_Err gf_odf_av1_cfg_write_bs(GF_AV1Config *cfg, GF_BitStream *bs)
1481
0
{
1482
0
  u32 i = 0;
1483
0
  gf_bs_write_int(bs, cfg->marker, 1);
1484
0
  gf_assert(cfg->marker == 1);
1485
0
  gf_bs_write_int(bs, cfg->version, 7);
1486
0
  gf_assert(cfg->version == 1);
1487
0
  gf_bs_write_int(bs, cfg->seq_profile, 3);
1488
0
  gf_bs_write_int(bs, cfg->seq_level_idx_0, 5);
1489
0
  gf_bs_write_int(bs, cfg->seq_tier_0, 1);
1490
0
  gf_bs_write_int(bs, cfg->high_bitdepth, 1);
1491
0
  gf_bs_write_int(bs, cfg->twelve_bit, 1);
1492
0
  gf_bs_write_int(bs, cfg->monochrome, 1);
1493
0
  gf_bs_write_int(bs, cfg->chroma_subsampling_x, 1);
1494
0
  gf_bs_write_int(bs, cfg->chroma_subsampling_y, 1);
1495
0
  gf_bs_write_int(bs, cfg->chroma_sample_position, 2);
1496
0
  gf_bs_write_int(bs, 0, 3); /*reserved*/
1497
0
  gf_bs_write_int(bs, cfg->initial_presentation_delay_present, 1);
1498
0
  gf_bs_write_int(bs, cfg->initial_presentation_delay_minus_one, 4); /*TODO: compute initial_presentation_delay_minus_one*/
1499
0
  for (i = 0; i < gf_list_count(cfg->obu_array); ++i) {
1500
0
    GF_AV1_OBUArrayEntry *a = gf_list_get(cfg->obu_array, i);
1501
0
    gf_bs_write_data(bs, a->obu, (u32)a->obu_length); //TODO: we are supposed to omit the size on the last OBU...
1502
0
  }
1503
0
  return GF_OK;
1504
0
}
1505
1506
GF_EXPORT
1507
0
GF_Err gf_odf_av1_cfg_write(GF_AV1Config *cfg, u8 **outData, u32 *outSize) {
1508
0
  GF_Err e;
1509
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1510
0
  *outSize = 0;
1511
0
  *outData = NULL;
1512
0
  e = gf_odf_av1_cfg_write_bs(cfg, bs);
1513
0
  if (e == GF_OK)
1514
0
    gf_bs_get_content(bs, outData, outSize);
1515
1516
0
  gf_bs_del(bs);
1517
0
  return e;
1518
0
}
1519
1520
GF_EXPORT
1521
GF_VPConfig *gf_odf_vp_cfg_new()
1522
0
{
1523
0
  GF_VPConfig *cfg;
1524
0
  GF_SAFEALLOC(cfg, GF_VPConfig);
1525
0
  if (!cfg) return NULL;
1526
0
  cfg->codec_initdata_size = 0;
1527
0
  cfg->codec_initdata = NULL;
1528
0
  return cfg;
1529
0
}
1530
1531
GF_EXPORT
1532
void gf_odf_vp_cfg_del(GF_VPConfig *cfg)
1533
0
{
1534
0
  if (!cfg) return;
1535
1536
0
  if (cfg->codec_initdata) {
1537
0
    gf_free(cfg->codec_initdata);
1538
0
    cfg->codec_initdata = NULL;
1539
0
  }
1540
1541
0
  gf_free(cfg);
1542
0
}
1543
1544
GF_EXPORT
1545
GF_Err gf_odf_vp_cfg_write_bs(GF_VPConfig *cfg, GF_BitStream *bs, Bool is_v0)
1546
0
{
1547
0
  gf_bs_write_int(bs, cfg->profile, 8);
1548
0
  gf_bs_write_int(bs, cfg->level, 8);
1549
0
  gf_bs_write_int(bs, cfg->bit_depth, 4);
1550
0
  gf_bs_write_int(bs, cfg->chroma_subsampling, 3);
1551
0
  gf_bs_write_int(bs, cfg->video_fullRange_flag, 1);
1552
0
  gf_bs_write_int(bs, cfg->colour_primaries, 8);
1553
0
  gf_bs_write_int(bs, cfg->transfer_characteristics, 8);
1554
0
  gf_bs_write_int(bs, cfg->matrix_coefficients, 8);
1555
1556
0
  if (!is_v0) {
1557
0
    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
0
    gf_bs_write_int(bs, (u16)0, 16);
1562
0
  }
1563
1564
0
  return GF_OK;
1565
0
}
1566
1567
GF_EXPORT
1568
GF_Err gf_odf_vp_cfg_write(GF_VPConfig *cfg, u8 **outData, u32 *outSize, Bool is_v0)
1569
0
{
1570
0
  GF_Err e;
1571
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1572
0
  *outSize = 0;
1573
0
  *outData = NULL;
1574
0
  e = gf_odf_vp_cfg_write_bs(cfg, bs, is_v0);
1575
0
  if (e==GF_OK)
1576
0
    gf_bs_get_content(bs, outData, outSize);
1577
1578
0
  gf_bs_del(bs);
1579
0
  return e;
1580
0
}
1581
1582
GF_EXPORT
1583
GF_VPConfig *gf_odf_vp_cfg_read_bs(GF_BitStream *bs, Bool is_v0)
1584
0
{
1585
0
  GF_VPConfig *cfg = gf_odf_vp_cfg_new();
1586
1587
0
  cfg->profile = gf_bs_read_int(bs, 8);
1588
0
  cfg->level = gf_bs_read_int(bs, 8);
1589
1590
0
  cfg->bit_depth = gf_bs_read_int(bs, 4);
1591
0
  cfg->chroma_subsampling = gf_bs_read_int(bs, 3);
1592
0
  cfg->video_fullRange_flag = gf_bs_read_int(bs, 1);
1593
1594
0
  cfg->colour_primaries = gf_bs_read_int(bs, 8);
1595
0
  cfg->transfer_characteristics = gf_bs_read_int(bs, 8);
1596
0
  cfg->matrix_coefficients = gf_bs_read_int(bs, 8);
1597
1598
0
  if (is_v0)
1599
0
    return cfg;
1600
1601
0
  cfg->codec_initdata_size = gf_bs_read_int(bs, 16);
1602
1603
  // must be 0 according to spec
1604
0
  if (cfg->codec_initdata_size) {
1605
0
    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
0
    gf_odf_vp_cfg_del(cfg);
1607
0
    return NULL;
1608
0
  }
1609
1610
0
  return cfg;
1611
0
}
1612
1613
GF_EXPORT
1614
GF_VPConfig *gf_odf_vp_cfg_read(u8 *dsi, u32 dsi_size)
1615
0
{
1616
0
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
1617
0
  GF_VPConfig *cfg = gf_odf_vp_cfg_read_bs(bs, GF_FALSE);
1618
0
  gf_bs_del(bs);
1619
0
  return cfg;
1620
0
}
1621
1622
GF_EXPORT
1623
GF_AV1Config *gf_odf_av1_cfg_read_bs_size(GF_BitStream *bs, u32 size)
1624
0
{
1625
0
#ifndef GPAC_DISABLE_AV_PARSERS
1626
0
  AV1State *av1_state;
1627
0
  u8 reserved;
1628
0
  GF_AV1Config *cfg;
1629
1630
0
  if (!size) size = (u32) gf_bs_available(bs);
1631
0
  if (!size) return NULL;
1632
1633
0
  GF_SAFEALLOC(av1_state, AV1State);
1634
0
  if (!av1_state) return NULL;
1635
0
  cfg = gf_odf_av1_cfg_new();
1636
0
  gf_av1_init_state(av1_state);
1637
0
  av1_state->config = cfg;
1638
1639
0
  cfg->marker = gf_bs_read_int(bs, 1);
1640
0
  cfg->version = gf_bs_read_int(bs, 7);
1641
0
  cfg->seq_profile = gf_bs_read_int(bs, 3);
1642
0
  cfg->seq_level_idx_0 = gf_bs_read_int(bs, 5);
1643
0
  cfg->seq_tier_0 = gf_bs_read_int(bs, 1);
1644
0
  cfg->high_bitdepth = gf_bs_read_int(bs, 1);
1645
0
  cfg->twelve_bit = gf_bs_read_int(bs, 1);
1646
0
  cfg->monochrome = gf_bs_read_int(bs, 1);
1647
0
  cfg->chroma_subsampling_x = gf_bs_read_int(bs, 1);
1648
0
  cfg->chroma_subsampling_y = gf_bs_read_int(bs, 1);
1649
0
  cfg->chroma_sample_position = gf_bs_read_int(bs, 2);
1650
1651
0
  reserved = gf_bs_read_int(bs, 3);
1652
0
  cfg->initial_presentation_delay_present = gf_bs_read_int(bs, 1);
1653
0
  if (cfg->initial_presentation_delay_present) {
1654
0
    cfg->initial_presentation_delay_minus_one = gf_bs_read_int(bs, 4);
1655
0
  } else {
1656
0
    /*reserved = */gf_bs_read_int(bs, 4);
1657
0
    cfg->initial_presentation_delay_minus_one = 0;
1658
0
  }
1659
0
  size -= 4;
1660
1661
0
  if (reserved != 0 || cfg->marker != 1 || cfg->version != 1) {
1662
0
    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
0
    gf_odf_av1_cfg_del(cfg);
1664
0
    gf_free(av1_state);
1665
0
    return NULL;
1666
0
  }
1667
1668
1669
0
  while (size) {
1670
0
    u64 pos, obu_size;
1671
0
    ObuType obu_type;
1672
0
    GF_AV1_OBUArrayEntry *a;
1673
1674
0
    pos = gf_bs_get_position(bs);
1675
0
    obu_size = 0;
1676
0
    if (gf_av1_parse_obu(bs, &obu_type, &obu_size, NULL, av1_state) != GF_OK) {
1677
0
      GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] av1C: could not parse AV1 OBU at position "LLU". Leaving parsing.\n", pos));
1678
0
      break;
1679
0
    }
1680
0
    gf_assert(obu_size == gf_bs_get_position(bs) - pos);
1681
0
    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));
1682
1683
0
    if (!av1_is_obu_header(obu_type)) {
1684
0
      GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[AV1] av1C: AV1 unexpected OBU type=%u size="LLU" found at position "LLU". Forwarding.\n", pos));
1685
0
    }
1686
0
    GF_SAFEALLOC(a, GF_AV1_OBUArrayEntry);
1687
0
    if (!a) break;
1688
0
    a->obu = gf_malloc((size_t)obu_size);
1689
0
    if (!a->obu) {
1690
0
      gf_free(a);
1691
0
      break;
1692
0
    }
1693
0
    gf_bs_seek(bs, pos);
1694
0
    gf_bs_read_data(bs, (char *) a->obu, (u32)obu_size);
1695
0
    a->obu_length = obu_size;
1696
0
    a->obu_type = obu_type;
1697
0
    gf_list_add(cfg->obu_array, a);
1698
1699
0
    if (size<obu_size) {
1700
0
      GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] AV1 config misses %d bytes to fit the entire OBU\n", obu_size - size));
1701
0
      break;
1702
0
    }
1703
0
    size -= (u32) obu_size;
1704
0
  }
1705
0
  gf_av1_reset_state(av1_state, GF_TRUE);
1706
0
  gf_bs_align(bs);
1707
0
  gf_free(av1_state);
1708
0
  return cfg;
1709
#else
1710
  return NULL;
1711
#endif
1712
0
}
1713
1714
GF_EXPORT
1715
GF_AV1Config *gf_odf_av1_cfg_read_bs(GF_BitStream *bs)
1716
0
{
1717
0
  return gf_odf_av1_cfg_read_bs_size(bs, 0);
1718
1719
0
}
1720
GF_EXPORT
1721
GF_AV1Config *gf_odf_av1_cfg_read(u8 *dsi, u32 dsi_size)
1722
0
{
1723
0
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
1724
0
  GF_AV1Config *cfg = gf_odf_av1_cfg_read_bs(bs);
1725
0
  gf_bs_del(bs);
1726
0
  return cfg;
1727
0
}
1728
1729
GF_EXPORT
1730
GF_DOVIDecoderConfigurationRecord *gf_odf_dovi_cfg_read_bs(GF_BitStream *bs)
1731
0
{
1732
0
  GF_DOVIDecoderConfigurationRecord *cfg;
1733
0
  GF_SAFEALLOC(cfg, GF_DOVIDecoderConfigurationRecord);
1734
1735
0
  cfg->dv_version_major = gf_bs_read_u8(bs);
1736
0
  cfg->dv_version_minor = gf_bs_read_u8(bs);
1737
0
  cfg->dv_profile = gf_bs_read_int(bs, 7);
1738
0
  cfg->dv_level = gf_bs_read_int(bs, 6);
1739
0
  cfg->rpu_present_flag = gf_bs_read_int(bs, 1);
1740
0
  cfg->el_present_flag = gf_bs_read_int(bs, 1);
1741
0
  cfg->bl_present_flag = gf_bs_read_int(bs, 1);
1742
0
  cfg->dv_bl_signal_compatibility_id = gf_bs_read_int(bs, 4);
1743
0
  if (gf_bs_read_int(bs, 28)) {
1744
0
    GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[DOVI] Configuration reserved bits are not zero\n"));
1745
0
  }
1746
0
  for (u32 i=0; i<4; i++) {
1747
0
    if (gf_bs_read_u32(bs)) {
1748
0
      GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[DOVII] Configuration reserved bits are not zero\n"));
1749
0
    }
1750
0
  }
1751
0
  return cfg;
1752
0
}
1753
1754
GF_EXPORT
1755
void gf_odf_dovi_cfg_del(GF_DOVIDecoderConfigurationRecord *cfg)
1756
0
{
1757
0
  gf_free(cfg);
1758
0
}
1759
1760
GF_EXPORT
1761
GF_Err gf_odf_dovi_cfg_write_bs(GF_DOVIDecoderConfigurationRecord *cfg, GF_BitStream *bs)
1762
0
{
1763
0
  gf_bs_write_u8(bs,  cfg->dv_version_major);
1764
0
  gf_bs_write_u8(bs,  cfg->dv_version_minor);
1765
0
  gf_bs_write_int(bs, cfg->dv_profile, 7);
1766
0
  gf_bs_write_int(bs, cfg->dv_level, 6);
1767
0
  gf_bs_write_int(bs, cfg->rpu_present_flag, 1);
1768
0
  gf_bs_write_int(bs, cfg->el_present_flag, 1);
1769
0
  gf_bs_write_int(bs, cfg->bl_present_flag, 1);
1770
0
  gf_bs_write_int(bs, cfg->dv_bl_signal_compatibility_id, 4);
1771
0
  gf_bs_write_int(bs, 0, 28);
1772
0
  gf_bs_write_u32(bs, 0);
1773
0
  gf_bs_write_u32(bs, 0);
1774
0
  gf_bs_write_u32(bs, 0);
1775
0
  gf_bs_write_u32(bs, 0);
1776
0
  return GF_OK;
1777
0
}
1778
1779
1780
GF_EXPORT
1781
GF_Err gf_odf_ac3_cfg_write_bs(GF_AC3Config *cfg, GF_BitStream *bs)
1782
0
{
1783
0
  if (!cfg || !bs) return GF_BAD_PARAM;
1784
1785
0
  if (cfg->is_ec3) {
1786
0
    u32 i;
1787
0
    gf_bs_write_int(bs, cfg->brcode, 13);
1788
0
    gf_bs_write_int(bs, cfg->nb_streams - 1, 3);
1789
0
    for (i=0; i<cfg->nb_streams; i++) {
1790
0
      gf_bs_write_int(bs, cfg->streams[i].fscod, 2);
1791
0
      gf_bs_write_int(bs, cfg->streams[i].bsid, 5);
1792
0
      gf_bs_write_int(bs, cfg->streams[i].bsmod, 5);
1793
0
      gf_bs_write_int(bs, cfg->streams[i].acmod, 3);
1794
0
      gf_bs_write_int(bs, cfg->streams[i].lfon, 1);
1795
0
      gf_bs_write_int(bs, 0, 3);
1796
0
      gf_bs_write_int(bs, cfg->streams[i].nb_dep_sub, 4);
1797
0
      if (cfg->streams[i].nb_dep_sub) {
1798
0
        gf_bs_write_int(bs, cfg->streams[i].chan_loc, 9);
1799
0
      } else {
1800
0
        gf_bs_write_int(bs, 0, 1);
1801
0
      }
1802
0
    }
1803
0
  } else {
1804
0
    gf_bs_write_int(bs, cfg->streams[0].fscod, 2);
1805
0
    gf_bs_write_int(bs, cfg->streams[0].bsid, 5);
1806
0
    gf_bs_write_int(bs, cfg->streams[0].bsmod, 3);
1807
0
    gf_bs_write_int(bs, cfg->streams[0].acmod, 3);
1808
0
    gf_bs_write_int(bs, cfg->streams[0].lfon, 1);
1809
0
    gf_bs_write_int(bs, cfg->brcode, 5);
1810
0
    gf_bs_write_int(bs, 0, 5);
1811
0
  }
1812
0
  return GF_OK;
1813
0
}
1814
1815
GF_EXPORT
1816
GF_Err gf_odf_ac3_cfg_write(GF_AC3Config *cfg, u8 **data, u32 *size)
1817
0
{
1818
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1819
0
  GF_Err e = gf_odf_ac3_cfg_write_bs(cfg, bs);
1820
1821
0
  if (cfg->is_ec3 && (cfg->atmos_ec3_ext || cfg->complexity_index_type)) {
1822
0
    gf_bs_write_int(bs, 0, 7);
1823
0
    gf_bs_write_int(bs, cfg->atmos_ec3_ext, 1);
1824
0
    gf_bs_write_u8(bs, cfg->complexity_index_type);
1825
0
  }
1826
0
  gf_bs_get_content(bs, data, size);
1827
1828
0
  gf_bs_del(bs);
1829
0
  return e;
1830
0
}
1831
1832
GF_EXPORT
1833
GF_Err gf_odf_ac3_cfg_parse_bs(GF_BitStream *bs, Bool is_ec3, GF_AC3Config *cfg)
1834
0
{
1835
0
  if (!cfg || !bs) return GF_BAD_PARAM;
1836
0
  memset(cfg, 0, sizeof(GF_AC3Config));
1837
0
  cfg->is_ec3 = is_ec3;
1838
0
  if (is_ec3) {
1839
0
    u32 j;
1840
0
    cfg->is_ec3 = 1;
1841
0
    cfg->brcode = gf_bs_read_int(bs, 13);
1842
0
    cfg->nb_streams = 1 + gf_bs_read_int(bs, 3);
1843
0
    for (j=0; j<cfg->nb_streams; j++) {
1844
0
      cfg->streams[j].fscod = gf_bs_read_int(bs, 2);
1845
0
      cfg->streams[j].bsid = gf_bs_read_int(bs, 5);
1846
0
      gf_bs_read_int(bs, 1);
1847
0
      cfg->streams[j].asvc = gf_bs_read_int(bs, 1);
1848
0
      cfg->streams[j].bsmod = gf_bs_read_int(bs, 3);
1849
0
      cfg->streams[j].acmod = gf_bs_read_int(bs, 3);
1850
0
      cfg->streams[j].lfon = gf_bs_read_int(bs, 1);
1851
0
      gf_bs_read_int(bs, 3);
1852
0
      cfg->streams[j].nb_dep_sub = gf_bs_read_int(bs, 4);
1853
0
      if (cfg->streams[j].nb_dep_sub) {
1854
0
        cfg->streams[j].chan_loc = gf_bs_read_int(bs, 9);
1855
0
      } else {
1856
0
        gf_bs_read_int(bs, 1);
1857
0
      }
1858
0
    }
1859
0
  } else {
1860
0
    cfg->nb_streams = 1;
1861
0
    cfg->streams[0].fscod = gf_bs_read_int(bs, 2);
1862
0
    cfg->streams[0].bsid = gf_bs_read_int(bs, 5);
1863
0
    cfg->streams[0].bsmod = gf_bs_read_int(bs, 3);
1864
0
    cfg->streams[0].acmod = gf_bs_read_int(bs, 3);
1865
0
    cfg->streams[0].lfon = gf_bs_read_int(bs, 1);
1866
0
    cfg->brcode = gf_bs_read_int(bs, 5);
1867
0
    gf_bs_read_int(bs, 5);
1868
0
  }
1869
0
  return GF_OK;
1870
0
}
1871
1872
GF_EXPORT
1873
GF_Err gf_odf_ac3_cfg_parse(u8 *dsi, u32 dsi_len, Bool is_ec3, GF_AC3Config *cfg)
1874
0
{
1875
0
  GF_BitStream *bs;
1876
0
  GF_Err e;
1877
0
  if (!cfg || !dsi) return GF_BAD_PARAM;
1878
0
  bs = gf_bs_new(dsi, dsi_len, GF_BITSTREAM_READ);
1879
0
  e = gf_odf_ac3_cfg_parse_bs(bs, is_ec3, cfg);
1880
0
  if (is_ec3 && gf_bs_available(bs)>=2) {
1881
0
    gf_bs_read_int(bs, 7);
1882
0
    cfg->atmos_ec3_ext = gf_bs_read_int(bs, 1);
1883
0
    cfg->complexity_index_type = gf_bs_read_u8(bs);
1884
0
  }
1885
0
  gf_bs_del(bs);
1886
0
  return e;
1887
0
}
1888
1889
0
#define GF_AC4_SSS(bs, value, nbits, size, mode) { \
1890
0
  if (mode == GF_AC4_DESCMODE_PARSE) value = gf_bs_read_int(bs, nbits); \
1891
0
  else if (mode == GF_AC4_DESCMODE_WRITE) gf_bs_write_int(bs, value, nbits); \
1892
0
  else if (mode == GF_AC4_DESCMODE_GETSIZE) *size += nbits;}
1893
1894
0
#define GF_AC4_ALLIGN(bs, size, mode) { \
1895
0
  if (mode == GF_AC4_DESCMODE_PARSE) gf_bs_align(bs); \
1896
0
  else if (mode == GF_AC4_DESCMODE_WRITE) gf_bs_align(bs); \
1897
0
  else if (mode == GF_AC4_DESCMODE_GETSIZE && (*size % 8 != 0)) *size = ((*size / 8) + 1) * 8;}
1898
1899
GF_Err gf_odf_ac4_cfg_alternative_info(GF_AC4AlternativeInfo *info, GF_BitStream *bs, u64 *size, u8 desc_mode)
1900
0
{
1901
0
  u32 i;
1902
1903
0
  GF_AC4_SSS(bs, info->name_len, 16, size, desc_mode);
1904
1905
0
  if (info->name_len >= GF_ARRAY_LENGTH(info->presentation_name))
1906
0
    return GF_ISOM_INVALID_MEDIA;
1907
1908
0
  for (i = 0; i < info->name_len; i++) {
1909
0
    GF_AC4_SSS(bs, info->presentation_name[i], 8, size, desc_mode);
1910
0
  }
1911
1912
0
  GF_AC4_SSS(bs, info->n_targets, 5, size, desc_mode);
1913
1914
0
  if (info->n_targets >= MIN(GF_ARRAY_LENGTH(info->target_md_compat), GF_ARRAY_LENGTH(info->target_device_category)))
1915
0
    return GF_ISOM_INVALID_MEDIA;
1916
1917
0
  for (i = 0; i < info->n_targets; i++) {
1918
0
    GF_AC4_SSS(bs, info->target_md_compat[i], 3, size, desc_mode);
1919
0
    GF_AC4_SSS(bs, info->target_device_category[i], 8, size, desc_mode);
1920
0
  }
1921
0
  return GF_OK;
1922
0
}
1923
1924
GF_Err gf_odf_ac4_cfg_substream_dsi(GF_AC4SubStream *s, GF_BitStream *bs, u8 b_channel_coded, u64 *size, u8 desc_mode)
1925
0
{
1926
0
  u32 zero_val = 0;
1927
1928
0
  GF_AC4_SSS(bs, s->dsi_sf_multiplier, 2, size, desc_mode);
1929
0
  GF_AC4_SSS(bs, s->b_substream_bitrate_indicator, 1, size, desc_mode);
1930
0
  if (s->b_substream_bitrate_indicator == 1) {
1931
0
    GF_AC4_SSS(bs, s->substream_bitrate_indicator, 5, size, desc_mode);
1932
0
  }
1933
0
  if (b_channel_coded == 1) {
1934
0
    GF_AC4_SSS(bs, s->dsi_substream_channel_mask, 24, size, desc_mode);
1935
0
  } else {
1936
0
    GF_AC4_SSS(bs, s->b_ajoc, 1, size, desc_mode);
1937
0
    if (s->b_ajoc == 1) {
1938
0
      GF_AC4_SSS(bs, s->b_static_dmx, 1, size, desc_mode);
1939
0
      if (s->b_static_dmx == 0) {
1940
0
        GF_AC4_SSS(bs, s->n_dmx_objects_minus1, 4, size, desc_mode);
1941
0
      }
1942
0
      GF_AC4_SSS(bs, s->n_umx_objects_minus1, 6, size, desc_mode);
1943
0
    }
1944
0
    GF_AC4_SSS(bs, s->b_substream_contains_bed_objects, 1, size, desc_mode);
1945
0
    GF_AC4_SSS(bs, s->b_substream_contains_dynamic_objects, 1, size, desc_mode);
1946
0
    GF_AC4_SSS(bs, s->b_substream_contains_ISF_objects, 1, size, desc_mode);
1947
0
    GF_AC4_SSS(bs, zero_val, 1, size, desc_mode); //reserved bit
1948
0
  }
1949
0
  return GF_OK;
1950
0
}
1951
1952
GF_Err gf_odf_ac4_cfg_content_type(GF_AC4SubStreamGroupV1 *g, GF_BitStream *bs, u64 *size, u8 desc_mode)
1953
0
{
1954
0
  u32 i;
1955
1956
0
  GF_AC4_SSS(bs, g->b_content_type, 1, size, desc_mode);
1957
0
  if (g->b_content_type == 1){
1958
0
    GF_AC4_SSS(bs, g->content_classifier, 3, size, desc_mode);
1959
0
    GF_AC4_SSS(bs, g->b_language_indicator, 1, size, desc_mode);
1960
0
    if (g->b_language_indicator == 1){
1961
0
      GF_AC4_SSS(bs, g->n_language_tag_bytes, 6, size, desc_mode);
1962
0
      for (i = 0; i < g->n_language_tag_bytes; i++ ){
1963
0
        GF_AC4_SSS(bs, g->language_tag_bytes[i], 8, size, desc_mode);
1964
0
      }
1965
0
    }
1966
0
  }
1967
0
  return GF_OK;
1968
0
}
1969
1970
GF_Err gf_odf_ac4_cfg_substream_group_dsi(GF_AC4SubStreamGroupV1 *g, GF_BitStream *bs, u64 *size, u8 desc_mode)
1971
0
{
1972
0
  u32 i;
1973
0
  GF_AC4SubStream *s;
1974
1975
0
  if (!g)
1976
0
    return GF_BAD_PARAM;
1977
1978
0
  GF_AC4_SSS(bs, g->b_substreams_present, 1, size, desc_mode);
1979
0
  GF_AC4_SSS(bs, g->b_hsf_ext, 1, size, desc_mode);
1980
0
  GF_AC4_SSS(bs, g->b_channel_coded, 1, size, desc_mode);
1981
0
  GF_AC4_SSS(bs, g->n_lf_substreams, 8, size, desc_mode);
1982
1983
0
  if (desc_mode == GF_AC4_DESCMODE_PARSE) {
1984
0
    g->substreams = gf_list_new();
1985
0
  }
1986
0
  for (i = 0; i < g->n_lf_substreams; i++ ){
1987
0
    if (desc_mode == GF_AC4_DESCMODE_PARSE) {
1988
0
      GF_SAFEALLOC(s, GF_AC4SubStream);
1989
0
    } else { // write or get_size
1990
0
      s = (GF_AC4SubStream*)gf_list_get(g->substreams, i);
1991
0
    }
1992
0
    gf_odf_ac4_cfg_substream_dsi(s, bs, g->b_channel_coded, size, desc_mode);
1993
0
    if (desc_mode == GF_AC4_DESCMODE_PARSE) {
1994
0
      gf_list_add(g->substreams, s);
1995
0
    }
1996
0
  }
1997
0
  gf_odf_ac4_cfg_content_type(g, bs, size, desc_mode);
1998
0
  return GF_OK;
1999
0
}
2000
2001
GF_Err gf_odf_ac4_cfg_bitrate_dsi(GF_AC4BitrateDsi *bitr, GF_BitStream *bs, u64 *size, u8 desc_mode)
2002
0
{
2003
0
  GF_AC4_SSS(bs, bitr->bit_rate_mode, 2, size, desc_mode);
2004
0
  GF_AC4_SSS(bs, bitr->bit_rate, 32, size, desc_mode);
2005
0
  GF_AC4_SSS(bs, bitr->bit_rate_precision, 32, size, desc_mode);
2006
0
  return GF_OK;
2007
0
}
2008
2009
GF_Err gf_odf_ac4_cfg_presentation_v1_dsi(GF_AC4PresentationV1 *p, GF_BitStream *bs, u64 *size, u8 desc_mode)
2010
0
{
2011
0
  GF_AC4SubStreamGroupV1 *g;
2012
0
  u32 i, zero_val = 0;
2013
2014
0
  GF_AC4_SSS(bs, p->presentation_config, 5, size, desc_mode);
2015
0
  if (p->presentation_config == 0x06) {
2016
0
    p->b_add_emdf_substreams = 1;
2017
0
  } else {
2018
0
    GF_AC4_SSS(bs, p->mdcompat, 3, size, desc_mode);
2019
0
    GF_AC4_SSS(bs, p->b_presentation_id, 1, size, desc_mode);
2020
0
    if (p->b_presentation_id) {
2021
0
      GF_AC4_SSS(bs, p->presentation_id, 5, size, desc_mode);
2022
0
    }
2023
0
    GF_AC4_SSS(bs, p->dsi_frame_rate_multiply_info, 2, size, desc_mode);
2024
0
    GF_AC4_SSS(bs, p->dsi_frame_rate_fraction_info, 2, size, desc_mode);
2025
0
    GF_AC4_SSS(bs, p->presentation_emdf_version, 5, size, desc_mode);
2026
0
    GF_AC4_SSS(bs, p->presentation_key_id, 10, size, desc_mode);
2027
2028
0
    GF_AC4_SSS(bs, p->b_presentation_channel_coded, 1, size, desc_mode);
2029
0
    if (p->b_presentation_channel_coded) {
2030
0
      GF_AC4_SSS(bs, p->dsi_presentation_ch_mode, 5, size, desc_mode);
2031
0
      if (p->dsi_presentation_ch_mode >= 11 && p->dsi_presentation_ch_mode <= 14) {
2032
0
        GF_AC4_SSS(bs, p->pres_b_4_back_channels_present, 1, size, desc_mode);
2033
0
        GF_AC4_SSS(bs, p->pres_top_channel_pairs, 2, size, desc_mode);
2034
0
      }
2035
0
      GF_AC4_SSS(bs, p->presentation_channel_mask_v1, 24, size, desc_mode);
2036
0
    }
2037
2038
0
    GF_AC4_SSS(bs, p->b_presentation_core_differs, 1, size, desc_mode);
2039
0
    if (p->b_presentation_core_differs) {
2040
0
      GF_AC4_SSS(bs, p->b_presentation_core_channel_coded, 1, size, desc_mode);
2041
0
      if (p->b_presentation_core_channel_coded) {
2042
0
        GF_AC4_SSS(bs, p->dsi_presentation_channel_mode_core, 2, size, desc_mode);
2043
0
      }
2044
0
    }
2045
0
    GF_AC4_SSS(bs, p->b_presentation_filter, 1, size, desc_mode);
2046
0
    if (p->b_presentation_filter) {
2047
0
      GF_AC4_SSS(bs, p->b_enable_presentation, 1, size, desc_mode);
2048
0
      GF_AC4_SSS(bs, p->n_filter_bytes, 8, size, desc_mode);
2049
0
      for (i = 0; i < p->n_filter_bytes; i++) {
2050
0
        GF_AC4_SSS(bs, zero_val, 8, size, desc_mode); // filter_data
2051
0
      }
2052
0
    }
2053
    // calloc memory for substream_groups
2054
0
    if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2055
0
      p->substream_groups = gf_list_new();
2056
0
    }
2057
2058
0
    if (p->presentation_config == 0x1f) {
2059
0
      if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2060
0
        GF_SAFEALLOC(g, GF_AC4SubStreamGroupV1);
2061
0
        gf_list_add(p->substream_groups, g);
2062
0
        p->n_substream_groups = 1;
2063
0
      } else { // write or get_size
2064
0
        g = (GF_AC4SubStreamGroupV1*)gf_list_get(p->substream_groups, 0);
2065
0
      }
2066
0
      if (g)
2067
0
        gf_odf_ac4_cfg_substream_group_dsi(g, bs, size, desc_mode);
2068
0
    }
2069
0
    else {
2070
0
      GF_AC4_SSS(bs, p->b_multi_pid, 1, size, desc_mode);
2071
0
      if (p->presentation_config >= 0 && p->presentation_config <= 2) {
2072
0
        p->n_substream_groups = 2;
2073
0
      }
2074
0
      if (p->presentation_config == 3 || p->presentation_config == 4) {
2075
0
        p->n_substream_groups = 3;
2076
0
      }
2077
2078
0
      if (p->presentation_config == 5) {
2079
        // n_substream_groups_minus2
2080
0
        if (desc_mode == GF_AC4_DESCMODE_PARSE)
2081
0
          p->n_substream_groups = gf_bs_read_int(bs, 3) + 2;
2082
0
        else if (desc_mode == GF_AC4_DESCMODE_WRITE)
2083
0
          gf_bs_write_int(bs, p->n_substream_groups - 2, 3);
2084
0
        else if(desc_mode == GF_AC4_DESCMODE_GETSIZE)
2085
0
          *size += 3;
2086
0
      }
2087
2088
0
      for (i = 0; i < p->n_substream_groups; i++) {
2089
0
        if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2090
0
          GF_SAFEALLOC(g, GF_AC4SubStreamGroupV1);
2091
0
          gf_list_add(p->substream_groups, g);
2092
0
        } else { // write or get_size
2093
0
          g = (GF_AC4SubStreamGroupV1*)gf_list_get(p->substream_groups, i);
2094
0
        }
2095
0
        gf_odf_ac4_cfg_substream_group_dsi(g, bs, size, desc_mode);
2096
0
      }
2097
2098
0
      if (p->presentation_config > 5) {
2099
0
        GF_AC4_SSS(bs, p->n_skip_bytes, 7, size, desc_mode);
2100
0
        for (i = 0; i < p->n_skip_bytes; i++) {
2101
0
          GF_AC4_SSS(bs, zero_val, 8, size, desc_mode); // skip_data
2102
0
        }
2103
0
      }
2104
0
    }
2105
0
    GF_AC4_SSS(bs, p->b_pre_virtualized, 1, size, desc_mode);
2106
0
    GF_AC4_SSS(bs, p->b_add_emdf_substreams, 1, size, desc_mode);
2107
0
  }
2108
0
  if (p->b_add_emdf_substreams) {
2109
0
    GF_AC4_SSS(bs, p->n_add_emdf_substreams, 7, size, desc_mode);
2110
0
    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++) {
2111
0
      GF_AC4_SSS(bs, p->substream_emdf_version[i], 5, size, desc_mode);
2112
0
      GF_AC4_SSS(bs, p->substream_key_id[i], 10, size, desc_mode);
2113
0
    }
2114
0
  }
2115
0
  GF_AC4_SSS(bs, p->b_presentation_bitrate_info, 1, size, desc_mode);
2116
0
  if (p->b_presentation_bitrate_info) {
2117
0
    gf_odf_ac4_cfg_bitrate_dsi(&(p->ac4_bitrate_dsi), bs, size, desc_mode);
2118
0
  }
2119
0
  GF_AC4_SSS(bs, p->b_alternative, 1, size, desc_mode);
2120
0
  if (p->b_alternative) {
2121
0
    GF_AC4_ALLIGN(bs, size, desc_mode);
2122
0
    gf_odf_ac4_cfg_alternative_info(&(p->alternative_info), bs, size, desc_mode);
2123
0
  }
2124
0
  GF_AC4_ALLIGN(bs, size, desc_mode);
2125
   /*
2126
   * TODO: Not implement, need the information from ac4_substream.
2127
   * Currently just set the value to 1 according to Dolby's internal discussion.
2128
   */
2129
0
  p->de_indicator = 1;
2130
0
  GF_AC4_SSS(bs, p->de_indicator, 1, size, desc_mode);
2131
0
  GF_AC4_SSS(bs, p->dolby_atmos_indicator, 1, size, desc_mode);
2132
0
  GF_AC4_SSS(bs, zero_val, 4, size, desc_mode);
2133
2134
0
  if (p->presentation_id > 31) {
2135
0
    p->b_extended_presentation_id = 1;
2136
0
    p->extended_presentation_id = p->presentation_id;
2137
0
  }
2138
0
  GF_AC4_SSS(bs, p->b_extended_presentation_id, 1, size, desc_mode);
2139
0
  if (p->b_extended_presentation_id) {
2140
0
    GF_AC4_SSS(bs, p->extended_presentation_id, 9, size, desc_mode);
2141
0
  }
2142
0
  else {
2143
0
    GF_AC4_SSS(bs, zero_val, 1, size, desc_mode);
2144
0
  }
2145
2146
0
  return GF_OK;
2147
0
}
2148
2149
static void gf_odf_ac4_presentation_deep_copy(GF_AC4PresentationV1 *pres_dst, GF_AC4PresentationV1 *pres_src);
2150
2151
GF_Err gf_odf_ac4_cfg_dsi_v1(GF_AC4StreamInfo *dsi, GF_BitStream *bs, u64 *size, u8 desc_mode)
2152
0
{
2153
0
  u32 i, j, add_pres_bytes, presentation_bytes, skip_bytes, ims_pres_num = 0, legacy_pres_num = 0;
2154
0
  u32 pres_bytes = 0, t_size_bytes = 0;
2155
0
  GF_AC4PresentationV1* p = NULL, *imsp = NULL;
2156
0
  u64 pos, t_size_bits = 0;
2157
0
  u8 *t_data = NULL;
2158
0
  GF_BitStream *t_bs;
2159
2160
0
  if (!dsi)
2161
0
    return GF_BAD_PARAM;
2162
2163
0
  GF_AC4_SSS(bs, dsi->ac4_dsi_version, 3, size, desc_mode);
2164
0
  GF_AC4_SSS(bs, dsi->bitstream_version, 7, size, desc_mode);
2165
0
  GF_AC4_SSS(bs, dsi->fs_index, 1, size, desc_mode);
2166
0
  GF_AC4_SSS(bs, dsi->frame_rate_index, 4, size, desc_mode);
2167
2168
0
  if (desc_mode == GF_AC4_DESCMODE_WRITE) {
2169
    // check whether legacy presentations are added in the presentations
2170
0
    for (i = 0; i < dsi->n_presentations; i++) {
2171
0
      p = gf_list_get(dsi->presentations, i);
2172
0
      if (!p) continue;
2173
0
      if (p->presentation_version == 1) {
2174
0
        legacy_pres_num += 1;
2175
0
      } else if (p->presentation_version == 2) {
2176
0
        ims_pres_num += 1;
2177
0
      }
2178
0
    }
2179
2180
    // In WRITE mode, modify n_presentations for IMS content and add legacy presentations
2181
    // For more information, please read Dolby AC-4 Online Delivery Kit - Signaling immersive stereo content
2182
0
    if (legacy_pres_num == 0 && ims_pres_num > 0) {
2183
0
      GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("[AC4] This is a Dolby AC-4 bitstreams signal immersive stereo content.\n"));
2184
2185
0
      for (i = 0; i < dsi->n_presentations; i++) {
2186
0
        p = gf_list_get(dsi->presentations, i);
2187
0
        if (!p) continue;
2188
0
        if (p->presentation_version == 2) {
2189
0
          GF_SAFEALLOC(imsp, GF_AC4PresentationV1);
2190
0
          gf_odf_ac4_presentation_deep_copy(imsp, p);
2191
2192
0
          imsp->presentation_version = 1;
2193
0
          imsp->b_pre_virtualized = 0;
2194
0
          imsp->dolby_atmos_indicator = 0;
2195
0
          gf_list_add(dsi->presentations, imsp);
2196
0
        }
2197
0
      }
2198
0
      dsi->n_presentations += ims_pres_num;
2199
0
    }
2200
0
  }
2201
2202
0
  GF_AC4_SSS(bs, dsi->n_presentations, 9, size, desc_mode);
2203
0
  if (dsi->bitstream_version > 1) {
2204
0
    GF_AC4_SSS(bs, dsi->b_program_id, 1, size, desc_mode);
2205
0
    if (dsi->b_program_id) {
2206
0
      GF_AC4_SSS(bs, dsi->short_program_id, 16, size, desc_mode);
2207
0
      GF_AC4_SSS(bs, dsi->b_uuid, 1, size, desc_mode);
2208
0
      if (dsi->b_uuid) {
2209
0
        for (i = 0; i < 16; i++)
2210
0
          GF_AC4_SSS(bs, dsi->program_uuid[i], 8, size, desc_mode);
2211
0
      }
2212
0
    }
2213
0
  }
2214
2215
  // ac4_bitrate_dsi
2216
0
  gf_odf_ac4_cfg_bitrate_dsi(&dsi->ac4_bitrate_dsi, bs, size, desc_mode);
2217
0
  GF_AC4_ALLIGN(bs, size, desc_mode);
2218
2219
0
  if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2220
0
    dsi->presentations = gf_list_new();
2221
0
  }
2222
2223
0
  for (i = 0; i < dsi->n_presentations; i++) {
2224
0
    if (desc_mode == GF_AC4_DESCMODE_PARSE) {
2225
0
      GF_SAFEALLOC(p, GF_AC4PresentationV1);
2226
0
      gf_list_add(dsi->presentations, p);
2227
2228
0
      p->presentation_version = gf_bs_read_int(bs, 8);
2229
0
      pres_bytes = gf_bs_read_int(bs, 8);
2230
0
      if (pres_bytes == 255) {
2231
0
        add_pres_bytes = gf_bs_read_int(bs, 16);
2232
0
        pres_bytes += add_pres_bytes;
2233
0
      }
2234
2235
0
      pos = gf_bs_get_position(bs);
2236
2237
0
      if (p->presentation_version == 0) {
2238
0
        GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support presentation_version 0.\n"));
2239
0
      } else if (p->presentation_version == 1) {
2240
0
        gf_odf_ac4_cfg_presentation_v1_dsi(p, bs, size, desc_mode);
2241
0
      } else if (p->presentation_version == 2) {
2242
0
        gf_odf_ac4_cfg_presentation_v1_dsi(p, bs, size, desc_mode);
2243
0
      }
2244
2245
0
      presentation_bytes = (u32) (gf_bs_get_position(bs) - pos);
2246
0
      skip_bytes = pres_bytes - presentation_bytes;
2247
2248
0
      for (j = 0; j < skip_bytes && gf_bs_available(bs); j++) {
2249
0
        gf_bs_read_int(bs, 8);
2250
0
      }
2251
0
    }
2252
0
    else if (desc_mode == GF_AC4_DESCMODE_WRITE) {
2253
0
      p = gf_list_get(dsi->presentations, i);
2254
0
      if (!p) continue;
2255
2256
0
      t_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
2257
0
      if (p->presentation_version == 0) {
2258
0
        GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support presentation_version 0.\n"));
2259
0
      } else if (p->presentation_version == 1 || p->presentation_version == 2) {
2260
0
        gf_odf_ac4_cfg_presentation_v1_dsi(p, t_bs, size, desc_mode);
2261
0
      }
2262
2263
      // write into output bitstream
2264
0
      gf_bs_write_int(bs, p->presentation_version, 8);
2265
0
      presentation_bytes = (u32) gf_bs_get_position(t_bs);
2266
0
      if (presentation_bytes < 255) {
2267
0
        gf_bs_write_int(bs, presentation_bytes, 8);
2268
0
      } else {
2269
0
        gf_bs_write_int(bs, 255, 8);
2270
0
        gf_bs_write_int(bs, presentation_bytes - 255, 16);
2271
0
      }
2272
0
      gf_bs_get_content(t_bs, &t_data, &t_size_bytes);
2273
0
      gf_bs_write_data(bs, t_data, t_size_bytes);
2274
2275
0
      gf_bs_del(t_bs);
2276
0
      gf_free(t_data);
2277
0
    }
2278
0
    else if (desc_mode == GF_AC4_DESCMODE_GETSIZE) {
2279
0
      p = gf_list_get(dsi->presentations, i);
2280
2281
0
      t_size_bits = 0; // t_size in bits
2282
0
      if (p->presentation_version == 0) {
2283
0
        GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support presentation_version 0.\n"));
2284
0
        return GF_OK;
2285
0
      } else if (p->presentation_version == 1 || p->presentation_version == 2) {
2286
0
        gf_odf_ac4_cfg_presentation_v1_dsi(p, bs, &t_size_bits, desc_mode);
2287
0
      }
2288
2289
0
      if (t_size_bits < 255 * 8) {
2290
0
        *size += (8 + 8 + t_size_bits);
2291
0
      } else {
2292
0
        *size += (8 + 8 + 16 + t_size_bits);
2293
0
      }
2294
0
    }
2295
0
  }
2296
2297
0
  return GF_OK;
2298
0
}
2299
2300
GF_EXPORT
2301
GF_Err gf_odf_ac4_cfg_write_bs(GF_AC4Config *cfg, GF_BitStream *bs)
2302
0
{
2303
0
  if (!cfg || !bs) return GF_BAD_PARAM;
2304
0
  GF_AC4StreamInfo* dsi = &cfg->stream;
2305
0
  if (dsi->ac4_dsi_version == 0) {
2306
0
    GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support ac4_dsi_version 0.\n"));
2307
0
    return GF_OK;
2308
0
  }
2309
0
  GF_Err e = gf_odf_ac4_cfg_dsi_v1(dsi, bs, NULL, GF_AC4_DESCMODE_WRITE);
2310
0
  return e;
2311
0
}
2312
2313
GF_EXPORT
2314
GF_Err gf_odf_ac4_cfg_write(GF_AC4Config *cfg, u8 **data, u32 *size)
2315
0
{
2316
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
2317
0
  GF_Err e = gf_odf_ac4_cfg_write_bs(cfg, bs);
2318
0
  gf_bs_get_content(bs, data, size);
2319
0
  gf_bs_del(bs);
2320
0
  return e;
2321
0
}
2322
2323
GF_EXPORT
2324
GF_Err gf_odf_ac4_cfg_parse_bs(GF_BitStream *bs, GF_AC4Config *cfg)
2325
0
{
2326
0
  GF_AC4StreamInfo* dsi = &cfg->stream;
2327
0
  u64 pos = gf_bs_get_position(bs);
2328
0
  dsi->ac4_dsi_version = gf_bs_read_int(bs, 3);
2329
0
  if (dsi->ac4_dsi_version == 0) {
2330
0
    GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support ac4_dsi_version 0.\n"));
2331
0
    return GF_OK;
2332
0
  }
2333
0
  gf_bs_seek(bs, pos);
2334
0
  GF_Err e = gf_odf_ac4_cfg_dsi_v1(dsi, bs, NULL, GF_AC4_DESCMODE_PARSE);
2335
0
  if (e) return e;
2336
0
  cfg->sample_rate = dsi->fs_index ? 48000 : 44100;
2337
0
  return e;
2338
0
}
2339
2340
GF_EXPORT
2341
GF_Err gf_odf_ac4_cfg_parse(u8 *dsi, u32 dsi_len, GF_AC4Config *cfg)
2342
0
{
2343
0
  GF_BitStream *bs;
2344
0
  GF_Err e;
2345
0
  if (!cfg || !dsi) return GF_BAD_PARAM;
2346
0
  bs = gf_bs_new(dsi, dsi_len, GF_BITSTREAM_READ);
2347
0
  e = gf_odf_ac4_cfg_parse_bs(bs, cfg);
2348
0
  gf_bs_del(bs);
2349
0
  return e;
2350
0
}
2351
2352
GF_EXPORT
2353
u64 gf_odf_ac4_cfg_size(GF_AC4Config *cfg)
2354
0
{
2355
0
  GF_AC4StreamInfo* dsi = &cfg->stream;
2356
0
  u64 size = 0;
2357
0
  if (dsi->ac4_dsi_version == 0) {
2358
0
    GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[AC4] Don't support ac4_dsi_version 0.\n"));
2359
0
    return 0;
2360
0
  } else {
2361
0
    gf_odf_ac4_cfg_dsi_v1(dsi, NULL, &size, GF_AC4_DESCMODE_GETSIZE);
2362
0
  }
2363
0
  return size / 8;
2364
0
}
2365
2366
GF_EXPORT
2367
void gf_odf_ac4_cfg_deep_copy(GF_AC4Config *dst, GF_AC4Config *src)
2368
0
{
2369
0
  u32 i;
2370
0
  GF_List *presentations_src = src->stream.presentations;
2371
0
  GF_AC4PresentationV1 *pres_dst, *pres_src;
2372
2373
0
  if (!dst || !src) {
2374
0
    return;
2375
0
  }
2376
2377
0
  memcpy(dst, src, sizeof(GF_AC4Config));
2378
2379
0
  if (!src->stream.presentations) {
2380
0
    return;
2381
0
  }
2382
2383
0
  dst->stream.presentations = gf_list_new();
2384
0
  for (i = 0; i < gf_list_count(presentations_src); i++) {
2385
0
    pres_src = gf_list_get(presentations_src, i);
2386
2387
0
    GF_SAFEALLOC(pres_dst, GF_AC4PresentationV1);
2388
0
    gf_odf_ac4_presentation_deep_copy(pres_dst, pres_src);
2389
0
    gf_list_add(dst->stream.presentations, pres_dst);
2390
0
  }
2391
0
}
2392
2393
static void gf_odf_ac4_presentation_deep_copy(GF_AC4PresentationV1 *pres_dst, GF_AC4PresentationV1 *pres_src)
2394
0
{
2395
0
  u32 j, s;
2396
0
  GF_AC4SubStreamGroupV1 *group_dst, *group_src;
2397
0
  GF_AC4SubStream *subs_dst, *subs_src;
2398
2399
0
  if (!pres_dst || !pres_src) {
2400
0
    return;
2401
0
  }
2402
2403
0
  memcpy(pres_dst, pres_src, sizeof(GF_AC4PresentationV1));
2404
2405
0
  if (!pres_src->substream_groups) {
2406
0
    return;
2407
0
  }
2408
2409
0
  pres_dst->substream_groups = gf_list_new();
2410
0
  for (j = 0; j < gf_list_count(pres_src->substream_groups); j++) {
2411
0
    group_src = gf_list_get(pres_src->substream_groups, j);
2412
2413
0
    GF_SAFEALLOC(group_dst, GF_AC4SubStreamGroupV1);
2414
0
    memcpy(group_dst, group_src, sizeof(GF_AC4SubStreamGroupV1));
2415
0
    gf_list_add(pres_dst->substream_groups, group_dst);
2416
2417
0
    if (!group_src->substreams) {
2418
0
      continue;
2419
0
    }
2420
2421
0
    group_dst->substreams = gf_list_new();
2422
0
    for (s = 0; s < gf_list_count(group_src->substreams); s++) {
2423
0
      subs_src = gf_list_get(group_src->substreams, s);
2424
2425
0
      GF_SAFEALLOC(subs_dst, GF_AC4SubStream);
2426
0
      memcpy(subs_dst, subs_src, sizeof(GF_AC4SubStream));
2427
0
      gf_list_add(group_dst->substreams, subs_dst);
2428
0
    }
2429
0
  }
2430
0
}
2431
2432
GF_EXPORT
2433
void gf_odf_ac4_cfg_clean_list(GF_AC4Config *cfg)
2434
0
{
2435
0
  u32 s;
2436
0
  GF_AC4PresentationV1 *pres;
2437
0
  GF_AC4SubStreamGroupV1 *group;
2438
0
  GF_AC4SubStream *subs;
2439
2440
0
  if (!cfg)
2441
0
    return;
2442
2443
2444
0
  if (cfg->stream.presentations) {
2445
2446
0
    GF_List* groups_to_del = gf_list_new();
2447
2448
0
    while ( (pres = gf_list_pop_back(cfg->stream.presentations)) ) {
2449
2450
0
      if (pres->substream_groups) {
2451
2452
0
        while ( (group = gf_list_pop_back(pres->substream_groups)) ) {
2453
2454
0
          if (group && gf_list_find(groups_to_del, group) < 0)
2455
0
            gf_list_add(groups_to_del, group);
2456
2457
0
        }
2458
0
        gf_list_del(pres->substream_groups);
2459
2460
0
      }
2461
0
      gf_free(pres);
2462
0
    }
2463
2464
0
    while ( (group = gf_list_pop_back(groups_to_del)) ) {
2465
0
      if (group->substreams) {
2466
2467
0
        for (s = 0; s < gf_list_count(group->substreams); s++) {
2468
0
          subs = gf_list_get(group->substreams, s);
2469
0
          if (!subs) {
2470
0
            continue;
2471
0
          }
2472
2473
0
          gf_free(subs);
2474
0
        }
2475
0
        gf_list_del(group->substreams);
2476
2477
0
      }
2478
0
      gf_free(group);
2479
2480
0
    }
2481
0
    gf_list_del(groups_to_del);
2482
2483
0
    gf_list_del(cfg->stream.presentations);
2484
0
    cfg->stream.presentations = NULL;
2485
0
  }
2486
0
}
2487
2488
GF_EXPORT
2489
void gf_odf_ac4_cfg_del(GF_AC4Config *cfg)
2490
0
{
2491
0
  if (!cfg) return;
2492
0
  gf_odf_ac4_cfg_clean_list(cfg);
2493
0
  gf_free(cfg);
2494
0
}
2495
2496
GF_EXPORT
2497
GF_Err gf_odf_opus_cfg_parse_bs(GF_BitStream *bs, GF_OpusConfig *cfg)
2498
0
{
2499
0
  memset(cfg, 0, sizeof(GF_OpusConfig));
2500
0
  cfg->version = gf_bs_read_u8(bs);
2501
0
  cfg->OutputChannelCount = gf_bs_read_u8(bs);
2502
0
  cfg->PreSkip = gf_bs_read_u16_le(bs);
2503
0
  cfg->InputSampleRate = gf_bs_read_u32_le(bs);
2504
0
  cfg->OutputGain = gf_bs_read_u16_le(bs);
2505
0
  cfg->ChannelMappingFamily = gf_bs_read_u8(bs);
2506
0
  if (cfg->ChannelMappingFamily) {
2507
0
    cfg->StreamCount = gf_bs_read_u8(bs);
2508
0
    cfg->CoupledCount = gf_bs_read_u8(bs);
2509
0
    gf_bs_read_data(bs, (char *) cfg->ChannelMapping, cfg->OutputChannelCount);
2510
0
  }
2511
0
  return GF_OK;
2512
0
}
2513
2514
GF_EXPORT
2515
GF_Err gf_odf_opus_cfg_parse(u8 *dsi, u32 dsi_len, GF_OpusConfig *cfg)
2516
0
{
2517
0
  GF_BitStream *bs;
2518
0
  GF_Err e;
2519
0
  if (!cfg || !dsi) return GF_BAD_PARAM;
2520
0
  bs = gf_bs_new(dsi, dsi_len, GF_BITSTREAM_READ);
2521
0
  e = gf_odf_opus_cfg_parse_bs(bs, cfg);
2522
0
  gf_bs_del(bs);
2523
0
  return e;
2524
0
}
2525
2526
GF_EXPORT
2527
GF_Err gf_odf_opus_cfg_write_bs(GF_OpusConfig *cfg, GF_BitStream *bs)
2528
0
{
2529
0
  if (!cfg || !bs) return GF_BAD_PARAM;
2530
0
  gf_bs_write_u8(bs, cfg->version);
2531
0
  gf_bs_write_u8(bs, cfg->OutputChannelCount);
2532
0
  gf_bs_write_u16_le(bs, cfg->PreSkip);
2533
0
  gf_bs_write_u32_le(bs, cfg->InputSampleRate);
2534
0
  gf_bs_write_u16_le(bs, cfg->OutputGain);
2535
0
  gf_bs_write_u8(bs, cfg->ChannelMappingFamily);
2536
0
  if (cfg->ChannelMappingFamily) {
2537
0
    gf_bs_write_u8(bs, cfg->StreamCount);
2538
0
    gf_bs_write_u8(bs, cfg->CoupledCount);
2539
0
    gf_bs_write_data(bs, (char *) cfg->ChannelMapping, cfg->OutputChannelCount);
2540
0
  }
2541
0
  return GF_OK;
2542
0
}
2543
2544
GF_EXPORT
2545
GF_Err gf_odf_opus_cfg_write(GF_OpusConfig *cfg, u8 **data, u32 *size)
2546
0
{
2547
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
2548
0
  GF_Err e = gf_odf_opus_cfg_write_bs(cfg, bs);
2549
2550
0
  gf_bs_get_content(bs, data, size);
2551
0
  gf_bs_del(bs);
2552
0
  return e;
2553
0
}
2554
2555
GF_EXPORT
2556
GF_IAConfig *gf_odf_iamf_cfg_new()
2557
0
{
2558
0
  GF_IAConfig *cfg = NULL;
2559
0
  GF_SAFEALLOC(cfg, GF_IAConfig);
2560
0
  if (!cfg) return NULL;
2561
0
  cfg->configurationVersion = 1;
2562
0
  cfg->configOBUs_size = 0;
2563
0
  cfg->configOBUs = gf_list_new();
2564
0
  if (!cfg->configOBUs) {
2565
0
    gf_free(cfg);
2566
0
    return NULL;
2567
0
  }
2568
0
  return cfg;
2569
0
}
2570
2571
GF_EXPORT
2572
0
GF_IAConfig *gf_odf_iamf_cfg_read_bs_size(GF_BitStream *bs, u32 size) {
2573
0
#ifndef GPAC_DISABLE_AV_PARSERS
2574
0
  IAMFState *state = NULL;
2575
0
  GF_IAConfig *cfg = NULL;
2576
0
  u8 leb128_size;
2577
2578
0
  if (!size) size = (u32) gf_bs_available(bs);
2579
0
  if (!size) {
2580
0
    GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[IAMF] Unknown IAConfigurationBox size to read\n"));
2581
0
    return NULL;
2582
0
  }
2583
2584
0
  GF_SAFEALLOC(state, IAMFState);
2585
0
  if (!state) return NULL;
2586
0
  cfg = gf_odf_iamf_cfg_new();
2587
0
  gf_iamf_init_state(state);
2588
2589
0
  cfg->configurationVersion = gf_bs_read_u8(bs);
2590
0
  if (cfg->configurationVersion != 1) {
2591
0
    GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[IAMF] Unknown configurationVersion %d\n", cfg->configurationVersion));
2592
0
    gf_odf_iamf_cfg_del(cfg);
2593
0
    gf_free(state);
2594
0
    return NULL;
2595
0
  }
2596
0
  size--;
2597
2598
0
  cfg->configOBUs_size = (u32)gf_av1_leb128_read(bs, &leb128_size);
2599
0
  size -= leb128_size;
2600
2601
0
  while(size) {
2602
0
    u64 pos, obu_size;
2603
0
    IamfObuType obu_type;
2604
0
    GF_IamfObu *config_obu;
2605
2606
0
    pos = gf_bs_get_position(bs);
2607
0
    obu_size = 0;
2608
0
    if (gf_iamf_parse_obu(bs, &obu_type, &obu_size, state) != GF_OK) {
2609
0
      GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[IAMF] could not parse configOBUs at position "LLU". Leaving parsing.\n", pos));
2610
0
      break;
2611
0
    }
2612
0
    gf_assert(obu_size == gf_bs_get_position(bs) - pos);
2613
0
    GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[IAMF] parsed OBU type=%u size="LLU" at position "LLU".\n", obu_type, obu_size, pos));
2614
2615
0
    GF_SAFEALLOC(config_obu, GF_IamfObu);
2616
0
    if (!config_obu) break;
2617
0
    config_obu->raw_obu_bytes = gf_malloc((size_t)obu_size);
2618
0
    if (!config_obu->raw_obu_bytes) {
2619
0
      gf_free(config_obu);
2620
0
      break;
2621
0
    }
2622
0
    gf_bs_seek(bs, pos);
2623
0
    gf_bs_read_data(bs, (char *)config_obu->raw_obu_bytes, (u32)obu_size);
2624
0
    config_obu->obu_length = obu_size;
2625
0
    config_obu->obu_type = obu_type;
2626
0
    gf_list_add(cfg->configOBUs, config_obu);
2627
2628
0
    if (size < obu_size) {
2629
0
      GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[IAMF] IAMF config misses %d bytes to fit the entire OBU\n", obu_size - size));
2630
0
      break;
2631
0
    }
2632
0
    size -= (u32) obu_size;
2633
0
  }
2634
2635
0
  gf_iamf_reset_state(state, GF_TRUE);
2636
0
  gf_bs_align(bs);
2637
0
  gf_free(state);
2638
0
  return cfg;
2639
#else
2640
  return NULL;
2641
#endif
2642
0
}
2643
2644
GF_EXPORT
2645
0
GF_IAConfig *gf_odf_iamf_cfg_read_bs(GF_BitStream *bs) {
2646
0
  return gf_odf_iamf_cfg_read_bs_size(bs, 0);
2647
0
}
2648
2649
GF_EXPORT
2650
GF_IAConfig *gf_odf_iamf_cfg_read(u8 *dsi, u32 dsi_size)
2651
0
{
2652
0
  GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
2653
0
  GF_IAConfig *cfg = gf_odf_iamf_cfg_read_bs(bs);
2654
0
  gf_bs_del(bs);
2655
0
  return cfg;
2656
0
}
2657
2658
GF_EXPORT
2659
void gf_odf_iamf_cfg_del(GF_IAConfig *cfg)
2660
0
{
2661
0
  if (!cfg) return;
2662
0
  while (gf_list_count(cfg->configOBUs)) {
2663
0
    GF_IamfObu *configOBU = (GF_IamfObu*)gf_list_get(cfg->configOBUs, 0);
2664
0
    if (configOBU->raw_obu_bytes) gf_free(configOBU->raw_obu_bytes);
2665
0
    gf_list_rem(cfg->configOBUs, 0);
2666
0
    gf_free(configOBU);
2667
0
  }
2668
0
  gf_list_del(cfg->configOBUs);
2669
0
  gf_free(cfg);
2670
0
}
2671
2672
GF_EXPORT
2673
GF_Err gf_odf_iamf_cfg_write_bs(GF_IAConfig *cfg, GF_BitStream *bs)
2674
0
{
2675
0
  u32 i;
2676
0
  if (!cfg || !bs) return GF_BAD_PARAM;
2677
2678
0
  #ifndef GPAC_DISABLE_AV_PARSERS
2679
0
    gf_bs_write_u8(bs, cfg->configurationVersion);
2680
0
    gf_av1_leb128_write(bs, cfg->configOBUs_size);
2681
0
    for (i = 0; i < gf_list_count(cfg->configOBUs); ++i) {
2682
0
        GF_IamfObu *configOBU = gf_list_get(cfg->configOBUs, i);
2683
0
        gf_bs_write_data(bs, configOBU->raw_obu_bytes, (u32)configOBU->obu_length);
2684
0
    }
2685
0
  #endif
2686
2687
0
  return GF_OK;
2688
0
}
2689
2690
GF_EXPORT
2691
0
GF_Err gf_odf_iamf_cfg_write(GF_IAConfig *cfg, u8 **outData, u32 *outSize) {
2692
0
  GF_Err e;
2693
0
  GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
2694
0
  *outSize = 0;
2695
0
  *outData = NULL;
2696
0
  e = gf_odf_iamf_cfg_write_bs(cfg, bs);
2697
0
  if (e == GF_OK)
2698
0
    gf_bs_get_content(bs, outData, outSize);
2699
2700
0
  gf_bs_del(bs);
2701
0
  return e;
2702
0
}
2703
2704
GF_EXPORT
2705
u32 gf_odf_iamf_cfg_size(GF_IAConfig *cfg)
2706
0
{
2707
0
  if (!cfg) return 0;
2708
2709
0
  #ifndef GPAC_DISABLE_AV_PARSERS
2710
0
    u32 cfg_size = 1; // configurationVersion
2711
0
    cfg_size += gf_av1_leb128_size(cfg->configOBUs_size);
2712
0
    cfg_size += cfg->configOBUs_size;
2713
0
    return cfg_size;
2714
  #else
2715
    return 0;
2716
  #endif
2717
0
}