LCOV - code coverage report
Current view: top level - odf - descriptors.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 681 1013 67.2 %
Date: 2021-04-29 23:48:07 Functions: 49 55 89.1 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2012
       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             : 
      31             : #ifndef GPAC_DISABLE_AV_PARSERS
      32             : #include <gpac/internal/media_dev.h>
      33             : #endif
      34             : 
      35       43714 : s32 gf_odf_size_field_size(u32 size_desc)
      36             : {
      37       62552 :         if (size_desc < 0x00000080) {
      38             :                 return 1 + 1;
      39        1016 :         } else if (size_desc < 0x00004000) {
      40             :                 return 2 + 1;
      41           0 :         } else if (size_desc < 0x00200000) {
      42             :                 return 3 + 1;
      43           0 :         } else if (size_desc < 0x10000000) {
      44             :                 return 4 + 1;
      45             :         } else {
      46           0 :                 return -1;
      47             :         }
      48             : 
      49             : }
      50             : 
      51             : 
      52             : GF_EXPORT
      53       17444 : GF_Err gf_odf_parse_descriptor(GF_BitStream *bs, GF_Descriptor **desc, u32 *desc_size)
      54             : {
      55             :         u32 val, size, sizeHeader;
      56             :         u8 tag;
      57             :         GF_Err err;
      58             :         GF_Descriptor *newDesc;
      59       17444 :         if (!bs) return GF_BAD_PARAM;
      60             : 
      61       17444 :         *desc_size = 0;
      62             : 
      63             :         //tag
      64       17444 :         tag = (u8) gf_bs_read_int(bs, 8);
      65             :         sizeHeader = 1;
      66             : 
      67             :         //size
      68             :         size = 0;
      69             :         do {
      70       17742 :                 val = gf_bs_read_int(bs, 8);
      71       17742 :                 sizeHeader++;
      72       17742 :                 if (sizeHeader > 5) {
      73           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Descriptor size on more than 4 bytes\n"));
      74             :                         return GF_ODF_INVALID_DESCRIPTOR;
      75             :                 }
      76       17742 :                 size <<= 7;
      77       17742 :                 size |= val & 0x7F;
      78       17742 :         } while ( val & 0x80);
      79       17444 :         *desc_size = size;
      80             : 
      81       17444 :         if (gf_bs_available(bs) < size) {
      82           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));
      83             :                 return GF_ODF_INVALID_DESCRIPTOR;
      84             :         }
      85             : 
      86       17444 :         GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[ODF] Reading descriptor (tag %d size %d)\n", tag, size ));
      87             : 
      88       17444 :         newDesc = gf_odf_create_descriptor(tag);
      89       17444 :         if (! newDesc) {
      90           0 :                 *desc = NULL;
      91           0 :                 *desc_size = sizeHeader;
      92           0 :                 if ( (tag >= GF_ODF_ISO_RES_BEGIN_TAG) &&
      93             :                         (tag <= GF_ODF_ISO_RES_END_TAG) ) {
      94             :                         return GF_ODF_FORBIDDEN_DESCRIPTOR;
      95             :                 }
      96           0 :                 else if (!tag || (tag == 0xFF)) {
      97             :                         return GF_ODF_INVALID_DESCRIPTOR;
      98             :                 }
      99             : #ifndef GPAC_MINIMAL_ODF
     100             :                 return GF_OUT_OF_MEM;
     101             : #else
     102           0 :                 gf_bs_skip_bytes(bs, size);
     103           0 :                 *desc_size = size + sizeHeader - gf_odf_size_field_size(*desc_size);
     104           0 :                 return GF_OK;
     105             : #endif
     106             :         }
     107             : 
     108       17444 :         newDesc->tag = tag;
     109       17444 :         err = gf_odf_read_descriptor(bs, newDesc, *desc_size);
     110             : 
     111             :         /*FFMPEG fix*/
     112       17444 :         if ((tag==GF_ODF_SLC_TAG) && (((GF_SLConfig*)newDesc)->predefined==2)) {
     113        3367 :                 if (*desc_size==3) {
     114           0 :                         *desc_size = 1;
     115             :                         err = GF_OK;
     116             :                 }
     117             :         }
     118             : 
     119             :         //little trick to handle lazy bitstreams that encode
     120             :         //SizeOfInstance on a fix number of bytes
     121             :         //This nb of bytes is added in Read methods
     122       34888 :         *desc_size += sizeHeader - gf_odf_size_field_size(*desc_size);
     123       17444 :         *desc = newDesc;
     124       17444 :         if (err) {
     125           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) ));
     126           0 :                 gf_odf_delete_descriptor(newDesc);
     127           0 :                 *desc = NULL;
     128             :         }
     129             :         return err;
     130             : }
     131             : 
     132             : 
     133             : 
     134       50320 : GF_Err gf_odf_delete_descriptor_list(GF_List *descList)
     135             : {
     136             :         GF_Err e;
     137             :         GF_Descriptor*tmp;
     138             :         u32 i;
     139             :         //no error if NULL chain...
     140       50320 :         if (! descList) return GF_OK;
     141       47665 :         i=0;
     142       97501 :         while ((tmp = (GF_Descriptor*)gf_list_enum(descList, &i))) {
     143        2171 :                 e = gf_odf_delete_descriptor(tmp);
     144        2171 :                 if (e) return e;
     145             :         }
     146       47665 :         gf_list_del(descList);
     147       47665 :         return GF_OK;
     148             : }
     149             : 
     150       17082 : GF_Err gf_odf_write_base_descriptor(GF_BitStream *bs, u8 tag, u32 size)
     151             : {
     152             :         u32 length;
     153             :         unsigned char vals[4];
     154             : 
     155       17082 :         if (!tag ) return GF_BAD_PARAM;
     156             : 
     157             :         length = size;
     158       17082 :         vals[3] = (unsigned char) (length & 0x7f);
     159       17082 :         length >>= 7;
     160       17082 :         vals[2] = (unsigned char) ((length & 0x7f) | 0x80);
     161       17082 :         length >>= 7;
     162       17082 :         vals[1] = (unsigned char) ((length & 0x7f) | 0x80);
     163       17082 :         length >>= 7;
     164       17082 :         vals[0] = (unsigned char) ((length & 0x7f) | 0x80);
     165             : 
     166       17082 :         gf_bs_write_int(bs, tag, 8);
     167       17082 :         if (size < 0x00000080) {
     168       16762 :                 gf_bs_write_int(bs, vals[3], 8);
     169         320 :         } else if (size < 0x00004000) {
     170         320 :                 gf_bs_write_int(bs, vals[2], 8);
     171         320 :                 gf_bs_write_int(bs, vals[3], 8);
     172           0 :         } else if (size < 0x00200000) {
     173           0 :                 gf_bs_write_int(bs, vals[1], 8);
     174           0 :                 gf_bs_write_int(bs, vals[2], 8);
     175           0 :                 gf_bs_write_int(bs, vals[3], 8);
     176           0 :         } else if (size < 0x10000000) {
     177           0 :                 gf_bs_write_int(bs, vals[0], 8);
     178           0 :                 gf_bs_write_int(bs, vals[1], 8);
     179           0 :                 gf_bs_write_int(bs, vals[2], 8);
     180           0 :                 gf_bs_write_int(bs, vals[3], 8);
     181             :         } else {
     182             :                 return GF_ODF_INVALID_DESCRIPTOR;
     183             :         }
     184             :         return GF_OK;
     185             : }
     186             : 
     187             : 
     188       47203 : GF_Err gf_odf_size_descriptor_list(GF_List *descList, u32 *outSize)
     189             : {
     190             :         GF_Err e;
     191             :         u32 tmpSize, count, i;
     192       47203 :         if (! descList) return GF_OK;
     193             : 
     194       46836 :         count = gf_list_count(descList);
     195       48386 :         for ( i = 0; i < count; i++ ) {
     196        1550 :                 GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(descList, i);
     197        1550 :                 if (tmp) {
     198        1550 :                         e = gf_odf_size_descriptor(tmp, &tmpSize);
     199        1550 :                         if (e) return e;
     200        2944 :                         if (tmpSize) *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
     201             :                 }
     202             :         }
     203             :         return GF_OK;
     204             : }
     205             : 
     206       21242 : GF_Err gf_odf_write_descriptor_list(GF_BitStream *bs, GF_List *descList)
     207             : {
     208             :         GF_Err e;
     209             :         u32 count, i;
     210             : 
     211       21242 :         if (! descList) return GF_OK;
     212       21092 :         count = gf_list_count(descList);
     213       21905 :         for ( i = 0; i < count; i++ ) {
     214         813 :                 GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(descList, i);
     215         813 :                 if (tmp) {
     216         813 :                         e = gf_odf_write_descriptor(bs, tmp);
     217         813 :                         if (e) return e;
     218             :                 }
     219             :         }
     220             :         return GF_OK;
     221             : }
     222             : 
     223        3510 : GF_Err gf_odf_write_descriptor_list_filter(GF_BitStream *bs, GF_List *descList, u8 only_tag)
     224             : {
     225             :         GF_Err e;
     226             :         u32 count, i;
     227             : 
     228        3510 :         if (! descList) return GF_OK;
     229        3510 :         count = gf_list_count(descList);
     230        3510 :         for ( i = 0; i < count; i++ ) {
     231           0 :                 GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(descList, i);
     232           0 :                 if (tmp && (tmp->tag==only_tag) ) {
     233           0 :                         e = gf_odf_write_descriptor(bs, tmp);
     234           0 :                         if (e) return e;
     235             :                 }
     236             :         }
     237             :         return GF_OK;
     238             : }
     239             : 
     240             : #ifndef GPAC_MINIMAL_ODF
     241             : 
     242             : u32 gf_ipmpx_array_size(GF_BitStream *bs, u32 *array_size)
     243             : {
     244             :         u32 val, size, io_size;
     245             : 
     246             :         io_size = size = 0;
     247             :         do {
     248             :                 val = gf_bs_read_int(bs, 8);
     249             :                 io_size ++;
     250             :                 size <<= 7;
     251             :                 size |= val & 0x7F;
     252             :         } while ( val & 0x80 );
     253             :         *array_size = size;
     254             :         return io_size;
     255             : }
     256             : 
     257             : void gf_ipmpx_write_array(GF_BitStream *bs, u8 *data, u32 data_len)
     258             : {
     259             :         u32 length;
     260             :         unsigned char vals[4];
     261             : 
     262             :         if (!data || !data_len) return;
     263             : 
     264             :         length = data_len;
     265             :         vals[3] = (unsigned char) (length & 0x7f);
     266             :         length >>= 7;
     267             :         vals[2] = (unsigned char) ((length & 0x7f) | 0x80);
     268             :         length >>= 7;
     269             :         vals[1] = (unsigned char) ((length & 0x7f) | 0x80);
     270             :         length >>= 7;
     271             :         vals[0] = (unsigned char) ((length & 0x7f) | 0x80);
     272             : 
     273             :         if (data_len < 0x00000080) {
     274             :                 gf_bs_write_int(bs, vals[3], 8);
     275             :         } else if (data_len < 0x00004000) {
     276             :                 gf_bs_write_int(bs, vals[2], 8);
     277             :                 gf_bs_write_int(bs, vals[3], 8);
     278             :         } else if (data_len < 0x00200000) {
     279             :                 gf_bs_write_int(bs, vals[1], 8);
     280             :                 gf_bs_write_int(bs, vals[2], 8);
     281             :                 gf_bs_write_int(bs, vals[3], 8);
     282             :         } else if (data_len < 0x10000000) {
     283             :                 gf_bs_write_int(bs, vals[0], 8);
     284             :                 gf_bs_write_int(bs, vals[1], 8);
     285             :                 gf_bs_write_int(bs, vals[2], 8);
     286             :                 gf_bs_write_int(bs, vals[3], 8);
     287             :         } else {
     288             :                 return;
     289             :         }
     290             :         gf_bs_write_data(bs, data, data_len);
     291             : }
     292             : 
     293             : 
     294             : #endif /*GPAC_MINIMAL_ODF*/
     295             : 
     296             : /*special authoring functions*/
     297             : GF_EXPORT
     298          16 : GF_BIFSConfig *gf_odf_get_bifs_config(GF_DefaultDescriptor *dsi, u32 oti)
     299             : {
     300             :         Bool hasSize, cmd_stream;
     301             :         GF_BitStream *bs;
     302             :         GF_BIFSConfig *cfg;
     303             : 
     304          16 :         if (oti>=GF_CODECID_BIFS_EXTENDED) return NULL;
     305             : 
     306          16 :         if (!dsi || !dsi->data || !dsi->dataLength ) {
     307             :                 /* Hack for T-DMB non compliant streams (OnTimeTek ?) */
     308           0 :                 cfg = (GF_BIFSConfig *) gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG);
     309           0 :                 cfg->pixelMetrics = GF_TRUE;
     310           0 :                 cfg->version = 1;
     311           0 :                 return cfg;
     312             :         }
     313          16 :         bs = gf_bs_new(dsi->data, dsi->dataLength, GF_BITSTREAM_READ);
     314             : 
     315          16 :         cfg = (GF_BIFSConfig *) gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG);
     316          16 :         if (oti==2) {
     317             :                 /*3D Mesh Coding*/
     318          13 :                 gf_bs_read_int(bs, 1);
     319             :                 /*PMF*/
     320          13 :                 gf_bs_read_int(bs, 1);
     321             :         }
     322          16 :         cfg->nodeIDbits = gf_bs_read_int(bs, 5);
     323          16 :         cfg->routeIDbits = gf_bs_read_int(bs, 5);
     324          16 :         if (oti==2) cfg->protoIDbits = gf_bs_read_int(bs, 5);
     325             : 
     326          16 :         cmd_stream = (Bool)gf_bs_read_int(bs, 1);
     327          16 :         if (!cmd_stream) {
     328           0 :                 cfg->elementaryMasks = gf_list_new();
     329             :                 while (1) {
     330           0 :                         GF_ElementaryMask* em = (GF_ElementaryMask* ) gf_odf_New_ElemMask();
     331           0 :                         em->node_id = gf_bs_read_int(bs, cfg->nodeIDbits);
     332           0 :                         gf_list_add(cfg->elementaryMasks, em);
     333             :                         /*this assumes only FDP, BDP and IFS2D (no elem mask)*/
     334           0 :                         if (gf_bs_read_int(bs, 1) == 0) break;
     335             :                 }
     336           0 :                 gf_bs_align(bs);
     337           0 :                 if (gf_bs_get_size(bs) != gf_bs_get_position(bs)) {
     338           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[ODF] Reading bifs config: shift in sizes (not supported)\n"));
     339             :                 }
     340             :         } else {
     341          16 :                 cfg->pixelMetrics = (Bool)gf_bs_read_int(bs, 1);
     342          16 :                 hasSize = (Bool)gf_bs_read_int(bs, 1);
     343          16 :                 if (hasSize) {
     344          16 :                         cfg->pixelWidth = gf_bs_read_int(bs, 16);
     345          16 :                         cfg->pixelHeight = gf_bs_read_int(bs, 16);
     346             :                 }
     347          16 :                 gf_bs_align(bs);
     348          16 :                 if (gf_bs_get_size(bs) != gf_bs_get_position(bs))
     349           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[ODF] Reading bifs config: shift in sizes (invalid descriptor)\n"));
     350             :         }
     351          16 :         gf_bs_del(bs);
     352          16 :         return cfg;
     353             : }
     354             : 
     355             : /*special function for authoring - convert DSI to LASERConfig*/
     356             : GF_EXPORT
     357           2 : GF_Err gf_odf_get_laser_config(GF_DefaultDescriptor *dsi, GF_LASERConfig *cfg)
     358             : {
     359             :         u32 to_skip;
     360             :         GF_BitStream *bs;
     361             : 
     362           2 :         if (!cfg) return GF_BAD_PARAM;
     363             :         memset(cfg, 0, sizeof(GF_LASERConfig));
     364             : 
     365           2 :         if (!dsi || !dsi->data || !dsi->dataLength) return GF_BAD_PARAM;
     366           2 :         bs = gf_bs_new(dsi->data, dsi->dataLength, GF_BITSTREAM_READ);
     367             :         memset(cfg, 0, sizeof(GF_LASERConfig));
     368           2 :         cfg->tag = GF_ODF_LASER_CFG_TAG;
     369           2 :         cfg->profile = gf_bs_read_int(bs, 8);
     370           2 :         cfg->level = gf_bs_read_int(bs, 8);
     371           2 :         /*cfg->reserved = */gf_bs_read_int(bs, 3);
     372           2 :         cfg->pointsCodec = gf_bs_read_int(bs, 2);
     373           2 :         cfg->pathComponents = gf_bs_read_int(bs, 4);
     374           2 :         cfg->fullRequestHost = gf_bs_read_int(bs, 1);
     375           2 :         if (gf_bs_read_int(bs, 1)) cfg->time_resolution = gf_bs_read_int(bs, 16);
     376           2 :         else cfg->time_resolution = 1000;
     377           2 :         cfg->colorComponentBits = 1 + gf_bs_read_int(bs, 4);
     378           2 :         cfg->resolution = gf_bs_read_int(bs, 4);
     379           2 :         if (cfg->resolution>7) cfg->resolution -= 16;
     380           2 :         cfg->coord_bits = gf_bs_read_int(bs, 5);
     381           2 :         cfg->scale_bits_minus_coord_bits = gf_bs_read_int(bs, 4);
     382           2 :         cfg->newSceneIndicator = gf_bs_read_int(bs, 1);
     383           2 :         /*reserved2*/ gf_bs_read_int(bs, 3);
     384           2 :         cfg->extensionIDBits = gf_bs_read_int(bs, 4);
     385             :         /*hasExtConfig - we just ignore it*/
     386           2 :         if (gf_bs_read_int(bs, 1)) {
     387           0 :                 to_skip = gf_bs_read_vluimsbf5(bs);
     388           0 :                 while (to_skip) {
     389           0 :                         gf_bs_read_int(bs, 8);
     390           0 :                         to_skip--;
     391             :                 }
     392             :         }
     393             :         /*hasExtension - we just ignore it*/
     394           2 :         if (gf_bs_read_int(bs, 1)) {
     395           0 :                 to_skip = gf_bs_read_vluimsbf5(bs);
     396           0 :                 while (to_skip) {
     397           0 :                         gf_bs_read_int(bs, 8);
     398           0 :                         to_skip--;
     399             :                 }
     400             :         }
     401           2 :         gf_bs_del(bs);
     402           2 :         return GF_OK;
     403             : }
     404             : //unused
     405             : #if 0
     406             : GF_Err gf_odf_get_ui_config(GF_DefaultDescriptor *dsi, GF_UIConfig *cfg)
     407             : {
     408             :         u32 len, i;
     409             :         GF_BitStream *bs;
     410             :         if (!dsi || !dsi->data || !dsi->dataLength || !cfg) return GF_BAD_PARAM;
     411             :         memset(cfg, 0, sizeof(GF_UIConfig));
     412             :         cfg->tag = GF_ODF_UI_CFG_TAG;
     413             :         bs = gf_bs_new(dsi->data, dsi->dataLength, GF_BITSTREAM_READ);
     414             :         len = gf_bs_read_int(bs, 8);
     415             :         cfg->deviceName = (char*)gf_malloc(sizeof(char) * (len+1));
     416             :         for (i=0; i<len; i++) cfg->deviceName[i] = gf_bs_read_int(bs, 8);
     417             :         cfg->deviceName[i] = 0;
     418             : 
     419             :         if (!stricmp(cfg->deviceName, "StringSensor") && gf_bs_available(bs)) {
     420             :                 cfg->termChar = gf_bs_read_int(bs, 8);
     421             :                 cfg->delChar = gf_bs_read_int(bs, 8);
     422             :         }
     423             :         gf_bs_del(bs);
     424             :         return GF_OK;
     425             : }
     426             : #endif
     427             : 
     428             : GF_EXPORT
     429          27 : GF_Err gf_odf_encode_ui_config(GF_UIConfig *cfg, GF_DefaultDescriptor **out_dsi)
     430             : {
     431             :         u32 i, len;
     432             :         GF_BitStream *bs;
     433             :         GF_DefaultDescriptor *dsi;
     434          27 :         if (!out_dsi || (cfg->tag != GF_ODF_UI_CFG_TAG)) return GF_BAD_PARAM;
     435             : 
     436          27 :         *out_dsi = NULL;
     437          27 :         if (!cfg->deviceName) return GF_OK;
     438             : 
     439          27 :         bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
     440          27 :         len = (u32) strlen(cfg->deviceName);
     441          27 :         gf_bs_write_int(bs, len, 8);
     442          27 :         for (i=0; i<len; i++) gf_bs_write_int(bs, cfg->deviceName[i], 8);
     443          27 :         if (!stricmp(cfg->deviceName, "StringSensor")) {
     444             :                 /*fixme - this should be UTF-8 chars*/
     445           1 :                 if (cfg->delChar || cfg->termChar) {
     446           0 :                         gf_bs_write_int(bs, cfg->termChar, 8);
     447           0 :                         gf_bs_write_int(bs, cfg->delChar, 8);
     448             :                 }
     449             :         }
     450          27 :         if (cfg->ui_data) gf_bs_write_data(bs, cfg->ui_data, cfg->ui_data_length);
     451             : 
     452          27 :         dsi = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG);
     453          27 :         gf_bs_get_content(bs, &dsi->data, &dsi->dataLength);
     454          27 :         gf_bs_del(bs);
     455          27 :         *out_dsi = dsi;
     456          27 :         return GF_OK;
     457             : }
     458             : 
     459             : 
     460             : GF_EXPORT
     461        5923 : GF_AVCConfig *gf_odf_avc_cfg_new()
     462             : {
     463             :         GF_AVCConfig *cfg;
     464        5923 :         GF_SAFEALLOC(cfg, GF_AVCConfig);
     465        5923 :         if (!cfg) return NULL;
     466        5923 :         cfg->sequenceParameterSets = gf_list_new();
     467        5923 :         cfg->pictureParameterSets = gf_list_new();
     468        5923 :         cfg->AVCLevelIndication = 1;
     469        5923 :         cfg->chroma_format = 1;
     470        5923 :         cfg->chroma_bit_depth = 8;
     471        5923 :         cfg->luma_bit_depth = 8;
     472        5923 :         return cfg;
     473             : }
     474             : 
     475             : GF_EXPORT
     476        5943 : void gf_odf_avc_cfg_del(GF_AVCConfig *cfg)
     477             : {
     478        5943 :         if (!cfg) return;
     479       10799 :         while (gf_list_count(cfg->sequenceParameterSets)) {
     480        4876 :                 GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->sequenceParameterSets, 0);
     481        4876 :                 gf_list_rem(cfg->sequenceParameterSets, 0);
     482        4876 :                 if (sl->data) gf_free(sl->data);
     483        4876 :                 gf_free(sl);
     484             :         }
     485        5923 :         gf_list_del(cfg->sequenceParameterSets);
     486        5923 :         cfg->sequenceParameterSets = NULL;
     487             : 
     488       16727 :         while (gf_list_count(cfg->pictureParameterSets)) {
     489        4881 :                 GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->pictureParameterSets, 0);
     490        4881 :                 gf_list_rem(cfg->pictureParameterSets, 0);
     491        4881 :                 if (sl->data) gf_free(sl->data);
     492        4881 :                 gf_free(sl);
     493             :         }
     494        5923 :         gf_list_del(cfg->pictureParameterSets);
     495        5923 :         cfg->pictureParameterSets = NULL;
     496             : 
     497        5923 :         if (cfg->sequenceParameterSetExtensions) {
     498           0 :                 while (gf_list_count(cfg->sequenceParameterSetExtensions)) {
     499           0 :                         GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->sequenceParameterSetExtensions, 0);
     500           0 :                         gf_list_rem(cfg->sequenceParameterSetExtensions, 0);
     501           0 :                         if (sl->data) gf_free(sl->data);
     502           0 :                         gf_free(sl);
     503             :                 }
     504           0 :                 gf_list_del(cfg->sequenceParameterSetExtensions);
     505           0 :                 cfg->sequenceParameterSetExtensions = NULL;
     506             :         }
     507        5923 :         gf_free(cfg);
     508             : }
     509             : 
     510             : GF_EXPORT
     511        2499 : GF_Err gf_odf_avc_cfg_write_bs(GF_AVCConfig *cfg, GF_BitStream *bs)
     512             : {
     513             :         u32 i, count;
     514             : 
     515        2499 :         if (!cfg) return GF_BAD_PARAM;
     516             : 
     517        2499 :         count = gf_list_count(cfg->sequenceParameterSets);
     518             : 
     519        2499 :         if (!cfg->write_annex_b) {
     520        2499 :                 gf_bs_write_int(bs, cfg->configurationVersion, 8);
     521        2499 :                 gf_bs_write_int(bs, cfg->AVCProfileIndication , 8);
     522        2499 :                 gf_bs_write_int(bs, cfg->profile_compatibility, 8);
     523        2499 :                 gf_bs_write_int(bs, cfg->AVCLevelIndication, 8);
     524        2499 :                 gf_bs_write_int(bs, 0x3F, 6);
     525        2499 :                 gf_bs_write_int(bs, cfg->nal_unit_size - 1, 2);
     526        2499 :                 gf_bs_write_int(bs, 0x7, 3);
     527        2499 :                 gf_bs_write_int(bs, count, 5);
     528             :         }
     529        2620 :         for (i=0; i<count; i++) {
     530        2620 :                 GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->sequenceParameterSets, i);
     531        2620 :                 if (!cfg->write_annex_b) {
     532        2620 :                         gf_bs_write_u16(bs, sl->size);
     533             :                 } else {
     534           0 :                         gf_bs_write_u32(bs, 1);
     535             :                 }
     536        2620 :                 gf_bs_write_data(bs, sl->data, sl->size);
     537             :         }
     538        2499 :         count = gf_list_count(cfg->pictureParameterSets);
     539        2499 :         if (!cfg->write_annex_b) {
     540        2499 :                 gf_bs_write_int(bs, count, 8);
     541             :         }
     542        2340 :         for (i=0; i<count; i++) {
     543        2340 :                 GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(cfg->pictureParameterSets, i);
     544        2340 :                 if (!cfg->write_annex_b) {
     545        2340 :                         gf_bs_write_u16(bs, sl->size);
     546             :                 } else {
     547           0 :                         gf_bs_write_u32(bs, 1);
     548             :                 }
     549        2340 :                 gf_bs_write_data(bs, sl->data, sl->size);
     550             :         }
     551        2499 :         if (gf_avc_is_rext_profile(cfg->AVCProfileIndication)) {
     552        1505 :                 if (!cfg->write_annex_b) {
     553        1505 :                         gf_bs_write_int(bs, 0xFF, 6);
     554        1505 :                         gf_bs_write_int(bs, cfg->chroma_format, 2);
     555        1505 :                         gf_bs_write_int(bs, 0xFF, 5);
     556        1505 :                         gf_bs_write_int(bs, cfg->luma_bit_depth - 8, 3);
     557        1505 :                         gf_bs_write_int(bs, 0xFF, 5);
     558        1505 :                         gf_bs_write_int(bs, cfg->chroma_bit_depth - 8, 3);
     559             :                 }
     560        1505 :                 count = cfg->sequenceParameterSetExtensions ? gf_list_count(cfg->sequenceParameterSetExtensions) : 0;
     561        1505 :                 if (!cfg->write_annex_b) {
     562        1505 :                         gf_bs_write_u8(bs, count);
     563             :                 }
     564           0 :                 for (i=0; i<count; i++) {
     565           0 :                         GF_NALUFFParam *sl = (GF_NALUFFParam *) gf_list_get(cfg->sequenceParameterSetExtensions, i);
     566           0 :                         if (!cfg->write_annex_b) {
     567           0 :                                 gf_bs_write_u16(bs, sl->size);
     568             :                         } else {
     569           0 :                                 gf_bs_write_u32(bs, 1);
     570             :                         }
     571           0 :                         gf_bs_write_data(bs, sl->data, sl->size);
     572             :                 }
     573             :         }
     574             :         return GF_OK;
     575             : }
     576             : 
     577             : GF_EXPORT
     578        2499 : GF_Err gf_odf_avc_cfg_write(GF_AVCConfig *cfg, u8 **outData, u32 *outSize)
     579             : {
     580        2499 :         GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
     581        2499 :         gf_odf_avc_cfg_write_bs(cfg, bs);
     582        2499 :         *outSize = 0;
     583        2499 :         *outData = NULL;
     584        2499 :         gf_bs_get_content(bs, outData, outSize);
     585        2499 :         gf_bs_del(bs);
     586        2499 :         return GF_OK;
     587             : }
     588             : 
     589             : GF_EXPORT
     590         951 : GF_AVCConfig *gf_odf_avc_cfg_read(u8 *dsi, u32 dsi_size)
     591             : {
     592             :         u32 i, count;
     593         951 :         GF_AVCConfig *avcc = gf_odf_avc_cfg_new();
     594         951 :         GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
     595         951 :         avcc->configurationVersion = gf_bs_read_int(bs, 8);
     596         951 :         avcc->AVCProfileIndication  = gf_bs_read_int(bs, 8);
     597         951 :         avcc->profile_compatibility = gf_bs_read_int(bs, 8);
     598         951 :         avcc->AVCLevelIndication  = gf_bs_read_int(bs, 8);
     599         951 :         gf_bs_read_int(bs, 6);
     600         951 :         avcc->nal_unit_size = 1 + gf_bs_read_int(bs, 2);
     601         951 :         gf_bs_read_int(bs, 3);
     602         951 :         count = gf_bs_read_int(bs, 5);
     603        1908 :         for (i=0; i<count; i++) {
     604         957 :                 GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_malloc(sizeof(GF_NALUFFParam));
     605         957 :                 sl->size = gf_bs_read_int(bs, 16);
     606         957 :                 sl->data = (char*)gf_malloc(sizeof(char)*sl->size);
     607         957 :                 gf_bs_read_data(bs, sl->data, sl->size);
     608         957 :                 gf_list_add(avcc->sequenceParameterSets, sl);
     609             :         }
     610         951 :         count = gf_bs_read_int(bs, 8);
     611        1908 :         for (i=0; i<count; i++) {
     612         957 :                 GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_malloc(sizeof(GF_NALUFFParam));
     613         957 :                 sl->size = gf_bs_read_int(bs, 16);
     614         957 :                 sl->data = (char*)gf_malloc(sizeof(char)*sl->size);
     615         957 :                 gf_bs_read_data(bs, sl->data, sl->size);
     616         957 :                 gf_list_add(avcc->pictureParameterSets, sl);
     617             :         }
     618         951 :         if (gf_avc_is_rext_profile(avcc->AVCProfileIndication)) {
     619         501 :                 gf_bs_read_int(bs, 6);
     620         501 :                 avcc->chroma_format = gf_bs_read_int(bs, 2);
     621         501 :                 gf_bs_read_int(bs, 5);
     622         501 :                 avcc->luma_bit_depth = 8 + gf_bs_read_int(bs, 3);
     623         501 :                 gf_bs_read_int(bs, 5);
     624         501 :                 avcc->chroma_bit_depth = 8 + gf_bs_read_int(bs, 3);
     625             : 
     626         501 :                 count = gf_bs_read_int(bs, 8);
     627         501 :                 if (count) {
     628           0 :                         avcc->sequenceParameterSetExtensions = gf_list_new();
     629           0 :                         for (i=0; i<count; i++) {
     630           0 :                                 GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_malloc(sizeof(GF_NALUFFParam));
     631           0 :                                 sl->size = gf_bs_read_u16(bs);
     632           0 :                                 sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
     633           0 :                                 gf_bs_read_data(bs, sl->data, sl->size);
     634           0 :                                 gf_list_add(avcc->sequenceParameterSetExtensions, sl);
     635             :                         }
     636             :                 }
     637             :         }
     638             : 
     639             : 
     640         951 :         gf_bs_del(bs);
     641         951 :         return avcc;
     642             : }
     643             : 
     644             : 
     645         115 : GF_Descriptor *gf_odf_new_tx3g()
     646             : {
     647         115 :         GF_TextSampleDescriptor *newDesc = (GF_TextSampleDescriptor*) gf_malloc(sizeof(GF_TextSampleDescriptor));
     648         115 :         if (!newDesc) return NULL;
     649             :         memset(newDesc, 0, sizeof(GF_TextSampleDescriptor));
     650         115 :         newDesc->tag = GF_ODF_TX3G_TAG;
     651         115 :         return (GF_Descriptor *) newDesc;
     652             : }
     653         115 : GF_Err gf_odf_del_tx3g(GF_TextSampleDescriptor *sd)
     654             : {
     655             :         u32 i;
     656         230 :         for (i=0; i<sd->font_count; i++)
     657         115 :                 if (sd->fonts[i].fontName) gf_free(sd->fonts[i].fontName);
     658         115 :         gf_free(sd->fonts);
     659         115 :         gf_free(sd);
     660         115 :         return GF_OK;
     661             : }
     662             : 
     663             : GF_EXPORT
     664          53 : GF_TextSampleDescriptor *gf_odf_tx3g_read(u8 *dsi, u32 dsi_size)
     665             : {
     666             :         u32 i;
     667             :         u32 gpp_read_rgba(GF_BitStream *bs);
     668             :         void gpp_read_style(GF_BitStream *bs, GF_StyleRecord *rec);
     669             :         void gpp_read_box(GF_BitStream *bs, GF_BoxRecord *rec);
     670             : 
     671          53 :         GF_TextSampleDescriptor *txtc = (GF_TextSampleDescriptor *) gf_odf_new_tx3g();
     672          53 :         GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
     673             : 
     674          53 :         txtc->horiz_justif = gf_bs_read_int(bs, 8);
     675          53 :         txtc->vert_justif  = gf_bs_read_int(bs, 8);
     676          53 :         txtc->back_color = gpp_read_rgba(bs);
     677          53 :         gpp_read_box(bs, &txtc->default_pos);
     678          53 :         gpp_read_style(bs, &txtc->default_style);
     679          53 :         txtc->font_count = gf_bs_read_u16(bs);
     680          53 :         txtc->fonts = gf_malloc(sizeof(GF_FontRecord)*txtc->font_count);
     681         106 :         for (i=0; i<txtc->font_count; i++) {
     682             :                 u8 len;
     683          53 :                 txtc->fonts[i].fontID = gf_bs_read_u16(bs);
     684          53 :                 len = gf_bs_read_u8(bs);
     685          53 :                 txtc->fonts[i].fontName = gf_malloc(sizeof(char)*(len+1));
     686          53 :                 gf_bs_read_data(bs, txtc->fonts[i].fontName, len);
     687          53 :                 txtc->fonts[i].fontName[len] = 0;
     688             :         }
     689          53 :         gf_bs_del(bs);
     690          53 :         return txtc;
     691             : }
     692             : 
     693          69 : GF_Err gf_odf_tx3g_write(GF_TextSampleDescriptor *a, u8 **outData, u32 *outSize)
     694             : {
     695             :         u32 j;
     696             :         void gpp_write_rgba(GF_BitStream *bs, u32 col);
     697             :         void gpp_write_box(GF_BitStream *bs, GF_BoxRecord *rec);
     698             :         void gpp_write_style(GF_BitStream *bs, GF_StyleRecord *rec);
     699          69 :         GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
     700             : 
     701          69 :         gf_bs_write_u8(bs, a->horiz_justif);
     702          69 :         gf_bs_write_u8(bs, a->vert_justif);
     703          69 :         gpp_write_rgba(bs, a->back_color);
     704          69 :         gpp_write_box(bs, &a->default_pos);
     705          69 :         gpp_write_style(bs, &a->default_style);
     706             : 
     707          69 :         gf_bs_write_u16(bs, a->font_count);
     708         138 :         for (j=0; j<a->font_count; j++) {
     709          69 :                 gf_bs_write_u16(bs, a->fonts[j].fontID);
     710          69 :                 if (a->fonts[j].fontName) {
     711          69 :                         u32 len = (u32) strlen(a->fonts[j].fontName);
     712          69 :                         gf_bs_write_u8(bs, len);
     713          69 :                         gf_bs_write_data(bs, a->fonts[j].fontName, len);
     714             :                 } else {
     715           0 :                         gf_bs_write_u8(bs, 0);
     716             :                 }
     717             :         }
     718          69 :         gf_bs_get_content(bs, outData, outSize);
     719          69 :         gf_bs_del(bs);
     720          69 :         return GF_OK;
     721             : }
     722             : 
     723             : /*TextConfig*/
     724          10 : GF_Descriptor *gf_odf_new_text_cfg()
     725             : {
     726          10 :         GF_TextConfig *newDesc = (GF_TextConfig*) gf_malloc(sizeof(GF_TextConfig));
     727          10 :         if (!newDesc) return NULL;
     728             :         memset(newDesc, 0, sizeof(GF_TextConfig));
     729          10 :         newDesc->tag = GF_ODF_TEXT_CFG_TAG;
     730          10 :         newDesc->sample_descriptions = gf_list_new();
     731          10 :         newDesc->Base3GPPFormat = 0x10;
     732          10 :         newDesc->MPEGExtendedFormat = 0x10;
     733          10 :         newDesc->profileLevel = 0x10;
     734          10 :         newDesc->timescale = 1000;
     735          10 :         return (GF_Descriptor *) newDesc;
     736             : }
     737             : 
     738          10 : void ResetTextConfig(GF_TextConfig *desc)
     739             : {
     740             :         GF_List *bck;
     741          28 :         while (gf_list_count(desc->sample_descriptions)) {
     742           8 :                 GF_TextSampleDescriptor *sd = (GF_TextSampleDescriptor *)gf_list_get(desc->sample_descriptions, 0);
     743           8 :                 gf_list_rem(desc->sample_descriptions, 0);
     744           8 :                 gf_odf_del_tx3g(sd);
     745             :         }
     746          10 :         bck = desc->sample_descriptions;
     747             :         memset(desc, 0, sizeof(GF_TextConfig));
     748          10 :         desc->tag = GF_ODF_TEXT_CFG_TAG;
     749          10 :         desc->sample_descriptions = bck;
     750          10 : }
     751             : 
     752          10 : GF_Err gf_odf_del_text_cfg(GF_TextConfig *desc)
     753             : {
     754          10 :         ResetTextConfig(desc);
     755          10 :         gf_list_del(desc->sample_descriptions);
     756          10 :         gf_free(desc);
     757          10 :         return GF_OK;
     758             : }
     759             : 
     760             : /*we need box parsing*/
     761             : #include <gpac/internal/isomedia_dev.h>
     762             : GF_EXPORT
     763           2 : GF_Err gf_odf_get_text_config(u8 *data, u32 data_len, u32 codecid, GF_TextConfig *cfg)
     764             : {
     765             :         u32 i;
     766             :         Bool has_alt_format;
     767             : #ifndef GPAC_DISABLE_ISOM
     768             :         Bool has_sd;
     769             :         u32 j;
     770             : #endif
     771             :         GF_Err e;
     772             :         GF_BitStream *bs;
     773           2 :         if (data || data_len || !cfg) return GF_BAD_PARAM;
     774           1 :         if (codecid != GF_CODECID_TEXT_MPEG4) return GF_NOT_SUPPORTED;
     775             : 
     776             :         /*reset*/
     777           0 :         ResetTextConfig(cfg);
     778           0 :         bs = gf_bs_new(data, data_len, GF_BITSTREAM_READ);
     779             : 
     780             :         e = GF_OK;
     781           0 :         cfg->Base3GPPFormat = gf_bs_read_int(bs, 8);
     782           0 :         cfg->MPEGExtendedFormat = gf_bs_read_int(bs, 8);
     783           0 :         cfg->profileLevel = gf_bs_read_int(bs, 8);
     784           0 :         cfg->timescale = gf_bs_read_int(bs, 24);
     785           0 :         has_alt_format = (Bool)gf_bs_read_int(bs, 1);
     786           0 :         cfg->sampleDescriptionFlags = gf_bs_read_int(bs, 2);
     787             : #ifndef GPAC_DISABLE_ISOM
     788           0 :         has_sd = (Bool)gf_bs_read_int(bs, 1);
     789             : #else
     790             :         gf_bs_read_int(bs, 1);
     791             : #endif
     792           0 :         cfg->has_vid_info = (Bool)gf_bs_read_int(bs, 1);
     793           0 :         gf_bs_read_int(bs, 3);
     794           0 :         cfg->layer = gf_bs_read_int(bs, 8);
     795           0 :         cfg->text_width = gf_bs_read_int(bs, 16);
     796           0 :         cfg->text_height = gf_bs_read_int(bs, 16);
     797           0 :         if (has_alt_format) {
     798           0 :                 cfg->nb_compatible_formats = gf_bs_read_int(bs, 8);
     799           0 :                 for (i=0; i<cfg->nb_compatible_formats; i++) cfg->compatible_formats[i] = gf_bs_read_int(bs, 8);
     800             :         }
     801             : #ifndef GPAC_DISABLE_ISOM
     802           0 :         if (has_sd) {
     803             :                 u8 sample_index;
     804             :                 GF_TextSampleDescriptor *txdesc;
     805             :                 GF_Tx3gSampleEntryBox *a;
     806             :                 s64 avail;
     807           0 :                 u32 nb_desc = gf_bs_read_int(bs, 8);
     808             : 
     809             :                 /*parse TTU[5]s*/
     810           0 :                 avail = (s64) gf_bs_available(bs);
     811           0 :                 for (i=0; i<nb_desc; i++) {
     812           0 :                         sample_index = gf_bs_read_int(bs, 8);
     813           0 :                         avail -= 1;
     814           0 :                         e = gf_isom_box_parse((GF_Box **) &a, bs);
     815           0 :                         if (e) goto exit;
     816           0 :                         avail -= (s32) a->size;
     817             : 
     818           0 :                         if (avail<0) {
     819             :                                 e = GF_NON_COMPLIANT_BITSTREAM;
     820             :                                 goto exit;
     821             :                         }
     822           0 :                         txdesc = (GF_TextSampleDescriptor *)gf_malloc(sizeof(GF_TextSampleDescriptor));
     823           0 :                         txdesc->sample_index = sample_index;
     824           0 :                         txdesc->displayFlags = a->displayFlags;
     825           0 :                         txdesc->back_color = a->back_color;
     826           0 :                         txdesc->default_pos = a->default_box;
     827           0 :                         txdesc->default_style = a->default_style;
     828           0 :                         txdesc->vert_justif = a->vertical_justification;
     829           0 :                         txdesc->horiz_justif = a->horizontal_justification;
     830           0 :                         txdesc->font_count = a->font_table ? a->font_table->entry_count : 0;
     831           0 :                         if (txdesc->font_count) {
     832           0 :                                 txdesc->fonts = (GF_FontRecord*)gf_malloc(sizeof(GF_FontRecord)*txdesc->font_count);
     833           0 :                                 for (j=0; j<txdesc->font_count; j++) {
     834           0 :                                         txdesc->fonts[j].fontID = a->font_table->fonts[j].fontID;
     835           0 :                                         txdesc->fonts[j].fontName = a->font_table->fonts[j].fontName ? gf_strdup(a->font_table->fonts[j].fontName) : NULL;
     836             :                                 }
     837             :                         }
     838           0 :                         gf_list_add(cfg->sample_descriptions, txdesc);
     839           0 :                         gf_isom_box_del((GF_Box *)a);
     840             :                 }
     841             :         }
     842             : #endif
     843             : 
     844           0 :         if (cfg->has_vid_info) {
     845           0 :                 cfg->video_width = gf_bs_read_int(bs, 16);
     846           0 :                 cfg->video_height = gf_bs_read_int(bs, 16);
     847           0 :                 cfg->horiz_offset = gf_bs_read_int(bs, 16);
     848           0 :                 cfg->vert_offset = gf_bs_read_int(bs, 16);
     849             :         }
     850             : 
     851             : #ifndef GPAC_DISABLE_ISOM
     852           0 : exit:
     853             : #endif
     854           0 :         gf_bs_del(bs);
     855           0 :         if (e) ResetTextConfig(cfg);
     856             :         return e;
     857             : }
     858             : 
     859             : 
     860             : 
     861             : GF_EXPORT
     862        3147 : GF_HEVCConfig *gf_odf_hevc_cfg_new()
     863             : {
     864             :         GF_HEVCConfig *cfg;
     865        3147 :         GF_SAFEALLOC(cfg, GF_HEVCConfig);
     866        3147 :         if (!cfg) return NULL;
     867        3147 :         cfg->param_array = gf_list_new();
     868        3147 :         cfg->nal_unit_size = 4;
     869        3147 :         return cfg;
     870             : }
     871             : 
     872             : GF_EXPORT
     873        3147 : void gf_odf_hevc_cfg_del(GF_HEVCConfig *cfg)
     874             : {
     875        3147 :         if (!cfg) return;
     876        9778 :         while (gf_list_count(cfg->param_array)) {
     877        6631 :                 GF_NALUFFParamArray *pa = (GF_NALUFFParamArray*)gf_list_get(cfg->param_array, 0);
     878        6631 :                 gf_list_rem(cfg->param_array, 0);
     879             : 
     880       18863 :                 while (gf_list_count(pa->nalus)) {
     881        5601 :                         GF_NALUFFParam *n = (GF_NALUFFParam*)gf_list_get(pa->nalus, 0);
     882        5601 :                         gf_list_rem(pa->nalus, 0);
     883        5601 :                         if (n->data) gf_free(n->data);
     884        5601 :                         gf_free(n);
     885             :                 }
     886        6631 :                 gf_list_del(pa->nalus);
     887        6631 :                 gf_free(pa);
     888             :         }
     889        3147 :         gf_list_del(cfg->param_array);
     890        3147 :         gf_free(cfg);
     891             : }
     892             : 
     893             : GF_EXPORT
     894        2968 : GF_Err gf_odf_hevc_cfg_write_bs(GF_HEVCConfig *cfg, GF_BitStream *bs)
     895             : {
     896             :         u32 i, count;
     897             : 
     898        2968 :         count = gf_list_count(cfg->param_array);
     899             : 
     900        2968 :         if (!cfg->write_annex_b) {
     901        2967 :                 gf_bs_write_int(bs, cfg->configurationVersion, 8);
     902             : 
     903        2967 :                 if (!cfg->is_lhvc) {
     904        2760 :                         gf_bs_write_int(bs, cfg->profile_space, 2);
     905        2760 :                         gf_bs_write_int(bs, cfg->tier_flag, 1);
     906        2760 :                         gf_bs_write_int(bs, cfg->profile_idc, 5);
     907        2760 :                         gf_bs_write_int(bs, cfg->general_profile_compatibility_flags, 32);
     908        2760 :                         gf_bs_write_int(bs, cfg->progressive_source_flag, 1);
     909        2760 :                         gf_bs_write_int(bs, cfg->interlaced_source_flag, 1);
     910        2760 :                         gf_bs_write_int(bs, cfg->non_packed_constraint_flag, 1);
     911        2760 :                         gf_bs_write_int(bs, cfg->frame_only_constraint_flag, 1);
     912             :                         /*only lowest 44 bits used*/
     913        2760 :                         gf_bs_write_long_int(bs, cfg->constraint_indicator_flags, 44);
     914        2760 :                         gf_bs_write_int(bs, cfg->level_idc, 8);
     915             :                 }
     916             : 
     917        2967 :                 gf_bs_write_int(bs, 0xFF, 4);
     918        2967 :                 gf_bs_write_int(bs, cfg->min_spatial_segmentation_idc, 12);
     919             : 
     920        2967 :                 gf_bs_write_int(bs, 0xFF, 6);
     921        2967 :                 gf_bs_write_int(bs, cfg->parallelismType, 2);
     922             : 
     923        2967 :                 if (!cfg->is_lhvc) {
     924        2760 :                         gf_bs_write_int(bs, 0xFF, 6);
     925        2760 :                         gf_bs_write_int(bs, cfg->chromaFormat, 2);
     926        2760 :                         gf_bs_write_int(bs, 0xFF, 5);
     927        2760 :                         gf_bs_write_int(bs, cfg->luma_bit_depth-8, 3);
     928        2760 :                         gf_bs_write_int(bs, 0xFF, 5);
     929        2760 :                         gf_bs_write_int(bs, cfg->chroma_bit_depth-8, 3);
     930        2760 :                         gf_bs_write_int(bs, cfg->avgFrameRate, 16);
     931             : 
     932        2760 :                         gf_bs_write_int(bs, cfg->constantFrameRate, 2);
     933             :                 } else {
     934         207 :                         gf_bs_write_int(bs, 0xFF, 2);
     935             :                 }
     936             : 
     937        2967 :                 gf_bs_write_int(bs, cfg->numTemporalLayers, 3);
     938        2967 :                 gf_bs_write_int(bs, cfg->temporalIdNested, 1);
     939        2967 :                 gf_bs_write_int(bs, cfg->nal_unit_size - 1, 2);
     940             : 
     941        2967 :                 gf_bs_write_int(bs, count, 8);
     942             :         }
     943             : 
     944        7478 :         for (i=0; i<count; i++) {
     945             :                 u32 nalucount, j;
     946        7478 :                 GF_NALUFFParamArray *ar = (GF_NALUFFParamArray*)gf_list_get(cfg->param_array, i);
     947             : 
     948        7478 :                 nalucount = gf_list_count(ar->nalus);
     949        7478 :                 if (!cfg->write_annex_b) {
     950        7475 :                         gf_bs_write_int(bs, ar->array_completeness, 1);
     951        7475 :                         gf_bs_write_int(bs, 0, 1);
     952        7475 :                         gf_bs_write_int(bs, ar->type, 6);
     953        7475 :                         gf_bs_write_int(bs, nalucount, 16);
     954             :                 }
     955             : 
     956        7520 :                 for (j=0; j<nalucount; j++) {
     957        7520 :                         GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(ar->nalus, j);
     958        7520 :                         if (!cfg->write_annex_b) {
     959        7517 :                                 gf_bs_write_int(bs, sl->size, 16);
     960             :                         } else {
     961           3 :                                 gf_bs_write_u32(bs, 1);
     962             :                         }
     963        7520 :                         gf_bs_write_data(bs, sl->data, sl->size);
     964             :                 }
     965             :         }
     966        2968 :         return GF_OK;
     967             : }
     968             : 
     969             : GF_EXPORT
     970        1292 : GF_Err gf_odf_hevc_cfg_write(GF_HEVCConfig *cfg, u8 **outData, u32 *outSize)
     971             : {
     972             :         GF_Err e;
     973        1292 :         GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
     974        1292 :         *outSize = 0;
     975        1292 :         *outData = NULL;
     976        1292 :         e = gf_odf_hevc_cfg_write_bs(cfg, bs);
     977        1292 :         if (e==GF_OK)
     978        1292 :                 gf_bs_get_content(bs, outData, outSize);
     979             : 
     980        1292 :         gf_bs_del(bs);
     981        1292 :         return e;
     982             : }
     983             : 
     984             : GF_EXPORT
     985        2113 : GF_HEVCConfig *gf_odf_hevc_cfg_read_bs(GF_BitStream *bs, Bool is_lhvc)
     986             : {
     987             :         u32 i, count;
     988        2113 :         GF_HEVCConfig *cfg = gf_odf_hevc_cfg_new();
     989             : 
     990        2113 :         cfg->is_lhvc = is_lhvc;
     991             : 
     992        2113 :         cfg->configurationVersion = gf_bs_read_int(bs, 8);
     993             : 
     994        2113 :         if (!is_lhvc) {
     995        2055 :                 cfg->profile_space = gf_bs_read_int(bs, 2);
     996        2055 :                 cfg->tier_flag = gf_bs_read_int(bs, 1);
     997        2055 :                 cfg->profile_idc = gf_bs_read_int(bs, 5);
     998        2055 :                 cfg->general_profile_compatibility_flags = gf_bs_read_int(bs, 32);
     999             : 
    1000        2055 :                 cfg->progressive_source_flag = gf_bs_read_int(bs, 1);
    1001        2055 :                 cfg->interlaced_source_flag = gf_bs_read_int(bs, 1);
    1002        2055 :                 cfg->non_packed_constraint_flag = gf_bs_read_int(bs, 1);
    1003        2055 :                 cfg->frame_only_constraint_flag = gf_bs_read_int(bs, 1);
    1004             :                 /*only lowest 44 bits used*/
    1005        2055 :                 cfg->constraint_indicator_flags = gf_bs_read_long_int(bs, 44);
    1006        2055 :                 cfg->level_idc = gf_bs_read_int(bs, 8);
    1007             :         }
    1008             : 
    1009        2113 :         gf_bs_read_int(bs, 4); //reserved
    1010        2113 :         cfg->min_spatial_segmentation_idc = gf_bs_read_int(bs, 12);
    1011             : 
    1012        2113 :         gf_bs_read_int(bs, 6);//reserved
    1013        2113 :         cfg->parallelismType = gf_bs_read_int(bs, 2);
    1014             : 
    1015        2113 :         if (!is_lhvc) {
    1016        2055 :                 gf_bs_read_int(bs, 6);
    1017        2055 :                 cfg->chromaFormat = gf_bs_read_int(bs, 2);
    1018        2055 :                 gf_bs_read_int(bs, 5);
    1019        2055 :                 cfg->luma_bit_depth = gf_bs_read_int(bs, 3) + 8;
    1020        2055 :                 gf_bs_read_int(bs, 5);
    1021        2055 :                 cfg->chroma_bit_depth = gf_bs_read_int(bs, 3) + 8;
    1022        2055 :                 cfg->avgFrameRate = gf_bs_read_int(bs, 16);
    1023             : 
    1024        2055 :                 cfg->constantFrameRate = gf_bs_read_int(bs, 2);
    1025             :         } else {
    1026          58 :                 gf_bs_read_int(bs, 2); //reserved
    1027             :         }
    1028             : 
    1029        2113 :         cfg->numTemporalLayers = gf_bs_read_int(bs, 3);
    1030        2113 :         cfg->temporalIdNested = gf_bs_read_int(bs, 1);
    1031             : 
    1032        2113 :         cfg->nal_unit_size = 1 + gf_bs_read_int(bs, 2);
    1033             : 
    1034        2113 :         count = gf_bs_read_int(bs, 8);
    1035        7731 :         for (i=0; i<count; i++) {
    1036             :                 u32 nalucount, j;
    1037             :                 GF_NALUFFParamArray *ar;
    1038        5618 :                 GF_SAFEALLOC(ar, GF_NALUFFParamArray);
    1039        5618 :                 if (!ar) {
    1040           0 :                         gf_odf_hevc_cfg_del(cfg);
    1041           0 :                         return NULL;
    1042             :                 }
    1043        5618 :                 ar->nalus = gf_list_new();
    1044        5618 :                 gf_list_add(cfg->param_array, ar);
    1045             : 
    1046        5618 :                 ar->array_completeness = gf_bs_read_int(bs, 1);
    1047        5618 :                 gf_bs_read_int(bs, 1);
    1048        5618 :                 ar->type = gf_bs_read_int(bs, 6);
    1049        5618 :                 nalucount = gf_bs_read_int(bs, 16);
    1050       11236 :                 for (j=0; j<nalucount; j++) {
    1051             :                         GF_NALUFFParam *sl;
    1052        5618 :                         u32 size = gf_bs_read_int(bs, 16);
    1053        5618 :                         if (size>gf_bs_available(bs)) {
    1054           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Wrong param set size %d\n", size));
    1055           0 :                                 gf_odf_hevc_cfg_del(cfg);
    1056           0 :                                 return NULL;
    1057             :                         }
    1058        5618 :                         GF_SAFEALLOC(sl, GF_NALUFFParam );
    1059        5618 :                         if (!sl) {
    1060           0 :                                 gf_odf_hevc_cfg_del(cfg);
    1061           0 :                                 return NULL;
    1062             :                         }
    1063             : 
    1064        5618 :                         sl->size = size;
    1065        5618 :                         sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
    1066        5618 :                         gf_bs_read_data(bs, sl->data, sl->size);
    1067        5618 :                         gf_list_add(ar->nalus, sl);
    1068             :                 }
    1069             :         }
    1070             :         return cfg;
    1071             : }
    1072             : 
    1073             : GF_EXPORT
    1074         567 : GF_HEVCConfig *gf_odf_hevc_cfg_read(u8 *dsi, u32 dsi_size, Bool is_lhvc)
    1075             : {
    1076         567 :         GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
    1077         567 :         GF_HEVCConfig *cfg = gf_odf_hevc_cfg_read_bs(bs, is_lhvc);
    1078         567 :         gf_bs_del(bs);
    1079         567 :         return cfg;
    1080             : }
    1081             : 
    1082             : GF_EXPORT
    1083           0 : GF_VVCConfig *gf_odf_vvc_cfg_new()
    1084             : {
    1085             :         GF_VVCConfig *cfg;
    1086           0 :         GF_SAFEALLOC(cfg, GF_VVCConfig);
    1087           0 :         if (!cfg) return NULL;
    1088           0 :         cfg->param_array = gf_list_new();
    1089           0 :         cfg->configurationVersion = 1;
    1090           0 :         cfg->nal_unit_size = 4;
    1091           0 :         return cfg;
    1092             : }
    1093             : 
    1094             : GF_EXPORT
    1095           0 : void gf_odf_vvc_cfg_del(GF_VVCConfig *cfg)
    1096             : {
    1097           0 :         if (!cfg) return;
    1098           0 :         while (gf_list_count(cfg->param_array)) {
    1099           0 :                 GF_NALUFFParamArray *pa = (GF_NALUFFParamArray*)gf_list_get(cfg->param_array, 0);
    1100           0 :                 gf_list_rem(cfg->param_array, 0);
    1101             : 
    1102           0 :                 while (gf_list_count(pa->nalus)) {
    1103           0 :                         GF_NALUFFParam *n = (GF_NALUFFParam*)gf_list_get(pa->nalus, 0);
    1104           0 :                         gf_list_rem(pa->nalus, 0);
    1105           0 :                         if (n->data) gf_free(n->data);
    1106           0 :                         gf_free(n);
    1107             :                 }
    1108           0 :                 gf_list_del(pa->nalus);
    1109           0 :                 gf_free(pa);
    1110             :         }
    1111           0 :         gf_list_del(cfg->param_array);
    1112           0 :         if (cfg->general_constraint_info)
    1113           0 :                 gf_free(cfg->general_constraint_info);
    1114           0 :         if (cfg->sub_profiles_idc)
    1115           0 :                 gf_free(cfg->sub_profiles_idc);
    1116           0 :         gf_free(cfg);
    1117             : }
    1118             : 
    1119             : GF_EXPORT
    1120           0 : GF_Err gf_odf_vvc_cfg_write_bs(GF_VVCConfig *cfg, GF_BitStream *bs)
    1121             : {
    1122             :         u32 i, count;
    1123             : 
    1124           0 :         count = gf_list_count(cfg->param_array);
    1125             : 
    1126           0 :         if (!cfg->write_annex_b) {
    1127           0 :                 gf_bs_write_u8(bs, cfg->configurationVersion);
    1128           0 :                 gf_bs_write_u16(bs, cfg->avgFrameRate);
    1129           0 :                 gf_bs_write_int(bs, cfg->constantFrameRate, 2);
    1130           0 :                 gf_bs_write_int(bs, cfg->numTemporalLayers, 3);
    1131           0 :                 gf_bs_write_int(bs, cfg->nal_unit_size - 1, 2);
    1132           0 :                 gf_bs_write_int(bs, cfg->ptl_present, 1);
    1133             : 
    1134           0 :                 if (cfg->ptl_present) {
    1135             :                         s32 idx;
    1136           0 :                         if (!cfg->general_constraint_info)
    1137           0 :                                 cfg->num_constraint_info = 0;
    1138             : 
    1139           0 :                         gf_bs_write_u8(bs, cfg->num_constraint_info);
    1140           0 :                         gf_bs_write_int(bs, cfg->general_profile_idc, 7);
    1141           0 :                         gf_bs_write_int(bs, cfg->general_tier_flag, 1);
    1142           0 :                         gf_bs_write_u8(bs, cfg->general_level_idc);
    1143           0 :                         gf_bs_write_int(bs, cfg->ptl_frame_only_constraint, 1);
    1144           0 :                         gf_bs_write_int(bs, cfg->ptl_multilayer_enabled, 1);
    1145             : 
    1146           0 :                         if (cfg->num_constraint_info) {
    1147           0 :                                 gf_bs_write_data(bs, cfg->general_constraint_info, cfg->num_constraint_info - 1);
    1148           0 :                                 gf_bs_write_int(bs, cfg->general_constraint_info[cfg->num_constraint_info - 1], 6);
    1149             :                         } else {
    1150           0 :                                 gf_bs_write_int(bs, 0, 6);
    1151             :                         }
    1152           0 :                         for (idx=cfg->numTemporalLayers-2; idx>=0; idx--) {
    1153           0 :                                 u8 val = cfg->ptl_sublayer_present_mask & (1<<idx);
    1154           0 :                                 gf_bs_write_int(bs, val, 1);
    1155             :                         }
    1156           0 :                         for (idx=cfg->numTemporalLayers; idx<=8 && cfg->numTemporalLayers>1; idx++) {
    1157           0 :                                 gf_bs_write_int(bs, 0, 1);
    1158             :                         }
    1159           0 :                         for (idx=cfg->numTemporalLayers-2; idx>=0; idx--) {
    1160           0 :                                 if (cfg->ptl_sublayer_present_mask & (1<<idx))
    1161           0 :                                         gf_bs_write_u8(bs, cfg->sublayer_level_idc[idx]);
    1162             :                         }
    1163           0 :                         if (!cfg->sub_profiles_idc) cfg->num_sub_profiles = 0;
    1164           0 :                         gf_bs_write_u8(bs, cfg->num_sub_profiles);
    1165           0 :                         for (idx=0; idx<cfg->num_sub_profiles; idx++) {
    1166           0 :                                 gf_bs_write_u32(bs, cfg->sub_profiles_idc[idx]);
    1167             :                         }
    1168           0 :                         gf_bs_write_int(bs, cfg->ols_idx, 16);
    1169             :                 }
    1170           0 :                 gf_bs_write_int(bs, cfg->chromaformat_plus_one ? 1 : 0, 1);
    1171           0 :                 if (cfg->chromaformat_plus_one)
    1172           0 :                         gf_bs_write_int(bs, cfg->chromaformat_plus_one - 1, 2);
    1173             :                 else
    1174           0 :                         gf_bs_write_int(bs, 0xFF, 2);
    1175             : 
    1176           0 :                 gf_bs_write_int(bs, cfg->bit_depth_plus_one ? 1 : 0, 1);
    1177           0 :                 if (cfg->bit_depth_plus_one)
    1178           0 :                         gf_bs_write_int(bs, cfg->bit_depth_plus_one - 8 - 1, 3);
    1179             :                 else
    1180           0 :                         gf_bs_write_int(bs, 0xFF, 3);
    1181             : 
    1182           0 :                 gf_bs_write_int(bs, 1, 1);
    1183           0 :                 gf_bs_write_int(bs, count, 8);
    1184             :         }
    1185             : 
    1186           0 :         for (i=0; i<count; i++) {
    1187             :                 u32 nalucount, j;
    1188           0 :                 GF_NALUFFParamArray *ar = (GF_NALUFFParamArray*)gf_list_get(cfg->param_array, i);
    1189             : 
    1190           0 :                 nalucount = gf_list_count(ar->nalus);
    1191           0 :                 if (!cfg->write_annex_b) {
    1192           0 :                         gf_bs_write_int(bs, ar->array_completeness, 1);
    1193           0 :                         gf_bs_write_int(bs, 0, 1);
    1194           0 :                         gf_bs_write_int(bs, ar->type, 6);
    1195           0 :                         gf_bs_write_int(bs, nalucount, 16);
    1196             :                 }
    1197             : 
    1198           0 :                 for (j=0; j<nalucount; j++) {
    1199           0 :                         GF_NALUFFParam *sl = (GF_NALUFFParam *)gf_list_get(ar->nalus, j);
    1200           0 :                         if (!cfg->write_annex_b) {
    1201           0 :                                 gf_bs_write_int(bs, sl->size, 16);
    1202             :                         } else {
    1203           0 :                                 gf_bs_write_u32(bs, 1);
    1204             :                         }
    1205           0 :                         gf_bs_write_data(bs, sl->data, sl->size);
    1206             :                 }
    1207             :         }
    1208           0 :         return GF_OK;
    1209             : }
    1210             : 
    1211             : GF_EXPORT
    1212           0 : GF_Err gf_odf_vvc_cfg_write(GF_VVCConfig *cfg, u8 **outData, u32 *outSize)
    1213             : {
    1214             :         GF_Err e;
    1215           0 :         GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
    1216           0 :         *outSize = 0;
    1217           0 :         *outData = NULL;
    1218           0 :         e = gf_odf_vvc_cfg_write_bs(cfg, bs);
    1219           0 :         if (e==GF_OK)
    1220           0 :                 gf_bs_get_content(bs, outData, outSize);
    1221             : 
    1222           0 :         gf_bs_del(bs);
    1223           0 :         return e;
    1224             : }
    1225             : 
    1226             : GF_EXPORT
    1227           0 : GF_VVCConfig *gf_odf_vvc_cfg_read_bs(GF_BitStream *bs)
    1228             : {
    1229             :         u32 i, count;
    1230           0 :         GF_VVCConfig *cfg = gf_odf_vvc_cfg_new();
    1231             : 
    1232           0 :         cfg->configurationVersion = gf_bs_read_u8(bs);
    1233           0 :         cfg->avgFrameRate = gf_bs_read_u16(bs);
    1234           0 :         cfg->constantFrameRate = gf_bs_read_int(bs, 2);
    1235           0 :         cfg->numTemporalLayers = gf_bs_read_int(bs, 3);
    1236           0 :         cfg->nal_unit_size = 1 + gf_bs_read_int(bs, 2);
    1237           0 :         cfg->ptl_present = gf_bs_read_int(bs, 1);
    1238             : 
    1239           0 :         if (cfg->ptl_present) {
    1240             :                 s32 j;
    1241           0 :                 cfg->num_constraint_info = gf_bs_read_u8(bs);
    1242           0 :                 cfg->general_profile_idc = gf_bs_read_int(bs, 7);
    1243           0 :                 cfg->general_tier_flag = gf_bs_read_int(bs, 1);
    1244           0 :                 cfg->general_level_idc = gf_bs_read_u8(bs);
    1245           0 :                 cfg->ptl_frame_only_constraint = gf_bs_read_int(bs, 1);
    1246           0 :                 cfg->ptl_multilayer_enabled = gf_bs_read_int(bs, 1);
    1247             : 
    1248           0 :                 if (cfg->num_constraint_info) {
    1249           0 :                         cfg->general_constraint_info = gf_malloc(sizeof(u8)*cfg->num_constraint_info);
    1250           0 :                         if (!cfg->general_constraint_info) {
    1251           0 :                                 gf_free(cfg);
    1252           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] alloc failed while parsing vvc config\n"));
    1253             :                                 return NULL;
    1254             :                         }
    1255           0 :                         gf_bs_read_data(bs, cfg->general_constraint_info, cfg->num_constraint_info - 1);
    1256           0 :                         cfg->general_constraint_info[cfg->num_constraint_info-1] =  gf_bs_read_int(bs, 6);
    1257             :                 } else {
    1258           0 :                         gf_bs_read_int(bs, 6);
    1259             :                 }
    1260             : 
    1261           0 :                 cfg->ptl_sublayer_present_mask = 0;
    1262           0 :                 for (j=cfg->numTemporalLayers-2; j>=0; j--) {
    1263           0 :                         u8 val = gf_bs_read_int(bs, 1);
    1264           0 :                         cfg->ptl_sublayer_present_mask = val << j;
    1265             :                 }
    1266           0 :                 for (j=cfg->numTemporalLayers; j<=8 && cfg->numTemporalLayers>1; j++) {
    1267           0 :                         gf_bs_read_int(bs, 1);
    1268             :                 }
    1269           0 :                 for (j=cfg->numTemporalLayers-2; j>=0; j--) {
    1270           0 :                         if (cfg->ptl_sublayer_present_mask & (1<<j)) {
    1271           0 :                                 cfg->sublayer_level_idc[j] = gf_bs_read_u8(bs);
    1272             :                         }
    1273             :                 }
    1274           0 :                 cfg->num_sub_profiles = gf_bs_read_u8(bs);
    1275           0 :                 if (cfg->num_sub_profiles) {
    1276           0 :                         cfg->sub_profiles_idc = gf_malloc(sizeof(u32)*cfg->num_sub_profiles);
    1277           0 :                         if (!cfg->sub_profiles_idc) {
    1278           0 :                                 gf_free(cfg->general_constraint_info);
    1279           0 :                                 gf_free(cfg);
    1280           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] alloc failed while parsing vvc config\n"));
    1281             :                                 return NULL;
    1282             :                         }
    1283             :                 }
    1284           0 :                 for (i=0; i<cfg->num_sub_profiles; i++) {
    1285           0 :                         cfg->sub_profiles_idc[i] = gf_bs_read_u32(bs);
    1286             :                 }
    1287           0 :                 cfg->ols_idx = gf_bs_read_u16(bs);
    1288             :         }
    1289             : 
    1290           0 :         if (gf_bs_read_int(bs, 1)) {
    1291           0 :                 cfg->chromaformat_plus_one = 1 + gf_bs_read_int(bs, 2);
    1292             :         } else {
    1293           0 :                 cfg->chromaformat_plus_one = 0;
    1294           0 :                 gf_bs_read_int(bs, 2);
    1295             :         }
    1296             : 
    1297           0 :         if (gf_bs_read_int(bs, 1)) {
    1298           0 :                 cfg->bit_depth_plus_one = 1 + 8 + gf_bs_read_int(bs, 3);
    1299             :         } else {
    1300           0 :                 cfg->bit_depth_plus_one = 0;
    1301           0 :                 gf_bs_read_int(bs, 3);
    1302             :         }
    1303           0 :         gf_bs_read_int(bs, 1);
    1304             : 
    1305           0 :         count = gf_bs_read_int(bs, 8);
    1306           0 :         for (i=0; i<count; i++) {
    1307             :                 u32 nalucount, j;
    1308             :                 GF_NALUFFParamArray *ar;
    1309           0 :                 GF_SAFEALLOC(ar, GF_NALUFFParamArray);
    1310           0 :                 if (!ar) {
    1311           0 :                         gf_odf_vvc_cfg_del(cfg);
    1312           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] alloc failed while parsing vvc config\n"));
    1313             :                         return NULL;
    1314             :                 }
    1315           0 :                 ar->nalus = gf_list_new();
    1316           0 :                 gf_list_add(cfg->param_array, ar);
    1317             : 
    1318           0 :                 ar->array_completeness = gf_bs_read_int(bs, 1);
    1319           0 :                 gf_bs_read_int(bs, 1);
    1320           0 :                 ar->type = gf_bs_read_int(bs, 6);
    1321           0 :                 nalucount = gf_bs_read_int(bs, 16);
    1322           0 :                 for (j=0; j<nalucount; j++) {
    1323             :                         GF_NALUFFParam *sl;
    1324           0 :                         u32 size = gf_bs_read_int(bs, 16);
    1325           0 :                         if (size>gf_bs_available(bs)) {
    1326           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Wrong param set size %d\n", size));
    1327           0 :                                 gf_odf_vvc_cfg_del(cfg);
    1328           0 :                                 return NULL;
    1329             :                         }
    1330           0 :                         GF_SAFEALLOC(sl, GF_NALUFFParam );
    1331           0 :                         if (!sl) {
    1332           0 :                                 gf_odf_vvc_cfg_del(cfg);
    1333           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] alloc failed while parsing vvc config\n"));
    1334             :                                 return NULL;
    1335             :                         }
    1336             : 
    1337           0 :                         sl->size = size;
    1338           0 :                         sl->data = (char *)gf_malloc(sizeof(char) * sl->size);
    1339           0 :                         if (!sl->data) {
    1340           0 :                                 gf_free(sl);
    1341           0 :                                 gf_odf_vvc_cfg_del(cfg);
    1342           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] alloc failed while parsing vvc config\n"));
    1343             :                                 return NULL;
    1344             :                         }
    1345           0 :                         gf_bs_read_data(bs, sl->data, sl->size);
    1346           0 :                         gf_list_add(ar->nalus, sl);
    1347             :                 }
    1348             :         }
    1349             :         return cfg;
    1350             : }
    1351             : 
    1352             : GF_EXPORT
    1353           0 : GF_VVCConfig *gf_odf_vvc_cfg_read(u8 *dsi, u32 dsi_size)
    1354             : {
    1355           0 :         GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
    1356           0 :         GF_VVCConfig *cfg = gf_odf_vvc_cfg_read_bs(bs);
    1357           0 :         gf_bs_del(bs);
    1358           0 :         return cfg;
    1359             : }
    1360             : 
    1361             : GF_EXPORT
    1362        3681 : GF_AV1Config *gf_odf_av1_cfg_new()
    1363             : {
    1364             :         GF_AV1Config *cfg;
    1365        3681 :         GF_SAFEALLOC(cfg, GF_AV1Config);
    1366        3681 :         if (!cfg) return NULL;
    1367        3681 :         cfg->marker = 1;
    1368        3681 :         cfg->version = 1;
    1369        3681 :         cfg->initial_presentation_delay_minus_one = 0;
    1370        3681 :         cfg->obu_array = gf_list_new();
    1371        3681 :         return cfg;
    1372             : }
    1373             : 
    1374             : GF_EXPORT
    1375        4448 : void gf_odf_av1_cfg_del(GF_AV1Config *cfg)
    1376             : {
    1377        4448 :         if (!cfg) return;
    1378        5880 :         while (gf_list_count(cfg->obu_array)) {
    1379        1432 :                 GF_AV1_OBUArrayEntry *a = (GF_AV1_OBUArrayEntry*)gf_list_get(cfg->obu_array, 0);
    1380        1432 :                 if (a->obu) gf_free(a->obu);
    1381        1432 :                 gf_list_rem(cfg->obu_array, 0);
    1382        1432 :                 gf_free(a);
    1383             :         }
    1384        4448 :         gf_list_del(cfg->obu_array);
    1385        4448 :         gf_free(cfg);
    1386             : }
    1387             : 
    1388             : GF_EXPORT
    1389        1178 : GF_Err gf_odf_av1_cfg_write_bs(GF_AV1Config *cfg, GF_BitStream *bs)
    1390             : {
    1391             :         u32 i = 0;
    1392        1178 :         gf_bs_write_int(bs, cfg->marker, 1); assert(cfg->marker == 1);
    1393        1178 :         gf_bs_write_int(bs, cfg->version, 7); assert(cfg->version == 1);
    1394        1178 :         gf_bs_write_int(bs, cfg->seq_profile, 3);
    1395        1178 :         gf_bs_write_int(bs, cfg->seq_level_idx_0, 5);
    1396        1178 :         gf_bs_write_int(bs, cfg->seq_tier_0, 1);
    1397        1178 :         gf_bs_write_int(bs, cfg->high_bitdepth, 1);
    1398        1178 :         gf_bs_write_int(bs, cfg->twelve_bit, 1);
    1399        1178 :         gf_bs_write_int(bs, cfg->monochrome, 1);
    1400        1178 :         gf_bs_write_int(bs, cfg->chroma_subsampling_x, 1);
    1401        1178 :         gf_bs_write_int(bs, cfg->chroma_subsampling_y, 1);
    1402        1178 :         gf_bs_write_int(bs, cfg->chroma_sample_position, 2);
    1403        1178 :         gf_bs_write_int(bs, 0, 3); /*reserved*/
    1404        1178 :         gf_bs_write_int(bs, cfg->initial_presentation_delay_present, 1);
    1405        1178 :         gf_bs_write_int(bs, cfg->initial_presentation_delay_minus_one, 4); /*TODO: compute initial_presentation_delay_minus_one*/
    1406        2356 :         for (i = 0; i < gf_list_count(cfg->obu_array); ++i) {
    1407        1178 :                 GF_AV1_OBUArrayEntry *a = gf_list_get(cfg->obu_array, i);
    1408        1178 :                 gf_bs_write_data(bs, a->obu, (u32)a->obu_length); //TODO: we are supposed to omit the size on the last OBU...
    1409             :         }
    1410        1178 :         return GF_OK;
    1411             : }
    1412             : 
    1413             : GF_EXPORT
    1414         869 : GF_Err gf_odf_av1_cfg_write(GF_AV1Config *cfg, u8 **outData, u32 *outSize) {
    1415             :         GF_Err e;
    1416         869 :         GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
    1417         869 :         *outSize = 0;
    1418         869 :         *outData = NULL;
    1419         869 :         e = gf_odf_av1_cfg_write_bs(cfg, bs);
    1420         869 :         if (e == GF_OK)
    1421         869 :                 gf_bs_get_content(bs, outData, outSize);
    1422             : 
    1423         869 :         gf_bs_del(bs);
    1424         869 :         return e;
    1425             : }
    1426             : 
    1427             : GF_EXPORT
    1428        2287 : GF_VPConfig *gf_odf_vp_cfg_new()
    1429             : {
    1430             :         GF_VPConfig *cfg;
    1431        2287 :         GF_SAFEALLOC(cfg, GF_VPConfig);
    1432        2287 :         if (!cfg) return NULL;
    1433        2287 :         cfg->codec_initdata_size = 0;
    1434        2287 :         cfg->codec_initdata = NULL;
    1435        2287 :         return cfg;
    1436             : }
    1437             : 
    1438             : GF_EXPORT
    1439        2287 : void gf_odf_vp_cfg_del(GF_VPConfig *cfg)
    1440             : {
    1441        2287 :         if (!cfg) return;
    1442             : 
    1443        2287 :         if (cfg->codec_initdata) {
    1444           0 :                 gf_free(cfg->codec_initdata);
    1445           0 :                 cfg->codec_initdata = NULL;
    1446             :         }
    1447             : 
    1448        2287 :         gf_free(cfg);
    1449             : }
    1450             : 
    1451             : GF_EXPORT
    1452        1645 : GF_Err gf_odf_vp_cfg_write_bs(GF_VPConfig *cfg, GF_BitStream *bs, Bool is_v0)
    1453             : {
    1454        1645 :         gf_bs_write_int(bs, cfg->profile, 8);
    1455        1645 :         gf_bs_write_int(bs, cfg->level, 8);
    1456        1645 :         gf_bs_write_int(bs, cfg->bit_depth, 4);
    1457        1645 :         gf_bs_write_int(bs, cfg->chroma_subsampling, 3);
    1458        1645 :         gf_bs_write_int(bs, cfg->video_fullRange_flag, 1);
    1459        1645 :         gf_bs_write_int(bs, cfg->colour_primaries, 8);
    1460        1645 :         gf_bs_write_int(bs, cfg->transfer_characteristics, 8);
    1461        1645 :         gf_bs_write_int(bs, cfg->matrix_coefficients, 8);
    1462             : 
    1463        1645 :         if (!is_v0) {
    1464        1645 :                 if (cfg->codec_initdata_size) {
    1465           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] VP Configuration Box: invalid data, codec_initdata_size must be 0, was %d - ignoring\n", cfg->codec_initdata_size));
    1466             :                 }
    1467             : 
    1468        1645 :                 gf_bs_write_int(bs, (u16)0, 16);
    1469             :         }
    1470             : 
    1471        1645 :         return GF_OK;
    1472             : }
    1473             : 
    1474             : GF_EXPORT
    1475        1590 : GF_Err gf_odf_vp_cfg_write(GF_VPConfig *cfg, u8 **outData, u32 *outSize, Bool is_v0)
    1476             : {
    1477             :         GF_Err e;
    1478        1590 :         GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
    1479        1590 :         *outSize = 0;
    1480        1590 :         *outData = NULL;
    1481        1590 :         e = gf_odf_vp_cfg_write_bs(cfg, bs, is_v0);
    1482        1590 :         if (e==GF_OK)
    1483        1590 :                 gf_bs_get_content(bs, outData, outSize);
    1484             : 
    1485        1590 :         gf_bs_del(bs);
    1486        1590 :         return e;
    1487             : }
    1488             : 
    1489             : GF_EXPORT
    1490         249 : GF_VPConfig *gf_odf_vp_cfg_read_bs(GF_BitStream *bs, Bool is_v0)
    1491             : {
    1492         249 :         GF_VPConfig *cfg = gf_odf_vp_cfg_new();
    1493             : 
    1494         249 :         cfg->profile = gf_bs_read_int(bs, 8);
    1495         249 :         cfg->level = gf_bs_read_int(bs, 8);
    1496             : 
    1497         249 :         cfg->bit_depth = gf_bs_read_int(bs, 4);
    1498         249 :         cfg->chroma_subsampling = gf_bs_read_int(bs, 3);
    1499         249 :         cfg->video_fullRange_flag = gf_bs_read_int(bs, 1);
    1500             : 
    1501         249 :         cfg->colour_primaries = gf_bs_read_int(bs, 8);
    1502         249 :         cfg->transfer_characteristics = gf_bs_read_int(bs, 8);
    1503         249 :         cfg->matrix_coefficients = gf_bs_read_int(bs, 8);
    1504             : 
    1505         249 :         if (is_v0)
    1506             :                 return cfg;
    1507             : 
    1508         249 :         cfg->codec_initdata_size = gf_bs_read_int(bs, 16);
    1509             : 
    1510             :         // must be 0 according to spec
    1511         249 :         if (cfg->codec_initdata_size) {
    1512           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] VP Configuration Box: invalid data, codec_initdata_size must be 0, was %d\n", cfg->codec_initdata_size));
    1513           0 :                 gf_odf_vp_cfg_del(cfg);
    1514           0 :                 return NULL;
    1515             :         }
    1516             : 
    1517             :         return cfg;
    1518             : }
    1519             : 
    1520             : GF_EXPORT
    1521          73 : GF_VPConfig *gf_odf_vp_cfg_read(u8 *dsi, u32 dsi_size)
    1522             : {
    1523          73 :         GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
    1524          73 :         GF_VPConfig *cfg = gf_odf_vp_cfg_read_bs(bs, GF_FALSE);
    1525          73 :         gf_bs_del(bs);
    1526          73 :         return cfg;
    1527             : }
    1528             : 
    1529             : GF_EXPORT
    1530         590 : GF_AV1Config *gf_odf_av1_cfg_read_bs_size(GF_BitStream *bs, u32 size)
    1531             : {
    1532             : #ifndef GPAC_DISABLE_AV_PARSERS
    1533             :         AV1State state;
    1534             :         u8 reserved;
    1535             :         GF_AV1Config *cfg;
    1536             : 
    1537         590 :         if (!size) size = (u32) gf_bs_available(bs);
    1538         590 :         if (!size) return NULL;
    1539             : 
    1540         590 :         cfg = gf_odf_av1_cfg_new();
    1541         590 :         gf_av1_init_state(&state);
    1542         590 :         state.config = cfg;
    1543             : 
    1544         590 :         cfg->marker = gf_bs_read_int(bs, 1);
    1545         590 :         cfg->version = gf_bs_read_int(bs, 7);
    1546         590 :         cfg->seq_profile = gf_bs_read_int(bs, 3);
    1547         590 :         cfg->seq_level_idx_0 = gf_bs_read_int(bs, 5);
    1548         590 :         cfg->seq_tier_0 = gf_bs_read_int(bs, 1);
    1549         590 :         cfg->high_bitdepth = gf_bs_read_int(bs, 1);
    1550         590 :         cfg->twelve_bit = gf_bs_read_int(bs, 1);
    1551         590 :         cfg->monochrome = gf_bs_read_int(bs, 1);
    1552         590 :         cfg->chroma_subsampling_x = gf_bs_read_int(bs, 1);
    1553         590 :         cfg->chroma_subsampling_y = gf_bs_read_int(bs, 1);
    1554         590 :         cfg->chroma_sample_position = gf_bs_read_int(bs, 2);
    1555             : 
    1556         590 :         reserved = gf_bs_read_int(bs, 3);
    1557         590 :         if (reserved != 0 || cfg->marker != 1 || cfg->version != 1) {
    1558           0 :                 GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[AV1] wrong avcC reserved %d / marker %d / version %d expecting 0 1 1\n", reserved, cfg->marker, cfg->version));
    1559           0 :                 gf_odf_av1_cfg_del(cfg);
    1560           0 :                 return NULL;
    1561             :         }
    1562         590 :         cfg->initial_presentation_delay_present = gf_bs_read_int(bs, 1);
    1563         590 :         if (cfg->initial_presentation_delay_present) {
    1564           0 :                 cfg->initial_presentation_delay_minus_one = gf_bs_read_int(bs, 4);
    1565             :         } else {
    1566         590 :                 /*reserved = */gf_bs_read_int(bs, 4);
    1567         590 :                 cfg->initial_presentation_delay_minus_one = 0;
    1568             :         }
    1569         590 :         size -= 4;
    1570             : 
    1571        1770 :         while (size) {
    1572             :                 u64 pos, obu_size;
    1573             :                 ObuType obu_type;
    1574             :                 GF_AV1_OBUArrayEntry *a;
    1575             : 
    1576         590 :                 pos = gf_bs_get_position(bs);
    1577         590 :                 obu_size = 0;
    1578         590 :                 if (gf_av1_parse_obu(bs, &obu_type, &obu_size, NULL, &state) != GF_OK) {
    1579           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[AV1] could not parse AV1 OBU at position "LLU". Leaving parsing.\n", pos));
    1580           0 :                         break;
    1581             :                 }
    1582             :                 assert(obu_size == gf_bs_get_position(bs) - pos);
    1583         590 :                 GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[AV1] parsed AV1 OBU type=%u size="LLU" at position "LLU".\n", obu_type, obu_size, pos));
    1584             : 
    1585         590 :                 if (!av1_is_obu_header(obu_type)) {
    1586           0 :                         GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[AV1] AV1 unexpected OBU type=%u size="LLU" found at position "LLU". Forwarding.\n", pos));
    1587             :                 }
    1588         590 :                 GF_SAFEALLOC(a, GF_AV1_OBUArrayEntry);
    1589         590 :                 if (!a) break;
    1590         590 :                 a->obu = gf_malloc((size_t)obu_size);
    1591         590 :                 if (!a->obu) {
    1592           0 :                         gf_free(a);
    1593           0 :                         break;
    1594             :                 }
    1595         590 :                 gf_bs_seek(bs, pos);
    1596         590 :                 gf_bs_read_data(bs, (char *) a->obu, (u32)obu_size);
    1597         590 :                 a->obu_length = obu_size;
    1598         590 :                 a->obu_type = obu_type;
    1599         590 :                 gf_list_add(cfg->obu_array, a);
    1600             : 
    1601         590 :                 if (size<obu_size) {
    1602           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[AV1] AV1 config misses %d bytes to fit the entire OBU\n", obu_size - size));
    1603             :                         break;
    1604             :                 }
    1605         590 :                 size -= (u32) obu_size;
    1606             :         }
    1607         590 :         gf_av1_reset_state(& state, GF_TRUE);
    1608         590 :         return cfg;
    1609             : #else
    1610             :         return NULL;
    1611             : #endif
    1612             : }
    1613             : 
    1614             : GF_EXPORT
    1615         238 : GF_AV1Config *gf_odf_av1_cfg_read_bs(GF_BitStream *bs)
    1616             : {
    1617         238 :         return gf_odf_av1_cfg_read_bs_size(bs, 0);
    1618             : 
    1619             : }
    1620             : GF_EXPORT
    1621         238 : GF_AV1Config *gf_odf_av1_cfg_read(u8 *dsi, u32 dsi_size)
    1622             : {
    1623         238 :         GF_BitStream *bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
    1624         238 :         GF_AV1Config *cfg = gf_odf_av1_cfg_read_bs(bs);
    1625         238 :         gf_bs_del(bs);
    1626         238 :         return cfg;
    1627             : }
    1628             : 
    1629           1 : GF_DOVIDecoderConfigurationRecord *gf_odf_dovi_cfg_read_bs(GF_BitStream *bs)
    1630             : {
    1631             :         GF_DOVIDecoderConfigurationRecord *cfg;
    1632           1 :         GF_SAFEALLOC(cfg, GF_DOVIDecoderConfigurationRecord);
    1633             : 
    1634           1 :         cfg->dv_version_major = gf_bs_read_u8(bs);
    1635           1 :         cfg->dv_version_minor = gf_bs_read_u8(bs);
    1636           1 :         cfg->dv_profile = gf_bs_read_int(bs, 7);
    1637           1 :         cfg->dv_level = gf_bs_read_int(bs, 6);
    1638           1 :         cfg->rpu_present_flag = gf_bs_read_int(bs, 1);
    1639           1 :         cfg->el_present_flag = gf_bs_read_int(bs, 1);
    1640           1 :         cfg->bl_present_flag = gf_bs_read_int(bs, 1);
    1641             :         {
    1642             :                 int i = 0;
    1643             :                 u32 data[5];
    1644             :                 memset(data, 0, sizeof(data));
    1645           1 :                 gf_bs_read_data(bs, (char*)data, 20);
    1646           6 :                 for (i = 0; i < 5; ++i) {
    1647           5 :                         if (data[i] != 0) {
    1648           0 :                                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[odf_cfg] dovi config reserved bytes are not zero\n"));
    1649             :                         }
    1650             :                 }
    1651             :         }
    1652           1 :         return cfg;
    1653             : }
    1654             : 
    1655           2 : void gf_odf_dovi_cfg_del(GF_DOVIDecoderConfigurationRecord *cfg)
    1656             : {
    1657           2 :         gf_free(cfg);
    1658           2 : }
    1659             : 
    1660           1 : GF_Err gf_odf_dovi_cfg_write_bs(GF_DOVIDecoderConfigurationRecord *cfg, GF_BitStream *bs)
    1661             : {
    1662           1 :         gf_bs_write_u8(bs,  cfg->dv_version_major);
    1663           1 :         gf_bs_write_u8(bs,  cfg->dv_version_minor);
    1664           1 :         gf_bs_write_int(bs, cfg->dv_profile, 7);
    1665           1 :         gf_bs_write_int(bs, cfg->dv_level, 6);
    1666           1 :         gf_bs_write_int(bs, cfg->rpu_present_flag, 1);
    1667           1 :         gf_bs_write_int(bs, cfg->el_present_flag, 1);
    1668           1 :         gf_bs_write_int(bs, cfg->bl_present_flag, 1);
    1669           1 :     gf_bs_write_u32(bs, 0);
    1670           1 :     gf_bs_write_u32(bs, 0);
    1671           1 :     gf_bs_write_u32(bs, 0);
    1672           1 :     gf_bs_write_u32(bs, 0);
    1673           1 :     gf_bs_write_u32(bs, 0);
    1674           1 :         return GF_OK;
    1675             : }
    1676             : 
    1677             : 
    1678          49 : GF_Err gf_odf_ac3_cfg_write_bs(GF_AC3Config *cfg, GF_BitStream *bs)
    1679             : {
    1680          49 :         if (!cfg || !bs) return GF_BAD_PARAM;
    1681             : 
    1682          49 :         if (cfg->is_ec3) {
    1683             :                 u32 i;
    1684          10 :                 gf_bs_write_int(bs, cfg->brcode, 13);
    1685          10 :                 gf_bs_write_int(bs, cfg->nb_streams - 1, 3);
    1686          19 :                 for (i=0; i<cfg->nb_streams; i++) {
    1687           9 :                         gf_bs_write_int(bs, cfg->streams[i].fscod, 2);
    1688           9 :                         gf_bs_write_int(bs, cfg->streams[i].bsid, 5);
    1689           9 :                         gf_bs_write_int(bs, cfg->streams[i].bsmod, 5);
    1690           9 :                         gf_bs_write_int(bs, cfg->streams[i].acmod, 3);
    1691           9 :                         gf_bs_write_int(bs, cfg->streams[i].lfon, 1);
    1692           9 :                         gf_bs_write_int(bs, 0, 3);
    1693           9 :                         gf_bs_write_int(bs, cfg->streams[i].nb_dep_sub, 4);
    1694           9 :                         if (cfg->streams[i].nb_dep_sub) {
    1695           0 :                                 gf_bs_write_int(bs, cfg->streams[i].chan_loc, 9);
    1696             :                         } else {
    1697           9 :                                 gf_bs_write_int(bs, 0, 1);
    1698             :                         }
    1699             :                 }
    1700             :         } else {
    1701          39 :                 gf_bs_write_int(bs, cfg->streams[0].fscod, 2);
    1702          39 :                 gf_bs_write_int(bs, cfg->streams[0].bsid, 5);
    1703          39 :                 gf_bs_write_int(bs, cfg->streams[0].bsmod, 3);
    1704          39 :                 gf_bs_write_int(bs, cfg->streams[0].acmod, 3);
    1705          39 :                 gf_bs_write_int(bs, cfg->streams[0].lfon, 1);
    1706          39 :                 gf_bs_write_int(bs, cfg->brcode, 5);
    1707          39 :                 gf_bs_write_int(bs, 0, 5);
    1708             :         }
    1709             :         return GF_OK;
    1710             : }
    1711             : 
    1712          26 : GF_Err gf_odf_ac3_cfg_write(GF_AC3Config *cfg, u8 **data, u32 *size)
    1713             : {
    1714          26 :         GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
    1715          26 :         GF_Err e = gf_odf_ac3_cfg_write_bs(cfg, bs);
    1716             : 
    1717          26 :         gf_bs_get_content(bs, data, size);
    1718          26 :         gf_bs_del(bs);
    1719          26 :         return e;
    1720             : }
    1721             : 
    1722          30 : GF_Err gf_odf_ac3_config_parse_bs(GF_BitStream *bs, Bool is_ec3, GF_AC3Config *cfg)
    1723             : {
    1724          30 :         if (!cfg || !bs) return GF_BAD_PARAM;
    1725             :         memset(cfg, 0, sizeof(GF_AC3Config));
    1726          30 :         cfg->is_ec3 = is_ec3;
    1727          30 :         if (is_ec3) {
    1728             :                 u32 j;
    1729           8 :                 cfg->is_ec3 = 1;
    1730           8 :                 cfg->brcode = gf_bs_read_int(bs, 13);
    1731           8 :                 cfg->nb_streams = 1 + gf_bs_read_int(bs, 3);
    1732          23 :                 for (j=0; j<cfg->nb_streams; j++) {
    1733          15 :                         cfg->streams[j].fscod = gf_bs_read_int(bs, 2);
    1734          15 :                         cfg->streams[j].bsid = gf_bs_read_int(bs, 5);
    1735          15 :                         gf_bs_read_int(bs, 1);
    1736          15 :                         cfg->streams[j].asvc = gf_bs_read_int(bs, 1);
    1737          15 :                         cfg->streams[j].bsmod = gf_bs_read_int(bs, 3);
    1738          15 :                         cfg->streams[j].acmod = gf_bs_read_int(bs, 3);
    1739          15 :                         cfg->streams[j].lfon = gf_bs_read_int(bs, 1);
    1740          15 :                         gf_bs_read_int(bs, 3);
    1741          15 :                         cfg->streams[j].nb_dep_sub = gf_bs_read_int(bs, 4);
    1742          15 :                         if (cfg->streams[j].nb_dep_sub) {
    1743           0 :                                 cfg->streams[j].chan_loc = gf_bs_read_int(bs, 9);
    1744             :                         } else {
    1745          15 :                                 gf_bs_read_int(bs, 1);
    1746             :                         }
    1747             :                 }
    1748             :         } else {
    1749          22 :                 cfg->nb_streams = 1;
    1750          22 :                 cfg->streams[0].fscod = gf_bs_read_int(bs, 2);
    1751          22 :                 cfg->streams[0].bsid = gf_bs_read_int(bs, 5);
    1752          22 :                 cfg->streams[0].bsmod = gf_bs_read_int(bs, 3);
    1753          22 :                 cfg->streams[0].acmod = gf_bs_read_int(bs, 3);
    1754          22 :                 cfg->streams[0].lfon = gf_bs_read_int(bs, 1);
    1755          22 :                 cfg->brcode = gf_bs_read_int(bs, 5);
    1756          22 :                 gf_bs_read_int(bs, 5);
    1757             :         }
    1758             :         return GF_OK;
    1759             : }
    1760             : 
    1761           8 : GF_Err gf_odf_ac3_config_parse(u8 *dsi, u32 dsi_len, Bool is_ec3, GF_AC3Config *cfg)
    1762             : {
    1763             :         GF_BitStream *bs;
    1764             :         GF_Err e;
    1765           8 :         if (!cfg || !dsi) return GF_BAD_PARAM;
    1766           8 :         bs = gf_bs_new(dsi, dsi_len, GF_BITSTREAM_READ);
    1767           8 :         e = gf_odf_ac3_config_parse_bs(bs, is_ec3, cfg);
    1768           8 :         gf_bs_del(bs);
    1769           8 :         return e;
    1770             : }

Generated by: LCOV version 1.13